Как получить текущий путь со строкой запроса, используя Capybara


144

URL страницы похож на /people?search=name то, что когда я использовал current_pathметод капибары, он /peopleтолько возвращал .

current_path.should == people_path(:search => 'name')

Но это не говорит

expected: "/people?search=name"
got: "/people"

Как мы можем сделать это? Есть ли способ сделать это?


10
"/people?search=name" это не путь . "/people"это путь
Андрей Боталов

Ответы:


212

Я обновил этот ответ, чтобы отразить современные соглашения в капибаре. Я думаю, что это идеально, так как это принятый ответ, и на что многие люди обращаются, когда ищут решение. С учетом вышесказанного, правильный способ проверки текущего пути - использовать has_current_path?средство сопоставления, предоставленное Capybara, как описано здесь: Нажмите здесь

Пример использования:

expect(page).to have_current_path(people_path(search: 'name'))

Как видно из документации, доступны другие варианты. Если текущая страница есть, /people?search=nameно вы заботитесь только о том, чтобы она была на /peopleстранице независимо от параметра, вы можете отправить only_pathопцию:

expect(page).to have_current_path(people_path, only_path: true)

Кроме того, если вы хотите сравнить весь URL:

expect(page).to have_current_path(people_url, url: true)

Благодарим Тома Уолпола за указание на этот метод.


4
Скорее всего, этот синтаксис мне понадобится очень скоро, я пишу тесты для устаревшего приложения. Использование current_path.should ==работает сейчас (хотя мне нужно добавить косую черту в виде строки). Я заранее благодарю вас за код, который мне, вероятно, понадобится.
ТАСС

3
URI.parse(current_url).request_uriявляется более кратким. Смотрите ответ @Lasse Bunk.
Ричард Джонс

Начиная с Capybara 2.5 это уже не лучший ответ. Смотрите ответ @ tom-walpole ниже.
dkniffin

Поскольку спрашивающий вряд ли изменит принятый ответ, я обновил ответ, чтобы отразить современность. Это должно быть более полезным для новых пользователей, которые ищут решение и видят первый ответ. Спасибо @OddityOverseer за указание на это
nzifnab

1
Для новых версий Capybara используйте ignore_query: trueвместоonly_path: true
Александр

92

Я заменил метод _path на _url, чтобы сравнить полные URL с параметрами.

current_url.should == people_url(:search => 'name')

4
Как вы справились с принимающей стороной?
Крис Никола

11
Вы также можете использовать current_pathв более новых версиях Capybara и сопоставить его сpeople_path(...)
Джейсон Stirk

Когда у меня нет названного пути ... у меня есть только / users / register ... тогда как мне его использовать?
Gopal S Rathore

Что если это происходит на рендере, так что URL отличается от HTML-страницы?
bigpotato

52

Просто обновляю этот вопрос для современности. В настоящее время рекомендуется проверять значения current_paths при использовании Capybara 2.5+ с использованием средства сравнения current_path, которое будет использовать поведение ожидания Capybaras для проверки пути. Если вы хотите проверить против request_uri (путь и строка запроса)

expect(page).to have_current_path(people_path(:search => 'name'))  

Если требуется только часть пути (игнорирование строки запроса)

expect(page).to have_current_path(people_path, only_path: true) # Capybara < 2.16
expect(page).to have_current_path(people_path, ignore_query: true) # Capybara >= 2.16

Если вы хотите, чтобы соответствовать полный URL

expect(page).to have_current_path(people_url, url: true) # Capybara < 2.16
expect(page).to have_current_path(people_url) # Capybara >= 2.16

средство сравнения возьмет строку, которая сравнивается с ==, или регулярное выражение для сопоставления

expect(page).to have_current_path(/search=name/)

4
в эти современные времена это должно быть помечено как в ответ. Это избавит вас от многих смутных проблем со временем, спасибо!
Топор

1
@Vanuan rspec осуждает shouldсинтаксис. Вы должны стремиться использовать expect().toв своих спецификациях в будущем.
nzifnab

1
only_path: trueсейчасignore_query: true
srghma

18

Я знаю, что ответ был выбран, но я просто хотел дать альтернативное решение. Так:

Чтобы получить путь и строку запроса, как request.fullpathв Rails, вы можете сделать:

URI.parse(current_url).request_uri.should == people_path(:search => 'name')

Вы также можете сделать вспомогательный метод в своем тестовом классе (например ActionDispatch::IntegrationTest) следующим образом (что я и сделал):

def current_fullpath
  URI.parse(current_url).request_uri
end

Надеюсь это поможет.


1

РЕДАКТИРОВАТЬ: как упоминалось Tinynumberes, это не работает для URL с номером порта. Хранить его здесь на случай, если у кого-то еще будет такая же блестящая идея.

current_url[current_host.size..-1]

golfs точно также (35 символов) URI.parse(current_url).request_uri, но потенциально быстрее, потому что нет явного анализа URI.

Я сделал запрос на добавление, чтобы добавить это к Капибаре по адресу: https://github.com/jnicklas/capybara/pull/1405


Это не работает, если current_urlможет содержать номер порта. Например , учитывая current_urlиз http://foo.com:8888/some/path, current_url[current_host.size..-1]будет равно :8888/some/path. Кроме того, за кулисами current_hostдействует та же URI.parseлогика, которую @nzifnab рекомендовал в принятом ответе.
Tinynumbers
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.