背景:
我是在根据论坛上的一些帖子做基于 uiautomatorviewer 二次开发,开发录制功能实现可以录制一些简单脚本,但是现在遇到一个问题
如图:
我要如何获取这个 “下载” 按钮的 XPath 绝对路径呢?
我的思路:
我只要获取到 listview 那层开始就可以,不必获得从根节点开始的路径,我现在卡住的是,我要如何知道所选节点的父节点的父节点...这样一层层上去直到那个 Listview 那个节点。
用 while 循环可以吗?,还是有更好的思路去获取这个控件的唯一定位?
了解的人可以点拨一下吗?
解析整个 xml ,每个节点变成 node 对象,然后递归从你这个元素节点开始找 node 的 parent 吧?
不过搞个绝对路径有什么意义?
#1 楼 @chenhengjie123 我是想获取这个 “下载” 按钮的唯一定位方式,这几个 “下载” 按钮的属性都一样,没办法区分,我想到这个发子,不知道可行不?您有没有好的法子
直接获取下载元素的元素集,然后通过 index 决定使用哪个下载不行么?
#4 楼 @iriszhang 这几个下载元素的 index 都是 0,没办法根据这个区别的。
人写代码时,一般写成这样
//android.widget.TextView[text()='疯狂俄罗斯人']/parent::*/parent::*/following-sibling::*[1]/android.widget.Button[text()='下载']
如果想从包含 “下载” 的按钮推断出上面这个 Xpath,还需要一些信息来判断 parent 有几个、following-sibling 有几个,比如固定的结构(父节点的父节点的第一个弟节点),或者一个锚点(id 是 “appname” 的祖先节点),但这些都可能改变。用过的录制回放工具没有处理这种情况的,需要人再去改,改的时候 FirePath 这种工具就足够方便了。
另一种录制回放的思路是:如果录制时点第三个按钮成功,那回放时点第三个按钮也应该是成功的
#7 楼 @sanlengjingvv 但是我们老大给我的要求是,当点击 “下载” 按钮,就直接可以生成这样的路径
//android.widget.TextView[text()='疯狂俄罗斯人']/parent::*/parent::*/following-sibling::*[1]/android.widget.Button[text()='下载']
然后在封装一下直接生成可运行的脚本,尽量人不用在去改脚本。不过我才接触测试不到一个月,搞这个有点吃力
通过比较 xy 坐标来判断下载按钮属于哪个游戏的,然后拼出来路径。可行么。
场景 1:
- 上架新游 “疯狂俄罗斯人”
- 进入全部新游
- 下载 “疯狂俄罗斯人”
场景 2: 下载任意 app
场景 3:- 搜索 “疯狂俄罗斯人”
- 下载 “疯狂俄罗斯人”
场景 1,上架一般是 Web 后台操作的,先不说
场景 2,//android.widget.Button[text()='下载’][1]
这种 Xpath 就足够了
场景 3,给 ListViewItem 加个 ID,给游戏名称加个 ID ,从被点击的 “下载” 向上找到 ListViewItem 的 ID 停止,再向下遍历找到游戏名称的 ID ,就可以拼出这种 Xpath 了
//android.widget.TextView[text()='疯狂俄罗斯人']/parent::*/parent::*/following-sibling::*[1]/android.widget.Button[text()='下载']
其实,就先按 “父节点的父节点的第一个弟节点 “这种固定规则生成,App 界面树结构变了改录制代码后重新录制。先实际用起来,说不定层级就很少变呢?说不定用的人觉得这种非常智能的自动生成不重要呢?说不定老大改想法了呢?说不定使用场景明确以后就有更好的实现方法了呢?
#11 楼 @sanlengjingvv 我看到一个帖子是遍历把属性都相同的控件放到一个 list 里面,然后去判断点的是第几个,uiautomatorviewer 功能扩展实践
这样感觉比给出绝对路径的要简单,反正不管了,先试试这个思路,昨天搞了一天那个绝对路径没出来。