zoukankan      html  css  js  c++  java
  • appium -- Xpath定位元素

    如文章《Appium基于安卓的各种FindElement的控件定位方法实践》所述,Appium拥有众多获取控件的方法。其中一种就是根据控件所在页面的XPATH来定位控件。

    本文就是尝试通过自己的试验来尝试对Appium如何用xpath来定位控件做一个阐述,当中如有不对的地方敬请大家指出。

    1. 背景

    本文尝试使用的试验对象是SDK自带的NotePad应用实例,假设已经有两个Notes分别是“note1”和“note2”添加到Notepad上面,我们要做的就是尝试用xpath的方法来定位“note2”这个ListView下面的TextView控件。

    注意界面上有3个TextView类型的控件: 最上面的作为整个ListView的Title文本为“Notes”的TextView,Index为0中间的文本为“note2”的TextView,Index也是0最下面的文本为“note1”的TextView。

    e1 = driver.findElementByXPath("//android.widget.TextView[contains(@text,'note2')]");       

    assertThat(el.getText(),equalTo("note2"));

    又如下面的截图:

    这个元素在页面上没有text属性也没有cotent-des的属性,用上面的方法就没有办法正确定位了。

    正确的定位方法:x.find_element("xpath", "//android.widget.RelativeLayout/android.widget.TextView[1]")

    索引从0开始,定位第二个用TextView[1]定位

    2.1.2 通过index查找目标控件

    如果我们像下面的方式使用index为0来查找控件note2,那么将会失败,因为该xpath只是说“我要查找页面上android.widget.TextView类型的index为0的控件“,但如背景所说我们事实上有3个TextView控件,

    其中最上面的和中间的控件他们的Index都是0.所以最终获得的控件其实是Appium第一个找到的最上面文本为”Notes“的TextView。

        	el = driver.findElementByXPath("//android.widget.TextView[contains(@index,0)]");
            assertThat(el.getText(),equalTo("note2"));

    那么我们就要想办法加多点路径,让xpath能分辨出需要的是下面的index为0的TextView,而不是上面的。观看上图的UIAutomatorViewer控件的分层结构,发现这两个TextView是从LinearLayout开始分叉的

    所以我们应该从该路径开始通过数组下标指定我们需要的是”在LinearLayout下面的第二个FrameLayout下面的ListView下面的Index为0的TextView

            el = driver.findElementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[contains(@index,0)]");
            assertThat(el.getText(),equalTo("note2"));

    2.1.3 通过其他属性查找目标控件

    TBD,这些就不一一列举了,参照以上两个示例进行实现就可以了

    2.2 通过指定选择集合的位置获得控件

    按照我的实践和理解,通过这种方式获取控件是不靠谱的,起码存在两个问题。 问题1:控件在集合中的位置是不可控的。

            el = driver.findElementByXPath("//android.widget.TextView[1]");
            assertThat(el.getText(),equalTo("note2"));

    以上的例子我原意是想把UIAutomatorViewer里面的上中下3个TextView中的中间那个给找出来,但结果返回来给我的确实最上面的那个“Notes”。 问题2:通过增加路径层数限制查找指定元素集合不起效。

            el = driver.findElementByXPath("//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[0]");
            assertThat(el.getText(),equalTo("note2"));

    以上例子我本意是想通过增加父路径的限制来表明“我想要的控件是ListView下面的那两个TextView控件中的第一个”,但返回给我的是“An unknown server-side error occurred while processing the command",感觉是越界了的样子。

    2.4 xpath用法官方手册

    至于其他非主流获的通过xpath取控件的方式,请参考xpath官方手册中文版:http://wenku.baidu.com/link?url=tLdn9X4ucgmzYyKj4dpsgSDbshXEw6W8BTyqQAXd0kTMY6lBQqLiIL9FHtcZmdIeO8o5ZKV-fzlw96mFgvmWZ-qz35EPObyv8hKLTuyxbv3

    另外的例子:

    定位到截图的内容

    定位方法:

    findElements(By.xpath("//android.widget.ListView/android.view.View"))
    这样得到的是一个集合然后从集合中取你用定位的元素
    也可以直接定位到:
    findElements(By.xpath("//android.widget.ListView/android.view.View[1]"))
    其中后面的索引和截图中元素前面显示的索引一致
    (@index,0)
  • 相关阅读:
    矩阵快速幂 HDU3483
    欧拉函数 求小于某个数并与其互质的数的个数
    扩展欧几里德算法求逆元3
    拓展欧几里德算法求逆元2
    【20140113-2】MyEclipse生成javadoc时出错:编码GBK的不可映射字符
    【131202】SQL
    【20140113】package 与 import
    系统架构等级
    ora-01658 :无法为表空间USERS 中的段创建INITIAL区
    WMSYS.WM_CONCAT 函數的用法
  • 原文地址:https://www.cnblogs.com/fanxiaojuan/p/4881894.html
Copyright © 2011-2022 走看看