Como obter o caminho atual com a string de consulta usando a Capivara

144

O URL da página é algo como /people?search=name enquanto eu usava o current_pathmétodo capivara, ele retornava /peopleapenas.

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

Mas não diz

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

Como podemos fazer isso passar? Existe alguma maneira de fazer isso?

kriysna
fonte
10
"/people?search=name" não é um caminho . "/people"é um caminho
Andrei Botalov

Respostas:

212

Atualizei esta resposta para refletir as convenções modernas na capivara. Eu acho que isso é ideal, já que esta é a resposta aceita e o que muitas pessoas estão sendo consultadas ao procurar uma solução. Com isso dito, a maneira correta de verificar o caminho atual é usar o has_current_path?comparador fornecido pela Capivara, conforme documentado aqui: Clique Aqui

Exemplo de uso:

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

Como você pode ver na documentação, outras opções estão disponíveis. Se a página atual estiver, /people?search=namemas você se importa apenas com a /peoplepágina, independentemente do parâmetro, é possível enviar a only_pathopção:

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

Além disso, se você quiser comparar o URL inteiro:

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

Agradecemos a Tom Walpole por apontar esse método.

nzifnab
fonte
4
Provavelmente vou precisar dessa sintaxe muito em breve, estou escrevendo testes para um aplicativo herdado. O uso current_path.should ==está funcionando no momento (embora eu precise adicionar uma barra à direita como uma string). Agradeço antecipadamente o código que provavelmente precisarei.
Tass
3
URI.parse(current_url).request_urié mais sucinto. Veja a resposta do @Lasse Bunk.
Richard Jones
A partir da Capivara 2.5, essa não é mais a melhor resposta. Veja a resposta de @ tom-walpole abaixo.
dkniffin
Como é improvável que o solicitante altere a resposta aceita, atualizei a resposta para refletir os tempos modernos. Isso deve ser mais útil para novos usuários que procuram uma solução e veem a primeira resposta. Graças @OddityOverseer para apontar isso
nzifnab
1
Para novas versões da Capivara, use em ignore_query: truevez deonly_path: true
Alexander
92

Substituí o método _path por _url para comparar os URLs completos com os parâmetros.

current_url.should == people_url(:search => 'name')
Robert Starsi
fonte
4
Como você lidou com a parte do host?
22612 Chris Nicola
11
Você também pode usar current_pathnas versões mais recentes da Capivara e compará-las com #people_path(...)
Jason Stirk
Quando não tenho nomeado caminho ... tenho apenas / users / register ... então como devo usá-lo?
Gopal S Rathore
E se estiver acontecendo em uma renderização, para que o URL seja diferente da página html?
Bigpotato
52

Apenas atualizando esta questão para os tempos modernos. A melhor prática atual para verificar current_paths ao usar o Capybara 2.5+ é usar o match_path current_path, que usará o comportamento de espera das Capivaras para verificar o caminho. Se desejar verificar o request_uri (caminho e sequência de consultas)

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

Se apenas desejar a parte do caminho (ignorando a cadeia 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

Se desejar corresponder ao URL completo

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

o correspondente pegará uma sequência que seja comparada com == ou uma expressão regular para corresponder

expect(page).to have_current_path(/search=name/)
Thomas Walpole
fonte
4
nestes tempos modernos, isso deve ser marcado como a resposta. Isso salvará muitos problemas de tempo vagos, obrigado!
Ax
1
@Vanuan rspec está obsoleta a shouldsintaxe. Você deve se esforçar para usar expect().tosuas especificações daqui para frente.
Nzifnab 8/09
1
only_path: trueagora éignore_query: true
srghma 13/03/2019
18

Eu sei que uma resposta foi selecionada, mas eu só queria dar uma solução alternativa. Assim:

Para obter o caminho e a string de consulta, como request.fullpathno Rails, você pode:

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

Você também pode fazer um método auxiliar em sua classe de teste (como ActionDispatch::IntegrationTest) assim (que foi o que eu fiz):

def current_fullpath
  URI.parse(current_url).request_uri
end

Espero que isto ajude.

Lasse Bunk
fonte
1

EDIT: como Tinynumberes mencionou, isso falha para URLs com número de porta. Mantê-lo aqui, caso mais alguém tenha a mesma idéia brilhante.

current_url[current_host.size..-1]

golfs tão bem (35 caracteres) quanto URI.parse(current_url).request_uri, mas é potencialmente mais rápido porque não há análise explícita de URI envolvida.

Fiz uma solicitação pull para adicioná-lo à Capivara em: https://github.com/jnicklas/capybara/pull/1405

Ciro Santilli adicionou uma nova foto
fonte
Isso não funciona se o current_urlpode conter um número de porta. Por exemplo, dado um current_urlde http://foo.com:8888/some/path, current_url[current_host.size..-1]será igual :8888/some/path. Além disso, nos bastidores, current_hostfaz o mesmo tipo de URI.parselógica que o @nzifnab recomendou na resposta aceita.
Tinynumbers