【问题标题】:Using CSS selectors instead of XPath locators when searching through siblings搜索同级时使用 CSS 选择器而不是 XPath 定位器
【发布时间】:2016-11-08 19:55:34
【问题描述】:

目前,我有以下页面对象字段:

this.filterTeamDropdown = $("filter-item-edit .dropdown button");
this.teams = this.filterTeamDropdown.all(by.xpath("following-sibling::ul//li[contains(@class, 'dropdown-list-item')]"));

有没有办法替换 teams 字段的 XPath 定位器并使用 CSS 选择器来代替?


它的动机来自Style Guiderecommendation not to use XPaths

据我了解,不可能有一个 CSS 选择器从上下文中的当前元素开始转到下一个兄弟姐妹。但是,有其他选择吗?

【问题讨论】:

  • @Bhansa 是的,我知道+ 是我正在寻找的,但问题是,我不能简单地用+ 启动选择器并期望它在以下环境中工作当前元素。而且,没有办法在选择器字符串中引用当前节点。谢谢。
  • XPath 可能是样式指南所说的“最脆弱”的策略,但我怀疑这只是因为它可以做 CSS 做不到的事情。与 CSS 表达式做同样事情的 XPath 表达式并不比等效的 CSS 更脆弱。而在这种情况下,CSS 显然无法满足您的需求。
  • @LarsH 好点。实际上,我认为该指南太残忍了,并且对 XPath 的陈述太强烈,因为很明显,它有实际的实际用例,在 CSS 选择器中没有直接的替代方案。有时,尽管人们过度使用 xpaths 作为适用于代码库中每个定位器的灵丹妙药,这会导致问题过于复杂,并使维护测试代码变得更加困难。谢谢,请随时将其发布为答案 - “不,在这种情况下仍然使用 xpath 并且不要担心”是一个有效的意见。
  • Alecxe,我同意,风格指南的“从不”建议太强了。 XPath 肯定被那些试图在不理解的情况下使用它的人滥用,但该指南反应过度。与任何语言一样,如果您在团队中工作而其他人必须维护您的代码,则在选择要使用的语言时需要考虑这一点。 XPath 也不太适合关于类的谓词。 (我犹豫是否要提交答案,因为我对 CSS 的了解不够充分,无法说它不能执行“当前元素的跟随兄弟”。)

标签: javascript selenium xpath css-selectors protractor


【解决方案1】:

对任何事情说从不是愚蠢的。我强烈支持 CSS 选择器,因为通过 id 定位元素、CSS 选择器、几乎任何东西……都比 XPath 快。但是...同时我们说的是几毫秒的差异。

XPath 可以做一些其他定位器方法无法做到的事情。想到的一个例子是通过包含的元素文本查找元素(A 除外)。除此之外,当 ID 不起作用时,我通常会坚持使用 CSS 选择器。

我非常不喜欢很多人在 SO 上的定位器策略,因为 XPath 似乎是查找元素的首选方法,以至于它很愚蠢。我见过人们只寻找一个 id 并使用 XPath。我认为部分原因是您可以轻松获得 XPath,右键单击检查器中的元素并复制 XPath 并粘贴到代码中。我相信您知道,问题在于有时(很多时候?)这会导致 XPath 非常脆弱,但有些/很多人不知道更好。

说了这么多,我将向您指出 W3C CSS 选择器参考,也许您可​​以找到您正在寻找的东西。那里有一些兄弟组合器,但我没有你的 HTML,所以我不知道它们中的哪一个(如果有的话)可以工作。

https://www.w3.org/TR/selectors/#selectors

https://www.w3.org/TR/selectors/#adjacent-sibling-combinators


我刚刚阅读了您问题下方的一些 cmets,发现您已经了解 + 组合器。是否有某些原因您不能将初始定位器 CSS 与 XPath 转换的字符串一起使用?我不知道这是否有效/可用,但在将 XPath 转换为 CSS 选择器之后,我已经组合了您在代码中提供的两个定位器。

filter-item-edit .dropdown button + ul li.dropdown-list-item

【讨论】:

  • 找到了一种用 Protractor 解决它的方法,看看我的答案。谢谢。
【解决方案2】:

还有另一种 Protractor 特定的方法来解决它 - 使用父元素的 locator() 并连接以制作子元素选择器:

this.filterTeamDropdown = $("filter-item-edit .dropdown button");
this.teams = this.filterTeamDropdown.$$(this.filterTeamDropdown.locator().value + " + ul li.dropdown-list-item")

【讨论】:

    猜你喜欢
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 2018-05-04
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多