web-dev-qa-db-ja.com

Capybara 2.0にアップグレードした後、アイテムリストの最初のリンクをクリックする方法は?

その場合の最初のリンクをクリックする方法:

<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

私はこのエラーを受け取ります:

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

そして、withinなしで、私はこのエラーを受け取ります:

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

あなただけを使用することができます:

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

または

first('.item > a').click

(デフォルトのセレクターが:cssの場合)


あなたの質問のコードは次のように機能しません:

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

以下と同等です:

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

Capybaraはいくつかの.itemを検出するため、例外が発生します。カピバラ2のこの動作は非常に良いと思います。

173
Andrei Botalov

以下を試してください:

within ".item" do
  click_link("Agree", :match => :first)
end

ソース:

111
adamdboudreau

このフレージングも機能します。

within first(".item") do
  click_link "Agree"
end
21
Elle Mundy

Xpathは要素をアドレス指定できます。私はまだあまり良くありませんが、//div[@class='active'][1]/aのようなものです

動作する場合と動作しない場合がありますが、ポイントはxpathが一致する配列をアドレス指定して特定の配列を取り出すことができるということです。これと一致できるはずです。

私のプロジェクトの1つからの実例:

 page.find( "div.panel"内、テキスト:/ Proposals /)do 
 page.find( 'tr'、テキスト:/ Foo /)do 
ページ内have_xpath( 'td [3]'、text:@today)
 end 
 end 
4
DGM

First()は常に待機するとは限らないので、おそらくこれは便利です。

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

これらのソリューションのほとんどは、カピバラの素晴らしい待機機能を使用しません

このリンクが示唆するように行う方が良い:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

悪い:

first(".active").click
ページに.active要素がまだない場合、最初はnilを返し、クリックは失敗します。

良い:

正確に1つあることを確認したい場合
find(".active").click

最初の要素だけが必要な場合
find(".active", match: :first).click
カピバラは、要素が表示されるのを待ってからクリックしようとします。

match: :firstはより脆弱であることに注意してください。一致する新しい要素を導入すると、別の要素を静かにクリックするためです。

0
Salomanuel