Jak uzyskać bieżącą ścieżkę z ciągiem zapytania przy użyciu Kapibary

144

Adres URL strony jest podobny, /people?search=name podczas gdy ja użyłem current_pathmetody kapibary, /peopletylko zwrócił .

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

Ale to się nie powiedzie

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

Jak możemy to przejść? Czy jest na to sposób?

kriysna
źródło
10
"/people?search=name" nie jest ścieżką . "/people"jest ścieżką
Andrei Botalov

Odpowiedzi:

212

Zaktualizowałem tę odpowiedź, aby odzwierciedlała współczesne konwencje w kapibarze. Myślę, że jest to idealne rozwiązanie, ponieważ jest to akceptowana odpowiedź i do której odnosi się wiele osób, szukając rozwiązania. Mając to na uwadze, właściwym sposobem sprawdzenia bieżącej ścieżki jest użycie has_current_path?dopasowania dostarczonego przez Kapibarę, zgodnie z dokumentacją tutaj: Kliknij tutaj

Przykładowe użycie:

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

Jak widać w dokumentacji, dostępne są inne opcje. Jeśli bieżąca strona jest, /people?search=nameale zależy Ci tylko na tym, że znajduje się na /peoplestronie niezależnie od parametru, możesz wysłać only_pathopcję:

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

Dodatkowo, jeśli chcesz porównać cały adres URL:

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

Podziękowania dla Toma Walpole'a za wskazanie tej metody.

nzifnab
źródło
4
Prawdopodobnie wkrótce będę potrzebować tej składni, piszę testy dla starszej aplikacji. Używanie current_path.should ==na razie działa (chociaż muszę dodać końcowy ukośnik jako ciąg). Z góry dziękuję za kod, którego prawdopodobnie będę potrzebować.
Tass
3
URI.parse(current_url).request_urijest bardziej zwięzły. Zobacz odpowiedź @Lasse Bunk.
Richard Jones
Od wersji Capybara 2.5 nie jest to już najlepsza odpowiedź. Zobacz odpowiedź @ tom-walpole poniżej.
dkniffin
Ponieważ pytający raczej nie zmieni zaakceptowanej odpowiedzi, zaktualizowałem odpowiedź, aby odzwierciedlała współczesne czasy. Powinno to być bardziej pomocne dla nowych użytkowników szukających rozwiązania i widzących pierwszą odpowiedź. Dzięki @OddityOverseer za wskazanie tego
nzifnab,
1
W przypadku nowych wersji Kapibary użyj ignore_query: truezamiastonly_path: true
Alexander
92

Zastąpiłem metodę _path _url, aby uzyskać porównanie pełnych adresów URL z parametrami.

current_url.should == people_url(:search => 'name')
Robert Starsi
źródło
4
Jak poradziłeś sobie z częścią hosta?
Chris Nicola,
11
Możesz także użyć current_pathw nowszych wersjach Kapibary i dopasować ją przeciwkopeople_path(...)
Jason Stirk
Kiedy nie mam nazwanej ścieżki ... mam tylko / users / register ... to jak mam z niej korzystać?
Gopal S Rathore
A co, jeśli dzieje się to podczas renderowania, tak że adres URL różni się od strony html?
bigpotato
52

Aktualizuję to pytanie do czasów współczesnych. Bieżącą najlepszą praktyką sprawdzania bieżących ścieżek podczas korzystania z Kapibary 2.5+ jest użycie dopasowania bieżącej_ścieżki, który użyje zachowania czekającego Capybaras do sprawdzenia ścieżki. Jeśli chcesz porównać request_uri (ścieżka i ciąg zapytania)

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

Jeśli chcesz tylko część ścieżki (ignorowanie ciągu zapytania)

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

Jeśli chcesz dopasować pełny adres 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

element dopasowujący weźmie łańcuch, który jest porównywany z == lub wyrażeniem regularnym do dopasowania

expect(page).to have_current_path(/search=name/)
Thomas Walpole
źródło
4
w tych czasach nowożytnych powinno być oznaczone jako na odpowiedź. Pozwoli to uniknąć wielu niejasnych problemów z synchronizacją, dzięki!
Axe
1
@Vanuan rspec wycofuje shouldskładnię. Powinieneś starać się używać expect().tow swoich specyfikacjach w przyszłości.
nzifnab
1
only_path: truejest terazignore_query: true
srghma
18

Wiem, że wybrano odpowiedź, ale chciałem tylko podać alternatywne rozwiązanie. Więc:

Aby uzyskać ścieżkę i querystring, jak request.fullpathw Railsach, możesz:

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

Możesz również wykonać metodę pomocniczą w swojej klasie testowej (na przykład ActionDispatch::IntegrationTest) w następujący sposób (co zrobiłem):

def current_fullpath
  URI.parse(current_url).request_uri
end

Mam nadzieję że to pomoże.

Lasse Bunk
źródło
1

EDYCJA: jak wspomniał Tinynumberes, nie udaje się to w przypadku adresów URL z numerem portu. Zachowaj to tutaj na wypadek, gdyby ktoś inny wpadł na ten sam genialny pomysł.

current_url[current_host.size..-1]

golfa dokładnie tak samo (35 znaków) jak URI.parse(current_url).request_uri, ale jest potencjalnie szybsze, ponieważ nie obejmuje jawnego analizowania identyfikatora URI.

Poprosiłem o dodanie tego do Kapibary pod adresem : https://github.com/jnicklas/capybara/pull/1405

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
źródło
To nie działa, jeśli current_urlmoże zawierać numer portu. Np. Biorąc current_urlpod uwagę http://foo.com:8888/some/path, current_url[current_host.size..-1]będzie równe :8888/some/path. Poza tym za kulisami current_hostdziała ta sama URI.parselogika, którą @nzifnab zalecał w zaakceptowanej odpowiedzi.
Tinynumbers