Xpath的文本匹配
ummmm 确实很久没有更新过小笔记了…
最近接触了一些新的东西,比如 sketch 插件比如 e2e 测试,可能接下来会穿插着这两项的小知识点记一下小笔记~
今天是一篇关于 e2e 测试的一篇翻译:Xpath 中文本匹配方式,来自 stackOverflow。
首先为什么要使用 Xpath 呢,首先是因为我们的项目中有用 css-modules 的,有用 styled-component 的,className 首先不确定,也不想为每一个元素都添加 data-*
属性;其次相对来说文案是比较固定且通俗易懂的,Xpath 中的 text()
为依赖文案的测试提供了便利,并且支持多属性组合、父元素子孙元素搜索,功能比较强大。
翻译从这里开始:
现下有一个 XML 结构如下:
|
|
想获取到当前结构中所有包含 ABC 文本的节点,使用 //*[contains(text(), "ABC")]
只匹配到了 <Street>
但是没有匹配到 <Comment>
。是因为什么呢?
我们需要了解一下 Xpath 的匹配方式, //*[contains(text(), "ABC")]
中,大致是以下匹配规则:
*
是一个选择器,会匹配所有的元素 – 会返回一个节点集(node-set)[]
是在该节点集中每个节点上运行的条件,若当前节点匹配括号内的条件则匹配,返回布尔值,对第一步的节点集进行过滤操作text()
是一个选择器,是拿到当前节点的所有文本子节点contains
是对字符串进行运算的函数,它的两个参数都是字符串,如果参数不是字符串则会调用string()
方法转换为字符串,所以会把<Comment>
的文本子节点转换为字符串,string()
方法对文档顺序的第一个节点返回string-value
:
所以这个时候当前文本节点是第一个文本子节点,即 BLAH BLAH BLAH
,并不包含 ABC
,所以没有匹配到 <Comment>
那怎么解决这个问题呢,可以这样写 //*[text()[contains(.,"ABC")]]
:
*
是一个选择器,会匹配所有的元素 – 会返回一个节点集(node-set)[]
是在该节点集中每个节点上运行的条件 – 在此,它对文档中的每个元素进行操作text()
是一个选择器,是拿到当前节点的所有文本子节点- 内部的
[]
是在该节点集中每个节点上运行的条件 – 这里是文本节点 contains
是对字符串进行运算的函数,这里的.
指的是对当前的文本节点进行匹配
此时会对文本节点进行依次匹配,而不仅是第一个文本子节点了,就可以匹配到 <Street>
和 <Comment>
。
so,//*[contains(.,"ABC")]
匹配包含 ABC
的任何元素(但根节点除外)。对于上面的 XML 文档,它与 <Home>
,<Addr>
,<Street>
和 <Comment>
元素匹配。同理,//*[contains(.,"BLAH ABC")]
与 <Home>
,<Addr>
和 <Comment>
元素匹配。
文章作者 youting
上次更新 2020-06-09