Xpath 使用部分 class 名称和 ruby 中带有水豚的确切文本查找元素

Xpath to find an element using partial class name and exact text with capybara in ruby

我有 html 代码 div 在 class 名称中有与 menu1 相同的匹配文本,文本如

Berlin

Berlin Germany

当我使用下面的代码时 returns 不明确的元素

find(:xpath, "//div[contains(text(), \"Berlin\") and contains(@class, \"menu1\")] ")

注意:我希望 class 和文本都在我的 xpath

将不胜感激,提前致谢。

如果部分 class 名称是指 <div class="blah menu1 other">Berlin</div> 之类的意思,那么您可以使用

之类的可读方式来实现
find('div.menu1', exact_text: 'Berlin')

find('div.menu1', text: 'Berlin', exact: true)

如果它更像 <div class="blah menu1_part other">Berlin</div> 你仍然可以使用更易读的 CSS 选择器来完成它,比如

find('div[class*=menu1]', exact_text: 'Berlin')

如果您出于性能原因实际上需要在一个 XPath 中完成所有操作(页面上有很多 div.menu1 元素,由于某些疯狂的原因您无法在页面的有限部分范围内) 然后你可以做类似

find(:xpath, './/div[text()="Berlin"][contains(@class, "menu1")]')

注意 XPath 表达式中的前导 .。 99.9% 的时间在使用 Capybara 并手动编写您自己的 XPath 表达式时,您希望以 .// 开始您的 XPath 表达式,否则您将破坏您所做的任何范围界定 - 请参阅 https://github.com/teamcapybara/capybara#beware-the-xpath--trap

另一种选择是使用 xpath gem Capybara 在内部用于生成 XPath,类似于

find(:xpath, XPath.css('div.menu1')[XPath.string.n.is('Berlin')], exact: true)

find(:xpath, XPath.css('div[class *= "menu1"]')[XPath.string.n.is('Berlin')], exact: true)

取决于您所说的 partial class name 的确切含义。这样做的好处是 is 方法的含义可以根据 exact 选项的值从 contains 更改为 equals,并且它还处理字符串的所有规范化和转义如果你的字符串不像 'Berlin'

那么简单