So erhalten Sie den aktuellen Pfad mit der Abfragezeichenfolge mithilfe von Capybara

144

Die Seiten-URL ist so etwas wie, /people?search=name während ich die current_pathCapybara-Methode verwendet habe , die /peoplenur zurückgegeben wurde.

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

Aber es sagt nicht

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

Wie können wir es schaffen? Gibt es eine Möglichkeit, dies zu tun?

Kriysna
quelle
10
"/people?search=name" ist kein Weg . "/people"ist ein Weg
Andrei Botalov

Antworten:

212

Ich habe diese Antwort aktualisiert, um moderne Konventionen in Capybara widerzuspiegeln. Ich denke, dies ist ideal, da dies die akzeptierte Antwort ist und auf was viele Menschen bei der Suche nach einer Lösung verwiesen werden. Der korrekte Weg, um den aktuellen Pfad zu überprüfen, besteht darin, den has_current_path?von Capybara bereitgestellten Matcher zu verwenden , wie hier dokumentiert: Klicken Sie hier

Anwendungsbeispiel:

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

Wie Sie in der Dokumentation sehen können, stehen andere Optionen zur Verfügung. Wenn sich die aktuelle Seite befindet /people?search=name, Sie sich jedoch nur darum kümmern, dass sie sich /peopleunabhängig vom Parameter auf der Seite befindet, können Sie die folgende only_pathOption senden :

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

Wenn Sie außerdem die gesamte URL vergleichen möchten:

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

Dank an Tom Walpole für den Hinweis auf diese Methode.

nzifnab
quelle
4
Ich werde diese Syntax wahrscheinlich sehr bald brauchen, ich schreibe Tests für eine Legacy-Anwendung. Die Verwendung current_path.should ==funktioniert vorerst (obwohl ich einen abschließenden Schrägstrich als Zeichenfolge hinzufügen muss). Ich danke Ihnen im Voraus für den Code, den ich wahrscheinlich brauche.
Tass
3
URI.parse(current_url).request_uriist prägnanter. Siehe die Antwort von @Lasse Bunk.
Richard Jones
Ab Capybara 2.5 ist dies nicht mehr die beste Antwort. Siehe die Antwort von @ tom-walpole unten.
dkniffin
Da es unwahrscheinlich ist, dass der Fragesteller die akzeptierte Antwort ändert, habe ich die Antwort aktualisiert, um die moderne Zeit widerzuspiegeln. Dies sollte für neue Benutzer hilfreicher sein, die nach einer Lösung suchen und die erste Antwort sehen. Vielen Dank an @OddityOverseer für den Hinweis
nzifnab
1
Für neue Capybara-Versionen verwenden Sie ignore_query: trueanstelle vononly_path: true
Alexander
92

Ich habe die _path-Methode durch _url ersetzt, um die vollständigen URLs mit den Parametern zu vergleichen.

current_url.should == people_url(:search => 'name')
Robert Starsi
quelle
4
Wie sind Sie mit dem Host-Teil umgegangen?
Chris Nicola
11
Sie können auch current_pathin neueren Versionen von Capybara verwenden und es gegenpeople_path(...)
Jason Stirk
Wenn ich keinen Pfad benannt habe ... Ich habe nur / users / register ... wie soll ich ihn dann verwenden?
Gopal S Rathore
Was ist, wenn es beim Rendern passiert, sodass sich die URL von der HTML-Seite unterscheidet?
Bigpotato
52

Nur diese Frage für die moderne Zeit aktualisieren. Die derzeitige bewährte Methode zum Überprüfen von current_paths bei Verwendung von Capybara 2.5+ ist die Verwendung des current_path-Matchers, der das Warteverhalten von Capybaras zum Überprüfen des Pfads verwendet. Wenn Sie gegen die request_uri (Pfad und Abfragezeichenfolge) prüfen möchten

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

Wenn nur der Pfadteil gewünscht wird (Ignorieren der Abfragezeichenfolge)

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

Wenn Sie mit der vollständigen URL übereinstimmen möchten

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

Der Matcher nimmt eine Zeichenfolge, die mit == verglichen wird, oder einen regulären Ausdruck, mit dem verglichen werden soll

expect(page).to have_current_path(/search=name/)
Thomas Walpole
quelle
4
in diesen modernen Zeiten sollte dies als markiert die Antwort. Dies wird viele vage Timing-Probleme ersparen, danke!
Axe
1
@ Vanuan rspec hat die shouldSyntax abgelehnt . Sie sollten sich bemühen, expect().toin Zukunft in Ihren Spezifikationen zu verwenden.
Nzifnab
1
only_path: trueist jetztignore_query: true
srghma
18

Ich weiß, dass eine Antwort ausgewählt wurde, aber ich wollte nur eine alternative Lösung geben. So:

Um den Pfad und den Querystring wie request.fullpathin Rails abzurufen, können Sie Folgendes tun:

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

Sie können auch eine Hilfsmethode in Ihrer Testklasse (wie diese ActionDispatch::IntegrationTest) ausführen (wie ich es getan habe):

def current_fullpath
  URI.parse(current_url).request_uri
end

Hoffe das hilft.

Lasse Koje
quelle
1

BEARBEITEN: Wie von Tinynumberes erwähnt, schlägt dies bei URLs mit Portnummer fehl. Bewahren Sie es hier auf, falls jemand anderes die gleiche brillante Idee hat.

current_url[current_host.size..-1]

Golf genau so gut (35 Zeichen) wie URI.parse(current_url).request_uri, ist aber möglicherweise schneller, da keine explizite URI-Analyse erforderlich ist.

Ich habe eine Pull-Anfrage gestellt, um dies zu Capybara hinzuzufügen: https://github.com/jnicklas/capybara/pull/1405

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
Dies funktioniert nicht, wenn die current_urlmöglicherweise eine Portnummer enthält. ZB gegeben ein current_urlvon http://foo.com:8888/some/path, current_url[current_host.size..-1]wird gleich :8888/some/path. Hinter den Kulissen current_hostwird dieselbe URI.parseLogik verwendet, die @nzifnab in der akzeptierten Antwort empfohlen hat.
Tinynumbers