Wie klicke ich nach dem Upgrade auf Capybara 2.0 auf den ersten Link in der Liste der Elemente?


125

So klicken Sie in diesem Fall auf den ersten Link:

<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

und ich bekomme diesen Fehler:

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

Und ohne das withinbekomme ich diesen Fehler:

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

Antworten:


176

Sie können einfach verwenden:

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

oder

first('.item > a').click

(Wenn Ihre Standardauswahl lautet: css)


Code in Ihrer Frage funktioniert nicht wie folgt:

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

ist äquivalent zu:

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

Capybara findet mehrere .item, so dass es eine Ausnahme auslöst. Ich halte dieses Verhalten von Capybara 2 für sehr gut.


4
Ich würde empfehlen, #first nicht zu verwenden, es wartet nicht darauf, dass ein Element existiert: rubydoc.info/github/jnicklas/capybara/… . Wenn der Inhalt zur Laufzeit zuerst mit JS erstellt wurde, wird nil zurückgegeben, wenn die Erwartung ausgeführt wird, bevor der Link erstellt wird.
Dgtized


24

Diese Formulierung funktioniert auch:

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

Hat für mich gearbeitet, danke. Capybara 2.4.1 und Poltergeist.
Mauricio Moraes

4

Xpath kann das Element adressieren. Ich bin noch nicht sehr gut damit, aber so ähnlich//div[@class='active'][1]/a

Das mag funktionieren oder auch nicht, aber der Punkt ist, dass xpath ein Array von Übereinstimmungen adressieren und eine bestimmte herausziehen kann. Sie sollten in der Lage sein, damit übereinzustimmen.

Ein Arbeitsbeispiel aus einem meiner Projekte:

innerhalb von page.find ("div.panel", Text: / Proposals /) do
  innerhalb von page.find ('tr', Text: / Foo /) tun
    page.should have_xpath ('td [3]', Text: @today)
  Ende
Ende

2

Da first () nicht immer wartet, ist dies vielleicht nützlich:

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

2

Die meisten dieser Lösungen verwenden die brillanten Wartefunktionen von Capybara nicht

Machen Sie es besser, wie dieser Link vorschlägt:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

Schlecht:

first(".active").click
Wenn die Seite noch kein aktives Element enthält, wird zuerst nil zurückgegeben und der Klick schlägt fehl.

Gut:

Wenn Sie sicherstellen möchten, dass es genau eine gibt
find(".active").click

Wenn Sie nur das erste Element möchten
find(".active", match: :first).click
, wartet Capybara, bis das Element angezeigt wird, bevor Sie versuchen, darauf zu klicken.

Beachten Sie, dass dies match: :firstspröder ist, da es still auf ein anderes Element klickt, wenn Sie neue Elemente einführen, die übereinstimmen.


Ich glaube, das ist die genaueste Antwort.
katericata

-2

Einfach können Sie verwenden:

$('.item').find('a').first().click();

2
Dieses Beispiel ist nicht relevant für Capybara
Keoghpe

2
Ist das nicht jQuery?
leere Wände
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.