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
tomekfranek
la source

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.

Andrei Botalov
la source
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
Elle Mundy
la source
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
DGM
la source
2

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

expect(page).to have_css("selector")                               
first("selector").click
nez
la source
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.

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

Simple, vous pouvez utiliser:

$('.item').find('a').first().click();
Vlogs informatiques
la source
2
Cet exemple n'est pas pertinent pour capybara
keoghpe
2
N'est-ce pas jQuery?
emptywalls