Poco
前置
- 命令行运行脚本
在命令行执行脚本的命令是airtest run + 脚本文件 路径,该命令的可传参数如下:
--device,用来指定连接的被测设备
--log,用来指定log内容和截图存放的目录
--recording,运行脚本时进行录屏操作
--no-image,传入该参数后,在任务运行过程中不再保存截图
在 Poco 中,child 和 offspring 是两个不同的方法,用于查找元素的子元素,它们之间有一些区别:
child() 方法:
child() 方法用于查找直接子元素,即当前元素的直接后代。 它只会查找当前元素的一级子元素,不会查找子元素的子元素。
通常用于查找直接子元素,而不包括孙子元素及以下级别的元素。
offspring() 方法
offspring() 方法用于查找所有后代元素,包括直接子元素、孙子元素、曾孙元素,以及整个后代元素树。 它会递归查找当前元素的所有后代元素,直到找到所有符合条件的元素为止。
通常用于查找整个后代元素树中的元素。
a=poco("android:id/content").child("com.miui.cleanmaster:id/root").offspring("com.miui.cleanmaster:id/items").child("android.widget.LinearLayout")
for v in a:
print(v.offspring("com.miui.cleanmaster:id/name").get_text())
初始化
#初始化
poco = AndroidUiautomationPoco()
#启动应用程序
package_name = "com.example.myapp"
poco.device().app_start(package_name)
节点获取
- poco()图标定位不准的、调试时用模拟器通过节点的属性定位 到真机调试报错的情况: 用poco()正则表达式:textMatches 、 nameMatches 和 typeMatches 见名知意 ,例如 poco(typeMatches="")[0].click poco(nameMatches="^\s \s$").click()
- 通过poco()定位元素:poco(text="**).click
- 获取节点的属性:poco(text="**").attr("name")
- 设置节点的属性:poco(text="**").setattr("name","1")
- 获取节点的文本:poco(text="*").get_text() 赋值文本框,poco("搜索").set_text("")
- 通过多个属性获取节点 poco(text="", name="")
基本操作
获取控件保存变量
x = poco('NodeName')
x = poco('NodeName',type = '类型名比如Button')
获得A节点下的子节点B
item = poco('ANodeName').child('BNodeName')
获取A节点下类型为Image的子节点
item= poco('ANodeName').child(type='Image')
获得A节点下的子节点B的所有名为C的后代们,是一个节点数组
items = poco('ANodeName').child('BNodeName').offspring('CNodeName')
根据下标获得某个节点数组中的某个节点
item = items[i]
获取属性
x.get_position()
x.get_text()
设置属性
x.set_text('文本')
判断控件是否存在,并进行操作
if x.exists():
do something
判断某个节点是什么
if nodeA is nodeB:
do something
else:
do something
点击和长按
poco('NodeName').click()
poco('NodeName').long_click()
poco('NodeName').long_click(duration=5)
等待和停留
时间停留x秒,一般在一个交互完后都会写上大概1s左右的停留
time.sleep(x)
等待某个事件结束 直到某个节点出现
poco('nodeName').wait_for_appearance(timeout=3) # wait until appearance within 3s
直到某个节点消失
node.wait_for_disappearance()
直到某些节点出现在屏幕上
resultNode= poco.wait_for_any([noedA,noedB,noedC,...])
输出
print(xx)
例如输出一个节点是否存在
print(obj.exists())
poco的坐标系
左上角(0,0),右下角(1,1),横坐标为x,纵坐标为y
点击节点的某个位置
node.focus('center').click() // 点击节点的中心点位置
node.focus([0.1, 0.1]).long_click() // 点击节点的靠近左上角位置
node.focus([1, 1]).long_click() // 点击节点的右下角位置
node_right_edge = node.focus([1, 0.5])
拖拽和滑动
拖拽
从一个节点位置拖拽到另一个节点位置
poco('ANodeName').drag_to(poco('BNodeName'))
从列表的一端滑动到另一端
listView = poco('Scroll View')
listView.focus([0.5, 0.8]).drag_to(listView.focus([0.5, 0.2]))
滑动
滑动列表
poco('Scroll View').swipe([0, -0.1])
poco('Scroll View').swipe('up')
从A点滑动到B点
x, y = poco('Scroll View').get_position()
end = [x, y - 0.1]
poco.swipe([x, y], end)
从A点向指定方向和定长移动
x, y = poco('Scroll View').get_position()
dir = [0, -0.1]
poco.swipe([x, y], direction=dir)
for循环和if
for node in poco('nodeName')
do something
for name in poco('nodeName').offspring('childsSameName').child('name'):
print(name.get_text())
判断是否在组合中
if item not in itemsSet
itemsSet.add(item)
异常处理
InvalidOperationException
无效操作,主要原因是选中和操作的UI在屏幕外
try:
poco.click([1.1, 1.1]) # click outside screen
except InvalidOperationException:
print('【error】tips')
PocoNoSuchNodeException 对找不到的节点执行了操作或者获取属性,应该通过调用.exists()来避免这个异常报错的出现
try:
node.click()
except PocoNoSuchNodeException:
print('oops!')
try:
node.attr('text')
except PocoNoSuchNodeException:
print('oops!')
两个例外:
node = poco('not existed node') # 只是获取一个节点不会触发异常
print(node.exists()) # => False. 该方法不会报出异常
某个定时器结束时触发,但如果操作太快,节点还没显示在界面上,很可能是触发的PocoTargetTimeout
node= poco('node')
try:
star.wait_for_appearance(timeout=3) # wait until appearance within 3s
except PocoTargetTimeout:
print('oops!')