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.