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?

Kriysna
la source
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.

nzifnab
la source
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')
Robert Starsi
la source
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/)
Thomas Walpole
la source
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.

Lit superposé Lasse
la source
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

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
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