Come fare clic sul primo collegamento nell'elenco degli elementi dopo l'aggiornamento a Capybara 2.0?


125

Come fare clic sul primo collegamento in quel caso:

<div class="item">
  <a href="/agree/">Agree</a>
</div>
<div class="item">
  <a href="/agree/">Agree</a>
</div>
within ".item" do
  first(:link, "Agree").click
end

e ottengo questo errore:

Capybara::Ambiguous:
  Ambiguous match, found 2 elements matching css ".item"

E senza la presenza di withinquesto errore:

Failure/Error: first(:link, "Agree").click
NoMethodError:
  undefined method `click' for nil:NilClass

Risposte:


176

Puoi semplicemente usare:

first('.item').click_link('Agree')

o

first('.item > a').click

(se il selettore predefinito è: css)


Il codice nella tua domanda non funziona come:

within ".item" do
  first(:link, "Agree").click
end

è equivalente a:

find('.item').first(:link, "Agree").click

Capybara ne trova diversi .item, quindi solleva un'eccezione. Considero questo comportamento di Capybara 2 molto buono.


4
Consiglio di non usare #first, non aspetta l'esistenza di un elemento: rubydoc.info/github/jnicklas/capybara/… . Se il contenuto è stato creato in fase di esecuzione con JS, verrà restituito nullo se viene eseguita l'attesa prima della creazione del collegamento.
dgtized


24

Questo fraseggio funziona anche:

within first(".item") do
  click_link "Agree"
end

Ha funzionato per me, grazie. Capybara 2.4.1 e poltergeist.
Mauricio Moraes,

4

Xpath può indirizzare l'elemento. Non sono ancora molto bravo, ma qualcosa del genere//div[@class='active'][1]/a

Ciò può funzionare o meno, ma il punto è che xpath può indirizzare una serie di corrispondenze ed estrarne una particolare. Dovresti essere in grado di abbinare a questo.

Un esempio di esempio funzionante di uno dei miei progetti:

all'interno di page.find ("div.panel", testo: / Proposals /) do
  all'interno di page.find ('tr', testo: / Foo /) do
    page.should have_xpath ('td [3]', testo: @today)
  fine
fine

2

Poiché first () non sempre aspetta, forse questo è utile:

expect(page).to have_css("selector")                               
first("selector").click

2

la maggior parte di queste soluzioni non utilizzerà le brillanti funzionalità di attesa di Capybara

meglio fare come suggerisce questo link:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

Male:

first(".active").click
Se sulla pagina non è ancora presente un elemento .active, il primo restituirà zero e il clic non riuscirà.

Buona:

Se vuoi assicurarti che ce n'è esattamente uno
find(".active").click

Se vuoi solo il primo elemento
find(".active", match: :first).click
Capybara attenderà che l'elemento appaia prima di provare a fare clic.

Nota che match: :firstè più fragile, perché farà clic silenziosamente su un elemento diverso se introduci nuovi elementi che corrispondono.


Credo che questa sia la risposta più accurata.
Katericata,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.