Comment cliquer sur le premier lien de la liste des éléments après la mise à niveau vers Capybara 2.0?


125

Comment cliquer sur le premier lien dans ce cas:

<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

et j'obtiens cette erreur:

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

Et sans le withinje reçois cette erreur:

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

Réponses:


176

Vous pouvez simplement utiliser:

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

ou

first('.item > a').click

(si votre sélecteur par défaut est: css)


Le code de votre question ne fonctionne pas comme:

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

est équivalent à:

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

Capybara en trouve plusieurs .itemdonc il soulève une exception. Je considère que ce comportement de Capybara 2 est très bon.


4
Je recommanderais de ne pas utiliser #first, cela n'attend pas qu'un élément existe: rubydoc.info/github/jnicklas/capybara/… . Si le contenu a été créé au moment de l'exécution avec JS, il retournera d'abord nil s'il exécute l'attente avant la création du lien.
dgtized


24

Cette formulation fonctionne également:

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

A travaillé pour moi, merci. Capybara 2.4.1 et poltergeist.
Mauricio Moraes

4

Xpath peut adresser l'élément. Je ne suis pas encore très bon avec ça, mais quelque chose comme//div[@class='active'][1]/a

Cela peut ou non fonctionner, mais le fait est que xpath peut adresser un tableau de correspondances et en extraire une en particulier. Vous devriez pouvoir correspondre avec cela.

Un exemple concret d'un de mes projets:

dans page.find ("div.panel", text: / Proposals /) do
  dans page.find ('tr', text: / Foo /) do
    page.should have_xpath ('td [3]', texte: @today)
  fin
fin

2

Puisque first () n'attend pas toujours, c'est peut-être utile:

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

2

la plupart de ces solutions n'utiliseront pas les brillantes fonctionnalités d'attente de Capybara

mieux faire comme ce lien le suggère:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

Mauvais:

first(".active").click
S'il n'y a pas encore d'élément .active sur la page, first retournera nul et le clic échouera.

Bien:

Si vous voulez vous assurer qu'il y en a exactement un
find(".active").click

Si vous voulez juste que le premier élément,
find(".active", match: :first).click
Capybara attendra que l'élément apparaisse avant d'essayer de cliquer.

Notez que match: :firstc'est plus fragile, car il cliquera silencieusement sur un élément différent si vous introduisez de nouveaux éléments qui correspondent.


Je pense que c'est la réponse la plus précise.
katericata le

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.