我怎样才能找到一个跟随Capybara的另一个元素之后的元素?

AKW*_*KWF 9 html css xpath css-selectors capybara

我正在尝试使用学习Capybara进行刮擦任务.到目前为止,我只用它进行测试.有100万的事情,我想学习,但在它的非常基本的部分,我想知道如何找到某个元素是兄弟姐妹,并配备,我能找到另一个元素?

拿一个像这样的页面:

<body>
  <h3>Name1</h3>
  <table>
    ...
  </table>
  <h3>Name2</h3>
  <table>
    ...
  </table>
  <h3>Name3</h3>
  <table>
    ...
  </table>
</body>
Run Code Online (Sandbox Code Playgroud)

我想返回在具有文本Name2<table><h3>元素之后的元素.

我知道如何循环使用元素all,我知道如何使用first而不是find,但我不知道如何"在特定元素Y后面找到第一个元素X ".

tgf*_*tgf 9

CSS

在CSS中,您可以使用兄弟选择器.这些允许您选择兄弟元素; 或者那些处于相同嵌套级别且具有相同父元素的那些.有两种类型的兄弟选择器:

  • '+'相邻的兄弟选择器
  • '〜'一般兄弟选择器(相邻或不相邻的兄弟姐妹)

尽可能避免文本匹配通常是理想的.(这使您的规范更容易编写,也意味着文本更改不太可能破坏您的规范.)在理想世界中,您的'h3'元素可能具有ID,我们可以只:

find('h3#name2+table')
Run Code Online (Sandbox Code Playgroud)

但是,在您的示例中,他们没有ID,所以让我们将几个查询连接到我们想要的范围.

find('h3', text: 'Name2').find('+table')
Run Code Online (Sandbox Code Playgroud)

首先,我们找到了正确的'h3'元素(使用文本匹配),然后以该查询为基础,我们请求兄弟'table'元素.

您可能还会注意到,如果您使用了通用兄弟选择器'〜',则会出现模糊元素错误; Capybara找到了所有"桌子"元素,而不仅仅是相邻的元素.

XPath的

有时,如果您真的被迫进行文本元素选择,XPath实际上更容易使用.所以你可以改为:

find(:xpath, "//h3[contains(text(),'Name2')]/following-sibling::table")
Run Code Online (Sandbox Code Playgroud)

更难读,但做同样的事情.首先找到带有'Name2'文本的'h3',然后选择它的兄弟'table'元素.

  • 我为相邻的兄弟CSS选择器收到了非法的语法错误....但XPath替代方案完美无缺:)有趣的是,我看到有一个[拒绝拉请求](https://github.com/jnicklas/capybara/pull/1434)将此功能添加为内置的Capybara方法; 该实现还使用了"follow-sibling"XPath方法. (3认同)

Que*_*ven 7

Capybara 现在有siblingancestor发现者 (~>=2.15.0)

[2018/09 更新] 正如@trueunlessfalse 所评论的那样,如果有多个匹配项,sibling将返回使用finder的原始答案amgibuous match error。所以,请考虑在这种情况下使用 xpath..

以下使用 xpath 的代码将返回 OP 想要的内容

find('h3', text: 'Name2').first(:xpath, './following-sibling::table')
Run Code Online (Sandbox Code Playgroud)


以下代码将返回 OP 想要的=> 不明确的匹配错误

find('h3', text: 'Name2').sibling('table')
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看详细信息。 https://www.rubydoc.info/github/jnicklas/capybara/Capybara/Node/Finders:sibling