Cómo obtener la ruta actual con la cadena de consulta usando Capybara

144

La URL de la página es algo así, /people?search=name mientras que utilicé el current_pathmétodo de carpincho solo regresó /people.

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

Pero falla diciendo

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

¿Cómo podemos hacer que pase? ¿Hay alguna forma de hacer esto?

kriysna
fuente
10
"/people?search=name" No es un camino . "/people"es un camino
Andrei Botalov

Respuestas:

212

He actualizado esta respuesta para reflejar las convenciones modernas en carpincho. Creo que esto es ideal ya que esta es la respuesta aceptada, y a lo que se refiere a muchas personas cuando buscan una solución. Dicho esto, la forma correcta de verificar la ruta actual es utilizar el has_current_path?comparador proporcionado por Capybara, como se documenta aquí: haga clic aquí

Ejemplo de uso:

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

Como puede ver en la documentación, hay otras opciones disponibles. Si la página actual es /people?search=namepero solo le importa que esté en la /peoplepágina independientemente del parámetro, puede enviar la only_pathopción:

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

Además, si desea comparar la URL completa:

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

Gracias a Tom Walpole por señalar este método.

nzifnab
fuente
44
Probablemente necesitaré esta sintaxis muy pronto, estoy escribiendo pruebas para una aplicación heredada. Usar current_path.should ==está funcionando por ahora (aunque necesito agregar una barra diagonal posterior como una cadena). Le agradezco de antemano el código que probablemente necesite.
Tass
3
URI.parse(current_url).request_uriEs más sucinto. Ver la respuesta de @Lasse Bunk.
Richard Jones el
A partir de Capybara 2.5, esta ya no es la mejor respuesta. Vea la respuesta de @ tom-walpole a continuación.
dkniffin
Como es poco probable que el autor de la pregunta cambie la respuesta aceptada, he actualizado la respuesta para reflejar los tiempos modernos. Esto debería ser más útil para los nuevos usuarios que buscan una solución y ven la primera respuesta. Gracias @OddityOverseer por señalarlo
nzifnab
1
Para nuevas versiones de Carpincho, use en ignore_query: truelugar deonly_path: true
Alexander
92

Reemplacé el método _path con _url para lograr comparar las URL completas con los parámetros.

current_url.should == people_url(:search => 'name')
Robert Starsi
fuente
44
¿Cómo lidiaste con la parte del anfitrión?
Chris Nicola
11
También se puede utilizar current_pathen las versiones más recientes de capibara y el partido contrapeople_path(...)
Jason Stirk
Cuando no tengo nombre de ruta ... solo tengo / users / register ... entonces, ¿cómo debo usarlo?
Gopal S Rathore
¿Qué pasa si está sucediendo en un render, de modo que la URL es diferente de la página html?
bigpotato
52

Simplemente actualizo esta pregunta para los tiempos modernos. La mejor práctica actual para verificar current_paths cuando se usa Capybara 2.5+ es usar el emparejador current_path, que usará el comportamiento de espera de Capybaras para verificar la ruta. Si desea verificar con request_uri (ruta y cadena de consulta)

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

Si solo desea la parte de la ruta (ignorando la cadena de consulta)

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 quiere coincidir con la url completa

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

el comparador tomará una cadena que se compara con == o una expresión regular para comparar con

expect(page).to have_current_path(/search=name/)
Thomas Walpole
fuente
44
en estos tiempos modernos esto debería marcarse como la respuesta. Esto salvará muchos problemas vagos de tiempo, ¡gracias!
Hacha
1
@Vanuan rspec ha estado despreciando la shouldsintaxis. Debes esforzarte por usar expect().totus especificaciones en el futuro.
nzifnab
1
only_path: truees ahoraignore_query: true
srghma
18

Sé que se ha seleccionado una respuesta, pero solo quería dar una solución alternativa. Entonces:

Para obtener la ruta y la cadena de consulta, como request.fullpathen Rails, puede hacer:

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

También puede hacer un método auxiliar en su clase de prueba (como ActionDispatch::IntegrationTest) como este (que es lo que hice):

def current_fullpath
  URI.parse(current_url).request_uri
end

Espero que esto ayude.

Lasse Bunk
fuente
1

EDITAR: como mencionó Tinynumberes, esto falla para las URL con número de puerto. Mantenerlo aquí en caso de que alguien más tenga la misma idea brillante.

current_url[current_host.size..-1]

golf exactamente igual (35 caracteres) como URI.parse(current_url).request_uri, pero es potencialmente más rápido porque no hay un análisis de URI explícito involucrado.

He realizado una solicitud de extracción para agregar esto a Capybara en: https://github.com/jnicklas/capybara/pull/1405

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Esto no funciona si current_urlpuede contener un número de puerto. Por ejemplo, dado un current_urlde http://foo.com:8888/some/path, current_url[current_host.size..-1]será igual :8888/some/path. Además, detrás de escena current_hosthace el mismo tipo de URI.parselógica que @nzifnab recomendó en la respuesta aceptada.
Tinynumbers