技术改变人生!

Selenium用className找不到元素时,用xpath或css

上一篇 / 下一篇  2013-07-03 16:13:42 / 个人分类:selenium

如果用className查找不到页面元素,我们可以使用xpath,或者是css查找元素,以下是使用方法:

css查找

如button上有class属性的,如:

 <button id="ext-eng=1026" class="x-right-button"...>
可以这样写:
css=button.x-right-button
.代表class
如果class里带的空格,用.来代替空格如:
<button class="x-btn-text module_picker_icon">...
可以这样写:
css=button.x-btn-text.module_picker_icon
如果想用别的属性值定位,用方括号【属性名=属性值】的方式,如:
<abbr>Abc<abbr/>
css=abbr[title="Abc"]
如果button上有id属性的,如:
<input id="ag_name" type="text"...>
可以这样写:
css=input#ag_name 
或者直接写 
css=#ag_name
#代表id
但是在实际应该中,如果有元素固定id的,可以直接用id locator,这样写:
id=ag_name
这通常是在Form里的input元素, 需要用户填写内容然后提交的部分,也是最简单的部分。
没有固定id的,通常是由javascript框架自动生成的id如,每次加载页面都会改变的,如:
<button id="ext-eng-1026" >,下回可能就是<button id="ext-eng-2047">
这种情况不能使用id属性来定位。
如果你想定位一个显示OK的Button,但页面上有几个Button,id是自动生成的,class是一样的,我又想用一个简单点的CSS locator的时候,
<button id="ext-eng-1026" class="x-right-button">OK</button>
<button id="ext-eng-1027" class="x-right-button">Cancel</button>
可以这样写: 
css=button.x-right-button:contains("OK")
:contains是个Pseudo-class,用冒号开头,括号里是内容。
Pseudo-classes是CSS提供的伪类,用来访问页面上DOM tree之外的信息,还有Pseudo-elements 用来最精准的定位页面上的某一行文字,甚至某一行文字的第一个字母。我也是昨天头一回听说有这玩意儿,具体可以研究一下css3 selector文档的Chapter 6.6 Pseudo-classes 和 Chapter 7 Pseudo-elements
基本上用XPath能定位的元素,都能用CSS Selector定位到。
它两最相似的是这样写: 
<table><tr><td><div><span>abcd</span><span>1234</span></div></td></tr></table>
xpath=//table/tr/td/div/span[1]
css=table>tr>td>div>span:nth-child(1)
*xpath没在页面上测试过。
一个非常好的blog,不看可惜了。
http://saucelabs.com/blog/index.php/2009/10/selenium-tip-of-the-week-start-improving-your-locators/
综上所述,就是:
有固定id的用id selector, 
没有固定id的用css selector。 
Pseudo-selements :contains()很好用。
会了这几下子,基本上定位就不成问题了。
 
 

XPath:preceding-sibling

     XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。

     XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 同时被构建于 XPath 表达之上。

     推荐一个挺不错的网站:http://www.zvon.org/xxl/XPathTutorial/General_chi/examples.html  里面有很不错的例子,下面的例子中红色字体表示使用对应语法获取的元素(或属性)。

     XPath轴(XPath Axes)可定义某个相对于当前节点的节点集:

     1、child  选取当前节点的所有子元素

     2、parent  选取当前节点的父节点

     3、descendant选取当前节点的所有后代元素(子、孙等)

     4、ancestor  选取当前节点的所有先辈(父、祖父等)

     5、descendant-or-self选取当前节点的所有后代元素(子、孙等)以及当前节点本身

     6、ancestor-or-self  选取当前节点的所有先辈(父、祖父等)以及当前节点本身

     7、preceding-sibling选取当前节点之前的所有同级节点

     8、following-sibling 选取当前节点之后的所有同级节点

     9、preceding   选取文档中当前节点的开始标签之前的所有节点

     10、following   选取文档中当前节点的结束标签之后的所有节点

     11、self  选取当前节点

     12、attribute  选取当前节点的所有属性

     13、namespace 选取当前节点的所有命名空间节点

 

     preceding-sibling,选取当前节点之前的所有同级节点,同一个parent下该节点之前的节点,即“哥哥”节点(是同父的哥哥节点)。

 

    /AAA/XXX/preceding-sibling::*    /AAA/XXX节点的所有之前同级节点

  <AAA>   

        <EEE/> 

 

     <BBB> 

          <CCC/> 

          <DDD/> 

     </BBB> 

     <XXX> 

          <DDD> 

               <EEE/> 

               <DDD/> 

               <CCC/> 

               <FFF/> 

               <FFF> 

                    <GGG/> 

               </FFF> 

          </DDD> 

     </XXX> 

     <CCC> 

          <DDD/> 

     </CCC> 

   </AAA>

     //CCC/preceding-sibling::*   选取所有CCC节点的同级哥哥节点

  <AAA> 
     <BBB> 
          <CCC/> 
          <DDD/> 
     </BBB> 
     <XXX> 
          <DDD> 
               <EEE/> 
               <DDD/> 
               <CCC/> 
               <FFF/> 
               <FFF> 
                    <GGG/> 
               </FFF> 
          </DDD> 
     </XXX> 
     <CCC> 
          <DDD/> 
     </CCC> 
  </AAA>

TAG:

引用 删除 1234567809   /   2016-03-10 16:09:52
<input id="aui_3_4_0_1_215" class="aui-button-input aui-button-input-submit" type="submit" value="Sign In">  源代码是这样的
引用 删除 1234567809   /   2016-03-10 16:09:20
具体的表现呢?  感觉都是写这一点 你看我这个对不?    driver.findElement(By.cssSelector("button[class='button.aui-button-input.aui-button-input-submit']")).click();
 

评分:0

我来说两句

Open Toolbar