จะคลิกลิงค์แรกในรายการไอเทมหลังจากอัพเกรดเป็น Capybara 2.0 ได้อย่างไร


125

วิธีคลิกลิงค์แรกในกรณีนั้น:

<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

คำตอบ:


176

คุณสามารถใช้:

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รายการดังนั้นจึงมีข้อยกเว้น ฉันถือว่าพฤติกรรมของ Capybara 2 นี้ดีมาก


4
ผมอยากจะแนะนำต่อโดยใช้ #first ก็ไม่ได้รอให้องค์ประกอบจะมีชีวิตอยู่ต่อไปนี้: rubydoc.info/github/jnicklas/capybara/... หากเนื้อหาถูกสร้างขึ้นที่รันไทม์ด้วย JS ก่อนจะส่งคืนค่า nil หากรันความคาดหวังก่อนที่จะสร้างลิงก์
dgtized

122

ลองทำดังต่อไปนี้:

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

แหล่งที่มา:


1
น่าอัศจรรย์ และใช้งานได้บน page.find ('# {css}',: match =>: first) คลิกไชโยสำหรับคำตอบที่เป็นประโยชน์จริงๆ
Dono


4

Xpath สามารถระบุองค์ประกอบได้ ฉันยังไม่ค่อยดีกับมัน แต่มีบางอย่างเช่น//div[@class='active'][1]/a

นั่นอาจได้ผลหรือไม่ก็ได้ แต่ประเด็นก็คือ xpath สามารถจัดการอาร์เรย์ของการจับคู่และดึงข้อมูลที่ต้องการ คุณน่าจะเข้ากับสิ่งนี้ได้

ตัวอย่างการทำงานจากหนึ่งในโครงการของฉัน:

ภายใน page.find ("div.panel", text: / Proposals /) do
  ภายใน page.find ('tr', ข้อความ: / Foo /) do
    page.should have_xpath ('td [3]', text: @today)
  ปลาย
ปลาย

3

โซลูชันเหล่านี้ส่วนใหญ่จะไม่ใช้คุณสมบัติการรอที่ยอดเยี่ยมของ Capybara

ทำได้ดีกว่าตามลิงค์นี้:
https://thoughtbot.com/blog/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element

แย่:

first(".active").click
หากยังไม่มีองค์ประกอบ. active ในหน้าขั้นแรกจะคืนค่าศูนย์และการคลิกจะล้มเหลว

ดี:

หากต้องการแน่ใจว่ามีอย่างใดอย่างหนึ่ง
find(".active").click

หากคุณต้องการเพียงแค่องค์ประกอบแรก
find(".active", match: :first).click
Capybara จะรอให้องค์ประกอบนั้นปรากฏก่อนที่จะพยายามคลิก

โปรดทราบว่าmatch: :firstมีความเปราะมากขึ้นเนื่องจากจะคลิกองค์ประกอบอื่นโดยไม่โต้ตอบหากคุณแนะนำองค์ประกอบใหม่ที่เข้ากันได้


ฉันเชื่อว่านี่เป็นคำตอบที่ถูกต้องที่สุด
katericata

2

ตั้งแต่แรก () ไม่รอเสมอไปบางทีนี่อาจเป็นประโยชน์:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.