Comment obtenir le chemin actuel avec la chaîne de requête en utilisant Capybara


144

L'URL de la page ressemble à quelque chose comme /people?search=name si j'utilisais la current_pathméthode capybara, elle /peoplene retournait que.

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

Mais ça ne dit pas

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

Comment pouvons-nous le faire passer? Y a-t-il un moyen de le faire?


10
"/people?search=name" n'est pas un chemin . "/people"est un chemin
Andrei Botalov

Réponses:


212

J'ai mis à jour cette réponse pour refléter les conventions modernes en capybara. Je pense que c'est idéal car c'est la réponse acceptée, et ce à quoi de nombreuses personnes sont référées lorsqu'elles recherchent une solution. Cela dit, la bonne façon de vérifier le chemin actuel est d'utiliser le has_current_path?matcher fourni par Capybara, comme documenté ici: Cliquez ici

Exemple d'utilisation:

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

Comme vous pouvez le voir dans la documentation, d'autres options sont disponibles. Si la page actuelle est /people?search=namemais que vous vous souciez seulement qu'elle soit sur la /peoplepage quel que soit le paramètre, vous pouvez envoyer l' only_pathoption:

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

De plus, si vous souhaitez comparer l'URL entière:

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

Nous remercions Tom Walpole d'avoir souligné cette méthode.


4
J'aurai probablement besoin de cette syntaxe très bientôt, j'écris des tests pour une application héritée. L'utilisation current_path.should ==fonctionne pour le moment (bien que je doive ajouter une barre oblique de fin en tant que chaîne). Je vous remercie d'avance pour le code dont j'aurai probablement besoin.
Tass

3
URI.parse(current_url).request_uriest plus succinct. Voir la réponse de @Lasse Bunk.
Richard Jones

Depuis Capybara 2.5, ce n'est plus la meilleure réponse. Voir la réponse de @ tom-walpole ci-dessous.
dkniffin

Comme il est peu probable que le demandeur change la réponse acceptée, j'ai mis à jour la réponse pour refléter les temps modernes. Cela devrait être plus utile aux nouveaux utilisateurs qui recherchent une solution et voient la première réponse. Merci @OddityOverseer de l'avoir signalé
nzifnab

1
Pour les nouvelles versions de Capybara, utilisez à la ignore_query: trueplace deonly_path: true
Alexander

92

J'ai remplacé la méthode _path par _url pour comparer les URL complètes avec les paramètres.

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

4
Comment avez-vous géré la partie hôte?
Chris Nicola

11
Vous pouvez également utiliser current_pathdans les nouvelles versions de Capybara et le faire correspondre contrepeople_path(...)
Jason Stirk

Quand je n'ai pas de chemin nommé ... Je n'ai que / users / register ... alors comment dois-je l'utiliser?
Gopal S Rathore

Que faire si cela se produit sur un rendu, de sorte que l'URL soit différente de la page html?
bigpotato

52

Je mets juste à jour cette question pour les temps modernes. La meilleure pratique actuelle pour vérifier current_paths lors de l'utilisation de Capybara 2.5+ est d'utiliser le matcher current_path, qui utilisera le comportement d'attente de Capybaras pour vérifier le chemin. Si vous souhaitez vérifier par rapport au request_uri (chemin et chaîne de requête)

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

Si vous voulez seulement la partie du chemin (en ignorant la chaîne de requête)

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

Si vous souhaitez faire correspondre l'URL complète

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

le matcher prendra une chaîne qui est comparée à == ou à une expression régulière à comparer

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

4
dans ces temps modernes, cela devrait être marqué comme la réponse. Cela évitera beaucoup de vagues problèmes de timing, merci!
Axe

1
@Vanuan rspec a déprécié la shouldsyntaxe. Vous devriez vous efforcer d'utiliser expect().todans vos spécifications à l'avenir.
nzifnab

1
only_path: trueest maintenantignore_query: true
srghma

18

Je sais qu'une réponse a été choisie, mais je voulais juste donner une solution alternative. Alors:

Pour obtenir le chemin et la chaîne de requête, comme request.fullpathdans Rails, vous pouvez faire:

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

Vous pouvez également faire une méthode d'assistance dans votre classe de test (comme ActionDispatch::IntegrationTest) comme celle-ci (ce que j'ai fait):

def current_fullpath
  URI.parse(current_url).request_uri
end

J'espère que cela t'aides.


1

EDIT: comme Tinynumberes l'a mentionné, cela échoue pour les URL avec numéro de port. Gardez-le ici au cas où quelqu'un d'autre aurait la même idée géniale.

current_url[current_host.size..-1]

golfs exactement aussi bien (35 caractères) que URI.parse(current_url).request_uri, mais est potentiellement plus rapide car aucune analyse d'URI explicite n'est impliquée.

J'ai fait une demande de tirage pour ajouter ceci à Capybara à l' adresse : https://github.com/jnicklas/capybara/pull/1405


Cela ne fonctionne pas si le current_urlpeut contenir un numéro de port. Par exemple, étant donné un current_urlde http://foo.com:8888/some/path, current_url[current_host.size..-1]sera égal :8888/some/path. En outre, dans les coulisses current_hostfait le même type de URI.parselogique que @nzifnab recommandé dans la réponse acceptée.
Tinynumbers
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.