Jak kliknąć pierwszy link na liście przedmiotów po aktualizacji do Kapibary 2.0?

125

Jak w takim przypadku kliknąć pierwszy 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

i otrzymuję ten błąd:

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

A bez tego withinwyskakuje mi ten błąd:

Failure/Error: first(:link, "Agree").click
NoMethodError:
  undefined method `click' for nil:NilClass
tomekfranek
źródło

Odpowiedzi:

176

Możesz po prostu użyć:

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

lub

first('.item > a').click

(jeśli domyślnym selektorem jest: css)


Kod w Twoim pytaniu nie działa jako:

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

jest równa:

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

Kapibara znajduje kilka .item, więc pojawia się wyjątek. Uważam to zachowanie Kapibary 2 za bardzo dobre.

Andrei Botalov
źródło
4
Odradzałbym używanie #first, nie czeka na zaistnienie elementu: rubydoc.info/github/jnicklas/capybara/… . Jeśli treść została utworzona w czasie wykonywania za pomocą JS jako pierwsza, zwróci wartość nil, jeśli uruchomi oczekiwanie przed utworzeniem łącza.
dgtized
24

To wyrażenie działa również:

within first(".item") do
  click_link "Agree"
end
Elle Mundy
źródło
Pracował dla mnie, dzięki. Kapibara 2.4.1 i poltergeist.
Mauricio Moraes
4

Xpath może adresować element. Nie jestem jeszcze z tym dobry, ale coś w stylu//div[@class='active'][1]/a

To może działać lub nie, ale chodzi o to, że xpath może zaadresować tablicę dopasowań i wyciągnąć konkretną. Powinieneś być w stanie to dopasować.

Działający przykład z jednego z moich projektów:

wewnątrz page.find ("div.panel", text: / Propozycje /) do
  wewnątrz page.find ('tr', tekst: / Foo /) do
    page.should have_xpath ('td [3]', tekst: @today)
  koniec
koniec
DGM
źródło
2

Ponieważ first () nie zawsze czeka, być może jest to przydatne:

expect(page).to have_css("selector")                               
first("selector").click
nos
źródło
2

większość z tych rozwiązań nie będzie wykorzystywała wspaniałych funkcji oczekiwania Capybara

lepiej zrób tak, jak sugeruje ten link:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

Zły:

first(".active").click
Jeśli na stronie nie ma jeszcze elementu .active, najpierw zwróci zero, a kliknięcie zakończy się niepowodzeniem.

Dobry:

Jeśli chcesz mieć pewność, że jest dokładnie jeden
find(".active").click

Jeśli chcesz tylko pierwszego elementu,
find(".active", match: :first).click
Kapibara zaczeka na pojawienie się elementu, zanim spróbujesz kliknąć.

Zauważ, że match: :firstjest to bardziej kruche, ponieważ po cichu kliknie na inny element, jeśli wprowadzisz nowe elementy, które pasują.

Salomanuel
źródło
Uważam, że to najdokładniejsza odpowiedź.
katericata
-2

Prosty w użyciu:

$('.item').find('a').first().click();
Vlogi IT
źródło
2
Ten przykład nie dotyczy kapibary
keoghpe
2
Czy to nie jest jQuery?
emptywalls