如何在水豚中获得父节点?


85

我正在使用许多jQuery插件,这些插件通常会创建没有id或其他标识属性的DOM元素,而在Capybara中获取它们的唯一方法(例如单击)-首先获取其邻居(其祖先的另一个孩子) 。但是我什么都没找到,水豚支持这样的事情,例如:

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


另外,如果您告诉我,水豚是否会使用{display:hidden}生成对元素的点击,并且有某种方法可以在某些范围内查找display!= hidden吗?
Sandrew

这是一个单独的问题,但这取决于您使用的驱动程序。webrat会很高兴找到隐藏的东西,但是硒对于单击看不见的项目并不满意。
jamuraa'2

Answers:


111

我确实发现jamuraa的答案很有帮助,但是在我的情况下,选择完整的xpath会使我感到噩梦,因此我很高兴利用在Capybara中连接find的功能,使我可以将css和xpath选择混合在一起。您的示例将如下所示:

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

Capybara 2.0更新:极find(:xpath,".//..")有可能导致Ambiguous match错误。在这种情况下,请first(:xpath,".//..")改用。


感谢您的想法-我永远都不会想到这一点!我正在为用find(:css)找到的td元素做el.parent,但是由于某种原因,我不明白,el.parent返回#<Capybara :: Document>。另一方面,el.find(:xpath,“ .// ..”)返回#<Capybara :: Element tag =“ tr”>,这是我需要的。
泰勒·里克

递归查找某个父节点的另一种方法是使用xpath的祖先或自我选择器。检查出来stackoverflow.com/questions/1362466/...
vrish88

25
您无需.//..找到父项,就..足够了,也永远不会模棱两可。
Eamon Nerbonne

ty!我知道这条评论对党来说有点晚了,但是在阅读了编辑内容和Eamon的评论后,我将其简化为以下几点:el.first(:xpath,'..')
aschyiel 2014年

39

水豚和CSS无法做到这一点。不过,我过去曾使用XPath来实现此目标,它确实有一种获取父元素的方式,并且受到Capybara的支持:

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

2
当我执行类似的xpath查找时,出现Nokogiri错误,表示表达式无效。我在表达式中的方形方形find(:xpath, '//*[@id="some_button"]/..')
刹车框前面

35

我发现以下确实有效:

find(:xpath, '..')

水豚已经更新以支持此操作。

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


1
在我看来,您正在此处回答/完成先前的回答(“这”是什么“不起作用”?)。如果这是一个完整而独立的答案,那就更好了。因此,我建议您对其进行编辑。;-)
helenov

可以确认。在最新的Capybara 2.14.4中,这是获取父节点的正确方法。
fny17年

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

警告:请谨慎使用此功能,这可能会花费您大量时间进行测试,因此请确保距离祖先只有几步之遥。


加速:将第二个休息时间替换为break if ancestor[:class].split(" ").include?(css_class)
hakunin 2015年

@hakunin我很好奇您看到多少加速?重大?
kross 2015年

现在无法测试,但是has_css似乎需要一秒钟,而匹配该类似乎是立即的。
hakunin 2015年

水豚现在有一个ancestor(selector)内置的方法见。github.com/teamcapybara/capybara/commit/...
泰勒里克

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.