137

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

<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
4

7 回答 7

187

您可以使用:

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's,因此它引发了异常。我认为 Capybara 2 的这种行为非常好。

于 2013-01-25T07:12:51.497 回答
132

尝试以下操作:

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

资料来源:

于 2013-06-25T21:43:48.673 回答
25

这个措辞也有效:

within first(".item") do
  click_link "Agree"
end
于 2014-08-12T18:41:37.167 回答
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它更脆弱,因为如果您引入匹配的新元素,它会默默地点击不同的元素。

于 2019-06-18T09:30:49.580 回答
4

Xpath 可以寻址元素。我还不是很好,但是像//div[@class='active'][1]/a

这可能有效,也可能无效,但关键是 xpath 可以处理一组匹配项并提取一个特定的匹配项。你应该能够匹配这个。

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

在 page.find("div.panel", text: /Proposals/) 内做
  在 page.find('tr', text: /Foo/) 内做
    page.should have_xpath('td[3]', text: @today)
  结尾
结尾
于 2013-01-25T02:33:03.410 回答
2

由于 first() 并不总是等待,也许这很有用:

expect(page).to have_css("selector")                               
first("selector").click
于 2016-09-03T23:50:30.590 回答
-4

很简单,您可以使用:

$('.item').find('a').first().click();
于 2016-06-20T11:57:24.283 回答