selenium中的CSS定位

CSS是一种语言,它被用来描述HTML和XML文档的表现。CSS使用选择器来为页面元素绑定属性。这些选择器可以被selenium用作另外的定位策略。
CSS选择器的常见语法:

语法说明
*通用元素选择器,匹配任何元素
E标签选择器,匹配所有使用 E 标签的元素
.info class选择器,匹配所有 class 属性中包含 info 的元素
#footerid 选择器,匹配所有 id 属性等于 footer 的元素
E,F多元素选择器,同时匹配所有 E 元素或 F 元素,E 和 F 之间用逗号分隔
E F后代元素选择器,匹配所有属于 E 元素后代的 F 元素,E 和 F 之间用空格分隔
E > F子元素选择器,匹配所有 E 元素的子元素 F
E + F毗邻元素选择器,匹配紧随 E 元素之后的同级元素 F (只匹配第一个)
E ~ F同级元素选择器,匹配所有在 E 元素之后的同级 F 元素
E[att=‘val’]属性 att 的值为 val 的 E 元素 (区分大小写)
E[att^=‘val’]属性 att 的值以 val 开头的 E 元素 (区分大小写)
E[att$=‘val’]属性 att 的值以 val 结尾的 E 元素 (区分大小写)
E[att*=‘val’]属性 att 的值包含 val 的 E 元素 (区分大小写)
E[att1=‘v1’][att2*=‘v2’]属性 att1 的值为 v1,att2 的值包含 v2 (区分大小写)
E:contains(‘xxxx’)内容中包含 xxxx 的 E 元素
E:not(s)匹配不符合当前选择器的任何元元素

代码例子:

<div class="formdiv">
	<form name="fnfn">
		<input name="username" type="text"></input>
		<input name="password" type="text"></input>
		<input name="continue" type="button"></input>
		<input name="cancel" type="button"></input>
		<input value="SYS123456" name="vid" type="text">
		<input value="ks10cf6d6" name="cid" type="text">
	</form>
	<div class="subdiv">
		<ul id="recordlist">
			<p>Heading</p>
			<li>Cat</li>
			<li>Dog</li>
			<li>Car</li>
			<li>Goat</li>
		</ul>
	</div>
</div>

通过CSS语法进行匹配的实例结果:

locator匹配
css=div
css=div.formdiv
<div class="formdiv">
css=#recordlist
css=ul#recordlist
<ul id="recordlist">
css=div.subdiv p
css=div.subdiv > ul > p
<p>Heading</p>
css=form + div<div class="subdiv">
css=p + li
css=p ~ li
二者定位到的都是 <li>Cat</li>,但是 storeCssCount 的时候,前者得到 1,后者得到 4
css=form > input [name=username]<input name="username">
css=input[name$=id] [value^=SYS]<input value="SYS123456" name="vid" type="hidden">
css=input:not([name$=id] [value^=SYS])<input name="username" type="text"></input>
css=li:contains(‘Goa’)<li>Goat</li>
css=li:not(contains(‘Goa’))<li>Cat</li>

CSS中的结构性定位:
结构性定位就是根据元素的父子、同级中位置来定位,css3标准中有定义一些结构性定位伪类如
nth-of-type,nth-child,但是使用起来语法很不好理解,这里就不做介绍了。

语法说明
E:nth(n) ;E:eq(n)在其父元素中的 E 子元素集合中排在第 n+1 个的 E 元素 (第一个 n=0)
E:first在其父元素中的 E 子元素集合中排在第 1 个的 E 元素
E:last在其父元素中的 E 子元素集合中排在最后 1 个的 E 元素
E:even在其父元素中的 E 子元素集合中排在偶数位的 E 元素 (0,2,4…)
E:odd在其父元素中的 E 子元素集合中排在奇数的 E 元素 (1,3,5…)
E:lt(n)在其父元素中的 E 子元素集合中排在 n 位之前的 E 元素 (n=2,则匹配 0,1)
E:gt(n)在其父元素中的 E 子元素集合中排在 n 位之后的 E 元素 (n=2,在匹配 3,4)
E:only-child父元素的唯一一个子元素且标签为 E
E:empty不包含任何子元素的 E 元素,注意,文本节点也被看作子元素

例如以下代码:

<div class="subdiv">
	<ul id="recordlist">
		<p>Heading</p>
		<li>Cat</li>
		<li>Dog</li>
		<li>Car</li>
		<li>Goat</li>
	</ul>
</div>

匹配示例:

locator匹配
css=ul > li:nth(0)<li>Cat</li>
css=ul > *:nth(0)
css=ul > :nth(0)
<p>Heading</p>
css=ul > li:first<li>Cat</li>
css=ul > :first<p>Heading</p>
css=ul > *:last
css=ul > li:last
<li>Goat</li>
css=ul > li:evenCat, Car
css=ul > li:oddDog, Goat
css=ul > :even<p>Heading</p>
css=ul > p:odd[error] not found
css=ul > li:lt(2)<li>Cat</li>
css=ul > li:gt(2)<li>Goat</li>
css=ul > li:only-child
css=ul > :only-child
css=ul > *:only-child
[error] not found (ul 没有 only-child)
css=div.subdiv > :only-child<ul id="recordlist">

XPath和CSS的类似定位功能比较(可能会有偏差)

定位方式XPathCSS
标签//divdiv
By id//div[@id=‘eleid’]div#eleid
By class//div[@class=‘eleclass’] //div[contains(@class,‘eleclass’)]div.eleclass
By 属性//div[@title=‘Move mouse here’]div[title= Move mouse here]
div[title^=Move]
div[title$=here] div[title*=mouse]
定位子元素//div[@id=‘eleid’]/*
//div/h1
div#eleid >*
div#eleid >h1
定位后代元素//div[@id=‘eleid’]//h1div h1
By index//li[6]li:nth(5)
By content//a[contains(.,‘Issue 1164’)]a:contains(Issue 1164)

通过对比,我们可以看到,CSS 定位语法比 XPath 更为简洁,定位方式更多灵活多样;不过对 CSS 理解起来要比 XPath 较难;但不管是从性能还是定位更复杂的元素上,CSS 优于 XPath.