จะรับโหนดหลักใน Capybara ได้อย่างไร


86

ฉันกำลังทำงานกับปลั๊กอิน jQuery จำนวนมากซึ่งมักสร้างองค์ประกอบ DOM โดยไม่มี id หรือคุณสมบัติการระบุตัวตนอื่น ๆ และวิธีเดียวที่จะได้รับใน Capybara (ตัวอย่างเช่นการคลิก) - คือการรับเพื่อนบ้าน (ลูกหลานอีกคนของบรรพบุรุษ) ก่อน . แต่ฉันไม่พบที่ไหน Capybara สนับสนุนสิ่งต่างๆเช่น:

find('#some_button').parent.fill_in "Name:", :with => name

เหรอ?


นอกจากนี้มันจะมีประโยชน์มากสำหรับฉันถ้าคุณบอกว่า Capybara สร้างการคลิกที่องค์ประกอบด้วย {display: hidden} หรือไม่และมีวิธีค้นหาองค์ประกอบในบางขอบเขตที่ display! = hidden หรือไม่?
sandrew

นี่เป็นคำถามแยกต่างหาก แต่ขึ้นอยู่กับไดรเวอร์ที่คุณใช้ Webrat จะพบสิ่งที่ซ่อนอยู่อย่างมีความสุข แต่ซีลีเนียมไม่พอใจที่จะคลิกรายการที่คุณมองไม่เห็น
jamuraa

คำตอบ:


111

ฉันพบว่าคำตอบของ jamuraa มีประโยชน์จริงๆ แต่การไปหา xpath แบบเต็มทำให้ฉันฝันร้ายของสตริงในกรณีของฉันดังนั้นฉันจึงใช้ความสามารถในการเชื่อมต่อการค้นหาใน Capybara อย่างมีความสุขทำให้ฉันสามารถผสมการเลือก css และ xpath ได้ ตัวอย่างของคุณจะมีลักษณะดังนี้:

find('#some_button').find(:xpath,".//..").fill_in "Name:", :with => name

การอัปเดต Capybara 2.0 : find(:xpath,".//..")มักจะทำให้เกิดAmbiguous matchข้อผิดพลาด ในกรณีนั้นให้ใช้first(:xpath,".//..")แทน


ขอบคุณสำหรับความคิดนั้น - ฉันไม่เคยคิดแบบนั้นมาก่อน! ฉันกำลังทำ el.parent สำหรับองค์ประกอบ td ที่ฉันพบด้วย find (: css) แต่ด้วยเหตุผลบางอย่างที่ฉันไม่เข้าใจ el.parent กำลังส่งคืน # <Capybara :: Document> el.find (: xpath, ".// .. ") ในทางกลับกันจะส่งกลับ # <Capybara :: Element tag = "tr"> ซึ่งเป็นสิ่งที่ฉันต้องการ
Tyler Rick

อีกวิธีในการค้นหาโหนดแม่แบบวนซ้ำคือการใช้ตัวเลือกบรรพบุรุษหรือตัวเองของ xpath ลองดูที่stackoverflow.com/questions/1362466/…
vrish88

25
คุณไม่จำเป็นต้อง.//..พบผู้ปกครองเพียงแค่..พอเพียงและนั่นไม่เคยคลุมเครือ
Eamon Nerbonne

ไท! ฉันรู้ว่าความคิดเห็นนี้ช้าไปหน่อยสำหรับงานเลี้ยง แต่ฉันย่อความคิดเห็นต่อไปนี้หลังจากอ่านการแก้ไขและความคิดเห็นของ Eamon: el.first (: xpath, '.. ')
aschyiel

39

ไม่มีวิธีดำเนินการกับ capybara และ CSS ฉันเคยใช้ XPath ในอดีตเพื่อบรรลุเป้าหมายนี้ซึ่งมีวิธีรับองค์ประกอบหลักและได้รับการสนับสนุนโดย Capybara:

find(:xpath, '//*[@id="some_button"]/..').fill_in "Name:", :with => name

2
เมื่อฉันค้นหา xpath ที่คล้ายกันฉันได้รับข้อผิดพลาด Nokogiri แจ้งว่านิพจน์ไม่ถูกต้อง ฉันเพิ่มเครื่องหมายดอกจันที่ด้านหน้าของวงเล็บเหลี่ยมเปิดในนิพจน์เพื่อแก้ไขนิพจน์:find(:xpath, '//*[@id="some_button"]/..')
Andrew Ferk

35

ฉันพบสิ่งต่อไปนี้ที่ใช้งานได้:

find(:xpath, '..')

Capybara ได้รับการอัปเดตเพื่อรองรับสิ่งนี้

https://github.com/jnicklas/capybara/pull/505


