您从哪个层次开始选择器?似乎有一个从目标元素的容器开始的约定,但是为什么不从目标元素本身开始,特别是在id的情况下,还是以通配符加唯一标识符开头的情况?递归血统似乎是每个人最好的朋友。
XPaths和Css-Selector的用途非常广泛,可以用许多不同的方式描述相同的元素-即单个元素具有无限多个可能的定位符来描述它。目标是获得一些满足开发人员需求的东西,其中可能包括可读性,唯一性或自适应性。
考虑以下html示例:
<div id='mainContainer'>
<span>some span</span>
</div>
如果我要为<span>
元素定位,我不会选择//span
,因为这可能会产生太多结果。相反,您可以从具有ID的父对象开始,然后继续到跨度://*[@id='mainContainer']/span
,或者://span[parent::*[@id='mainContainer']]
。哪个XPath更好?您个人认为哪一个更具可读性。我同意你的看法,尽管我本人更偏爱后者,但第一个例子似乎更常见。
有时以某种方式使定位器具有适应性。例如,我很少写这样的定位符://*[@class='fooBar']
。原因是因为在现代Web开发中,类经常出现变化,并且该元素的类很可能会稍作改动。相反,您可以写//*[contains(@class,'fooBar')]
。现在,当开发人员加入并为纯样式添加类时,您无需返回并更新所有硒测试。这也是我经常使用通配符的原因。如果开发人员加入并将div
更新为span
,则我的测试仍然有效。
正如@Gilles Quenot所评论的那样,假设id唯一并不总是安全的。许多网站是由某人的失业叔叔编写的,他们在86年参加了html课。他们很糟糕,根本不关心标准或审计。这是另一个原因,您需要在定位器中包含足够的信息以指定您正在谈论的确切元素,而不是描述太多元素的信息太多。
还有一个评论是XPath是双向的,而Css-Selectors不是。这意味着XPath可以从子级到父级,也可以从父级到子级,而Css-Selectors只能从父级到子级。这会影响您从哪个节点开始,并且可能是您看到更多的Css-Selectors从父/祖先节点开始的原因。
TL; DR没有约定,只是个人喜好。做满足您需求的事情。