升级到Capybara 2.0后如何点击项目列表中的第一个链接?

tom*_*nek 123 ruby rspec capybara

在这种情况下如何单击第一个链接:

<div class="item">
  <a href="/agree/">Agree</a>
</div>
<div class="item">
  <a href="/agree/">Agree</a>
</div>
Run Code Online (Sandbox Code Playgroud)
within ".item" do
  first(:link, "Agree").click
end
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

Capybara::Ambiguous:
  Ambiguous match, found 2 elements matching css ".item"
Run Code Online (Sandbox Code Playgroud)

没有within我得到这个错误:

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

And*_*lov 176

你可以使用:

first('.item').click_link('Agree')
Run Code Online (Sandbox Code Playgroud)

要么

first('.item > a').click
Run Code Online (Sandbox Code Playgroud)

(如果你的默认选择器是:css)


您问题中的代码不起作用:

within ".item" do
  first(:link, "Agree").click
end
Run Code Online (Sandbox Code Playgroud)

相当于:

find('.item').first(:link, "Agree").click
Run Code Online (Sandbox Code Playgroud)

Capybara发现了几个.item,所以它引发了一个例外.我认为Capybara 2的这种行为非常好.

  • 我建议不要使用#first,它不会等待元素存在:http://www.rubydoc.info/github/jnicklas/capybara/Capybara%2FNode%2FFinders%3Afirst.如果内容是在运行时使用JS创建的,那么如果它在创建链接之前运行期望,则返回nil. (4认同)

Ell*_*ndy 21

这句话也有效:

within first(".item") do
  click_link "Agree"
end
Run Code Online (Sandbox Code Playgroud)


DGM*_*DGM 5

Xpath 可以对元素进行寻址。我还不太擅长,但是类似//div[@class='active'][1]/a

这可能有效,也可能无效,但重点是 xpath 可以寻址一组匹配项并提取特定的匹配项。你应该能够匹配这个。

我的一个项目中的一个工作示例:

在 page.find("div.panel", text: /Proposals/) 内执行
  在 page.find('tr', text: /Foo/) 内执行
    page.should have_xpath('td[3]', 文本: @today)
  结尾
结尾


Sal*_*uel 5

大多数这些解决方案不会使用 Capybara 出色的等待功能

最好按照这个链接的建议去做:https :
//thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

坏的:

first(".active").click
如果页面上还没有 .active 元素, first 将返回 nil 并且点击将失败。

好的:

如果你想确保只有一个
find(".active").click

如果您只想要第一个元素,
find(".active", match: :first).click
Capybara 将在尝试单击之前等待该元素出现。

请注意,match: :first它更脆弱,因为如果您引入匹配的新元素,它会默默地点击不同的元素。