自动化测试框架:Selenium 剖析(1.2)

Source
二.Selenium 元素定位大全

元素的定位是整个Web自动化中的重点以及难点。Selenium实现网页的控制操作主要是通过控制前端的元素来完成,在这个过程中,元素的定位是基础,只有准备抓取到对应元素才能进行后续的自动化控制。

1. 8种基本元素定位

1)id 定位

       这是一种最常见的定位方式,假设已知某个元素的id或通过Firebug查找得到id的相关信息,可通过此方法进行定位,比如如下:

driver.find_element(By.ID,"findpwd")

    2) name 定位

         name定位方式将会识别首个name属性等于定位值得页面元素,如果多个元素得name属性都相同,那么可以使用过滤器来进一步细化定位。默认得过滤器类型是value,比如如下:

    driver.find_element(By.NAME,"username")

    3)class_name 定位

         HTML 规定使用class来指定元素得类型,class属性在页面中不是唯一的。

    实例代码如下:

    driver.find_element(By.CLASS_NAME,"logindo")

    4)tag_name 定位

         通过标签的名称来定位元素的位置,这种方法比较困难,因为同一个页面中相同名称的标签往往比较多。

    实例代码如下:

    driver.find_element(By.TAG_NAME,"input")

    5)link_text 定位

         link_text专门来定位文本链接。

    实例代码如下:

    driver.find_element(By.LINK_TEXT,"忘记密码?")

    注意:此处的文本最好直接复制页面上的,不建议手动输入,因为手动输入的文本可能会存在部分差异,如空格,中英文符号问题等。

    6)partial_link_text 定位

         partial_link_text 是link_text的一种补充,有些文本链接较长时,可以提取文本链接的一部分进行定位,只要这一部分信息可以唯一地标识出这个链接。

    实例代码如下:

    driver.find_element(By.PARTIAL_LINK_TEXT,"忘记")
    7) Xpath 定位

         XPath定位方式由XML和Path两部分构成,以XML格式的树状结构形式进行递归逐级定位。XPath定位的两种方式:绝对路径定位,相对路径定位。

    绝对路径:从顶级父标签到当前标签的整个路径结构称为绝对路径。

    相对路径:表示相对当前标签而言的路径结构。常用的定位方式有以下几种。

    (1) 属性定位语法://标签名[@属性名=属性值]

    注意:1.标签名可以具体,也可以使用*。2.属性值如果是字符串则需要使用引号。

    (2) 使用逻辑运算符可以实现多个属性定位,逻辑运算符有and,or,not。例如,//input[@name='uname'and@pwd='upassword'],但是一般组合的属性不会超过2个,因为设定的属性越多,对脚本的依赖就越高。

    (3) 嵌入函数完成XPath定位。

    1)text函数定位语法://标签名[text()=对应标签的文本内容]。

    2)contains函数定位语法://标签名[contains(@属性名,对应属性名的前面部分值)]。

    3)starts-with函数定位语法://标签名[starts-with(@属性名,对应属性名的前面部分值)]。

    4)ends-with函数定位语法://标签[ends-with(@属性名,对应属性名的后面部分值)]。

    注意:一般starts-with,ends-with函数能完成定位的,contains函数也能完成,所以在实际工作中contains函数应用的更多。

    8)css定位方式

    CSS的定位主要是通过选择器来完成的,这属于CSS的高级定位。

                                                CSS定位中选择器的常用语法

    选择器 示例 语法说明
    .class .logindo 选择class='logindo'的所有元素
    #id #findpwd 选择id='findpwd'的所有元素
    * * 选择所有元素
    element p

    选择所有<p>元素

    1.By定位

    具体语法如下:

    (1)find_element(By.ID,"kw")

    (2)find_element(By.NAME,"wd")

    (3)find_element(By.CLASS_NAME,"s_ipt")

    (4)find_element(By.TAG_NAME,"input")

    (5)find_element(By.LINK_TEXT,u"新闻")

    (6)find_element(By.PARTIAL_LINK_TEXT,u"新")

    (7)find_element(By.XPATH,"//button[text()='登录']")

    (7)find_element(By.CSS_SELECTOR,"div[id="3"]>h3>a")

    注意:使用上面这些定位方式的前提是需要导入By类,具体导入语法:from selenium.webdriver.common.by import By。

    2.父子定位,二次定位

    父子定位:如果当前标签或者子级标签中不存在任何属性可以作为定位方式,则可以查找当前标签的父标签是否存在可定位的属性;如果父级还没有,则可以继续向上一级查找,以此类推,直到查找到可定位的标签。

    二次定位:可以先定位到可定位的其中一级标签获取对象,然后再通过该对象作为基准再次定位。

    3.JS定位

          除了Selenium前面的WebDriver的基本定位方式,还有一些使用基本定位方式无法解决的,如Windows窗口,浏览器滚动条等,这时就需要使用到JS定位。

    JS定位实际是使用DOM树的定位方式。DOM树表示树形展示的层级结构,层级结构很好地体现了元素与元素之间的联系。当指出树中所包含的DOM节点时,简单来说就是这个树实现了DOM接口的元素构成,同时这些实现包含了一些其他浏览器内部所需的属性信息。例如:

    document.getElementById("su")

    常用的几种定位方式的总结如下。

    (1)id定位:document.getElementById()

    (2)name定位:document.getElementByName()

    (3)tag定位:document.getElementByTagName()

    (4)class定位:document.getElementsByClassName()

    (5)CSS定位:document.querySelectorAll()

    以上方法都属于document对象的方法,document表示当前HTML页面的对象。

    注意:(1)在使用以上方式进行定位时,name,tag,class,CSS定位返回的对象都是复数形式,所以需要通过索引获取具体对象。(2)文本赋值使用的是该方法的value属性,如果是按钮则直接使用click()方法。(3)如果已通过定位元素获取了对应的对象,但是该对象无法直接完成某些事件的操作,则可以通过该对象调用该标签中声明的操作事件的属性值(使用js脚本完成),然后直接使用execute_script执行即可。

    4.jQuery 定位

        常用的jQuery定位方法有两种:一种使用jQuery选择器来完成元素的选择操作,可以直接获取一个或者一组元素;另外一种就是通过jQuery遍历来选择元素,这种方法常用在获取层级较为复杂的页面元素的情况。

        jQuery语法实际是为了HTML元素的选择设置的,不仅可以完成定位,还可以直接对元素完成一些具体的操作,基础语法如下:

    $(selector).action()

       jQuery通过$符号进行定义,selector选择器主要用于获取具体的HTML元素,而action()用于实现对获取的元素的具体操作。

    常用的操作如下:

    $(selector).val('input_value')
    $(selector).val('')
    $(selector).click()
    

    jQuery常用方法总结:

    (1)核心方法

    $("Element").length  #元素的个数,length是属性
    $("Element").size() #元素的个数,size()是方法。
    $("Element").get() #获取元素在页面中的集合,以数组的形式存储
    $("Element").get(index) #index表示第几元素,是数组的下标。
    $("Element").get().reverse() #将得到的数组逆序排列
    $("Element").index($('Element2')) #获取元素2在元素1中的索引值。
    

    (2)层级元素获取

    $("Element1 Element2 Element3...")  #前面是父级,后面是子集
    $("div>p")  #获取div元素后面的直接后代p元素
    $("div+p")  #获取div元素后面的第一个p元素
    $("div~p")  #获取div元素之后所有同层级的p元素
    

    (3)简单对象获取

    $("Element:first")  #HTML页面中某类元素的第一个元素
    $("Element:last")   #HTML页面中某类元素的最后一个元素
    

    (4)内容对象的获取和对象可见性

    $("Element:contains(text)") #获取包含text的元素

    (5)子元素的获取

    $("Element:nth-child(index)")  #选择父级下面的第n个元素。
    $("Element:first-child")       #选择父级下面的最后一个子元素。
    $("Element:last-child")        #选择父级下面的最后一个子元素。