Làm cách nào để nhấp vào liên kết đầu tiên trong danh sách các mục sau khi nâng cấp lên Capybara 2.0?


125

Cách nhấp vào liên kết đầu tiên trong trường hợp đó:

<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

và tôi nhận được lỗi này:

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

Và không withincó lỗi tôi gặp phải:

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

Câu trả lời:


176

Bạn chỉ có thể sử dụng:

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

hoặc là

first('.item > a').click

(nếu bộ chọn mặc định của bạn là: css)


Mã trong câu hỏi của bạn không hoạt động như:

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

tương đương với:

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

Capybara tìm thấy một số .itemvì vậy nó đưa ra một ngoại lệ. Tôi coi hành vi này của Capybara 2 rất tốt.


4
Tôi khuyên bạn không nên sử dụng #first, nó không chờ đợi một yếu tố tồn tại: rubydoc.info/github/jnicklas/caccobara/ . Nếu nội dung được tạo trong thời gian chạy với JS trước tiên sẽ trả về nil nếu nó chạy kỳ vọng trước khi liên kết được tạo.
dgtized


24

Phrasing này cũng hoạt động:

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

Làm việc cho tôi, cảm ơn. Capybara 2.4.1 và kiểm soát viên.
Mauricio Moraes

4

Xpath có thể giải quyết phần tử. Tôi không tốt lắm với nó, nhưng một cái gì đó như//div[@class='active'][1]/a

Điều đó có thể hoặc không thể hoạt động, nhưng vấn đề là xpath có thể giải quyết một loạt các trận đấu và rút ra một kết quả cụ thể. Bạn sẽ có thể phù hợp với điều này.

Một ví dụ hoạt động từ một trong các dự án của tôi:

trong page.find ("div.panel", văn bản: / Đề xuất /) làm
  trong page.find ('tr', văn bản: / Foo /) làm
    page.should have_xpath ('td [3]', văn bản: @today)
  kết thúc
kết thúc

2

Vì đầu tiên () không phải lúc nào cũng chờ đợi, có lẽ điều này hữu ích:

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

2

hầu hết các giải pháp đó sẽ không sử dụng các tính năng chờ đợi tuyệt vời của Capybara

làm tốt hơn vì liên kết này gợi ý: https :
// Dùtbot.com / blog

Xấu:

first(".active").click
Nếu chưa có phần tử .active trên trang, đầu tiên sẽ trả về nil và lần nhấp sẽ thất bại.

Tốt

Nếu bạn muốn chắc chắn có chính xác một
find(".active").click

Nếu bạn chỉ muốn phần tử đầu tiên,
find(".active", match: :first).click
Capybara sẽ đợi phần tử xuất hiện trước khi thử nhấp.

Lưu ý rằng match: :firstnó dễ vỡ hơn, bởi vì nó sẽ âm thầm nhấp vào một yếu tố khác nếu bạn giới thiệu các yếu tố mới phù hợp.


Tôi tin rằng đây là câu trả lời chính xác nhất.
katericata

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.