134 votes

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

Comment cliquer sur le premier lien dans ce cas :

<div class="item">
  <a href="http://stackoverflow.com/agree/">Agree</a>
</div>
<div class="item">
  <a href="http://stackoverflow.com/agree/">Agree</a>
</div>

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

et je reçois cette erreur :

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

Et sans le within Je reçois cette erreur :

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

185voto

Andrey Botalov Points 6566

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 dans votre question ne fonctionne pas comme :

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

est équivalent à :

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

Le capybara trouve plusieurs .item de sorte que cela soulève une exception. Je considère que ce comportement de Capybara 2 est très bon.

4 votes

Je vous déconseille d'utiliser #first, il 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 first retournera nil s'il exécute l'attente avant la création du lien.

127voto

adamdboudreau Points 371

1 votes

Étonnant. Et cela fonctionne sur une simple page.find('#{css}', :match => :first).click Merci pour cette réponse très utile.

25voto

Dan Mundy Points 488

Cette formulation fonctionne également :

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

0 votes

Ça a marché pour moi, merci. Capybara 2.4.1 et poltergeist.

5voto

Salomanuel Points 371

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

Il vaut 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 nil et le clic échouera.

Bien :

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

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

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

4voto

DGM Points 14007

Xpath peut s'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 fonctionner ou non, mais le fait est que xpath peut traiter un tableau de correspondances et en extraire une en particulier. Vous devriez être capable de trouver une correspondance avec ceci.

Un exemple de travail tiré de l'un de mes projets :

within page.find("div.panel", text: /Proposals/) do
  within page.find('tr', text: /Foo/) do
    page.should have\_xpath('td\[3\]', text: @today)
  end
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X