poco定位元素

1、基本操作

获取控件保存变量

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')


print(poco("CollectionView").child(type="Cell")[0].offspring(name="云南风景",type="StaticText").exists())

print(poco("CollectionView").child(type="Cell")[0].chiild(name="云南风景",type="StaticText").exists()) 

当根据child().child()定位时,如果第二个child是前面一个的孙节点,不能定位到,要用offspring,child节点必须是上个节点的儿子节点,不能跨辈分

根据下标获得某个节点数组中的某个节点

item = items[i]

sibling:获取当前节点的兄弟节点 

在王大二的兄弟中找王大三---->poco('王大二').sibling()

parent():获取当前节点的父节点

找王大三的爸爸---->poco('王大三').parent()

poco(text="朋友圈").parent().parent().parent()
如果只知道王大三名字的前两个字,怎么找王大三? (text用正则匹配)

A.poco(textMatches='^王大.')   #这样就找到所有名字前2个字是王大的,然后再逐步分析那个是王大三,如果目标节点是只有1个王大三,则结果就是王大三了

按照序号(顺序)进行选择总是按照空间排布顺序,先从左往右,再像之前那样一行一行从上到下。如下图所示,我们利用选择器选中了很多个 type="Text" 的元素,然后再利用索引顺序逐个选中单个元素:

name0 = poco("Content").child(type="Text")[0].get_name()
name1 = poco("Content").child(type="Text")[1].get_name()
name2 = poco("Content").child(type="Text")[2].get_name()

print(name0+" "+name1+" "+name2)

POCO定位元素后再通过局部坐标系定位

使用局部坐标系的click接口

首先我们需要知道点击默认是点在 anchorPoint 上的,每个UI都会有一个 anchorPoint ,也就是检视器(Inspector)中UI包围盒的那个红点,大部分情况下 anchorPoint 都在UI包围盒的正中央。

所以当我们使用poco默认的click接口时,点击的是UI包围盒中间的红点,举个例子:

poco("com.miui.home:id/workspace").offspring("天气").offspring("com.miui.home:id/icon_icon").click()

执行后报告显示的点击位置如下图:

我们引入局部坐标系来表示相对于某UI的坐标。局部坐标系以UI包围盒左上角为原点,向右为x轴,向下为y轴,包围盒宽和高均为单位一。局部坐标系可以更灵活地定位UI内或外的位置,例如(0.5, 0.5)就代表UI的正中央,也就相当于我们上文中默认的anchorPoint;超过1或小于0的坐标值则表示UI的外面。

所以如果我们想点击 anchorPoint 以外的其他指定位置时,可以传一个参数到 click 方法中,这个参数是一个用list或tuple表示的2维向量,其 [x, y] 值分别表示相对于包围盒左上角的偏移量,左上角为 [0, 0] ,右下角为 [1, 1] 。例如:

poco("com.miui.home:id/workspace").offspring("天气").offspring("com.miui.home:id/icon_icon").click([0,0])

执行后报告显示的点击位置如下图:

可以看出点击的是我们UI包围框左上角的原点(0,0)。
另外,我们想改变以anchorPoint为起点,也可以使用focus方法:

poco("com.miui.home:id/workspace").offspring("天气").offspring("com.miui.home:id/icon_icon").focus([0,0]).click()

使用归一化坐标系的swipe接口

归一化坐标系就是将屏幕宽和高按照单位一来算,这样UI在poco中的宽和高其实就是相对于屏幕的百分比大小了,好处就是不同分辨率设备之间,同一个UI的归一化坐标系下的位置和尺寸是一样的,有助于编写跨设备测试用例。
归一化坐标系的空间是均匀的,屏幕正中央一定是(0.5, 0.5),其他标量和向量的计算方法同欧式空间。

swipe操作同样是以 anchorPoint 为起点,如果你想改变起点也是使用上述的 focus 方法,然后朝给定向量所代表的方向滑动,距离也就是向量的长度。

下面展示使用 swipe 方法的一个例子:

joystick = poco('movetouch_panel').child('point_img')
joystick.swipe('up')
joystick.swipe([0.2, -0.2])  # swipe sqrt(0.08) unit distance at 45 degree angle up-and-right
joystick.swipe([0.2, -0.2], duration=0.5)

 

 

 

【特别注意】:对于offspring()和sibling()查询子孙节点,兄弟节点的方式,获取多个子孙节点、兄弟节点的顺序,笔者尝试后发现是没有规律的,所以只能先遍历下,找到对应节点的索引,然后再去通过这个索引值去指定对应节点。

    1.知道了怎么找到元素了,那找到元素后有怎么获取元素的属性值呢?

        poco(’节点名‘).attr('属性名')

    2.怎么获取元素中text的值?

        poco(’节点名‘).get_text() #当然这样用必须保证这个节点是有text属性的,否则会获取为空。

    3.child和children都是提取子节点,区别是什么?

    这个大家可以翻下源码,child是有参数name的,而children是没有参数的,这就可以区分对child是可以根据name来筛选某个子节点,对children无法筛选,结果有几个子节点就查出几个子节点。child和children都是可以提取多个子节点的,如果不去遍历的话,默认提取第一个子节点。

 

获取属性

x.get_position() #获取定位元素的坐标
x.get_text()

# 获取属性

name1 = poco("star_single").get_name()
name2 = poco("star_single").attr('name')
text = poco("star_single").get_text()

print ("name1:",name1)
print ("name2:",name2)
print("text:",text)

设置属性

# 设置属性

poco("pos_input").set_text("123")

poco("pos_input").setattr('text',"456")

判断控件是否存在,并进行操作

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)

2、等待和停留

时间停留x秒,一般在一个交互完后都会写上大概1s左右的停留

time.sleep(x)

等待某个事件结束

直到某个节点出现

poco('nodeName').wait_for_appearance(timeout=3)  # wait until appearance within 3s

直到某个节点消失

node.wait_for_disappearance()

直到某些节点出现在屏幕上

wait_for_all() 是在超时时长结束之前,需要 等待所有给定的UI对象都显示出来 ,即一次轮询所有UI,例如等待三个图标都显示之后,再点击返回按钮:
poco("wait_ui2").click()
yellow = poco("yellow")
blue = poco("blue")
black = poco("black")

poco.wait_for_all([yellow,blue,black])
poco("btn_back").click()

wait_for_any() 则是在超时时长结束之前,等待任意一个UI显示出来,即一次轮询任何一个给定的UI,例如:
bomb = poco("bomb")
yellow = poco("yellow")
blue = poco("blue")

while True:
    fish = poco.wait_for_any([bomb,yellow,blue])
    print(fish.get_name())

3、输出

print(xx)

例如输出一个节点是否存在

print(obj.exists())

4、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])

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)  

6、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)

7、异常处理,poco中有4中异常处理方式

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

某个定时器结束时触发,但如果操作太快,节点还没显示在界面上,很可能是触发的PocoNoSuchNodeException

node= poco('node')
try:
    star.wait_for_appearance(timeout=3)  # wait until appearance within 3s
except PocoTargetTimeout:
    print('oops!')

PocoTargetRemovedException

某个节点已经被删除时会触发

 

参考:https://mp.weixin.qq.com/s/PonBynNPfLqaWzp2oc689Q

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值