1
สำหรับฉันดูเหมือนว่าคุณกำลังตอบกลับ / ตอบคำตอบก่อนหน้านี้ที่นี่ ("นี่" อะไร "ใช้ไม่ได้"?) จะดีกว่าถ้าเป็นคำตอบที่สมบูรณ์และเป็นอิสระ ดังนั้นฉันขอแนะนำให้คุณแก้ไข ;-)
helenov

สามารถยืนยัน. ด้วย Capybara 2.14.4 ล่าสุดนี่เป็นวิธีที่เหมาะสมในการรับโหนดหลัก
fny

10

หากคุณสะดุดในสิ่งนี้โดยพยายามหาวิธีค้นหาโหนดหลัก (ตามบรรพบุรุษ ) (ตามที่ระบุไว้ในความคิดเห็นของ @ vrish88 เกี่ยวกับคำตอบของ @Pascal Lindelauf):

find('#some_button').find(:xpath, 'ancestor::div[@id="some_div_id"]')

5

คำตอบนี้เกี่ยวกับวิธีจัดการองค์ประกอบพี่น้องซึ่งเป็นสิ่งที่ฉันเชื่อว่าคำถามเดิมพาดพิงถึง

สมมติฐานคำถามของคุณใช้ได้ผลกับการปรับแต่งเล็กน้อย หากฟิลด์ที่สร้างแบบไดนามิกมีลักษณะเช่นนี้และไม่มี id:

<div>
  <input></input>
  <button>Test</button>
</div>

คำถามของคุณจะเป็น:

find('button', text: 'Test').find(:xpath, "..").find('input').set('whatever')

หากอินพุตที่สร้างแบบไดนามิกแนบมาพร้อมกับองค์ประกอบ id (โปรดระวังสิ่งเหล่านี้แม้ว่าในเชิงมุมจะไม่เปลี่ยนแปลงตามการเพิ่มและลบองค์ประกอบ) มันจะเป็นดังนี้:

find('button', text: 'Test').find(:xpath, "..").fill_in('#input_1', with: 'whatever')

หวังว่าจะช่วยได้


4

ฉันใช้วิธีการอื่นโดยการค้นหาองค์ประกอบหลักก่อนโดยใช้ข้อความภายในองค์ประกอบหลักนี้:

find("<parent element>", text: "text within your #some_button").fill_in "Name:", with: name

บางทีนี่อาจเป็นประโยชน์ในสถานการณ์ที่คล้ายคลึงกัน


1
นี่เป็นตัวเลือกที่ยอดเยี่ยม การกำหนดขอบเขตการดำเนินการ ui ให้เป็นส่วนหนึ่งของหน้าที่มีข้อความเฉพาะเป็นกรณีการใช้งานทั่วไปสำหรับฉัน
clemensp

2

ฉันต้องการค้นหาบรรพบุรุษด้วยคลาส css แม้ว่ามันจะไม่แน่นอนหากบรรพบุรุษเป้าหมายมีคลาส css ตั้งแต่หนึ่งคลาสขึ้นไปดังนั้นฉันจึงไม่เห็นวิธีสร้างคิวรี xpath ที่กำหนด ฉันทำสิ่งนี้แทน:

def find_ancestor_with_class(field, cssClass)
  ancestor = field
  loop do
    ancestor = ancestor.find(:xpath, '..')
    break if ancestor.nil?

    break if ancestor.has_css? cssClass
  end

  ancestor
end

คำเตือน: ใช้สิ่งนี้เท่าที่จำเป็นอาจทำให้คุณเสียเวลามากในการทดสอบดังนั้นตรวจสอบให้แน่ใจว่าบรรพบุรุษอยู่ห่างออกไปเพียงไม่กี่ครั้ง


Speedup: break if ancestor[:class].split(" ").include?(css_class)แทนที่แบ่งที่สองของคุณด้วย
hakunin

@hakunin ฉันอยากรู้ว่าคุณเห็น speedup มากแค่ไหน? มีนัยสำคัญ?
kross

ไม่สามารถทดสอบได้ในขณะนี้ แต่ has_css ดูเหมือนจะใช้เวลาสักครู่ในขณะที่การจับคู่ชั้นเรียนดูเหมือนจะทันที
hakunin

Capybara ตอนนี้มีancestor(selector)วิธีการสร้างขึ้นในดู. github.com/teamcapybara/capybara/commit/...
ไทเลอร์ริก

-5

นี่คือ

http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Base:parent

มีเมธอดผู้ปกครองอยู่;)


5
สิ่งนี้ส่งคืนเฉพาะเอกสารระดับบนสุดให้ฉัน ไม่แน่ใจว่าเป็นปัญหาของไดรเวอร์หรืออะไร
Nerdmaster

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