Poco API精讲之refresh()

上期回顾:Airtest解决“自动装包”过程中需要输入密码的问题(同适用于随机弹框处理)


以下基于
python3.8;airtestIDE1.2.14;airtest1.2.6;pocoui1.0.87

Poco最新版1.0.87新增了一个新的元素刷新API:refresh()

新接口的由来

如果你的项目之前使用了Poco,那你一定会使用PO模式,这样就可能会遇到元素不刷新的问题。
比如你在元素的ele.py中定义了元素,类似

info_button = poco("info_button")

在用例case.py中引入了元素定义并使用

from ele import info_button

info_button.click()

# 经过一系列操作,info_button可能已经发生位移,此时再去点击,点的会是之前的位置
# 因为poco元素定义赋给变量后,信息只会保留第1次使用时抓取的,之后不会更新
info_button.click()  # 会点不到

所以之前的解决方案很low,就是在case中再定义一次元素

info_button.click()

# 经过一系列操作,info_button可能已经发生位移

info_button1 = poco("info_button")  # 相同的元素重新赋值一次
info_button1.click()  # 这样就OK了

另外官方也列举了两个例子

例1
# 打开APP,有一个按钮‘每日推荐’
ele = poco("每日推荐")
print(ele.exist())  # 输出True

# 按手机HOME键

print(ele.exist())  # 此时仍输出True

即使元素不存在了,这种情况下Poco也仍然认为元素存在,原因同上面的例子,元素信息会保留第1次抓取的,后面不会自动更新

图片官方例子动图
例2

同样的,有时用Poco的wait_for_disappearance(),会遇到实际上节点已经消失了,但是接口没有判断到消失的问题。

解决方法

对于第1、2个例子,可以显示的用新增API refresh()去手动刷新。
以第2个例子为例:

# 打开APP,有一个按钮‘每日推荐’
ele = poco("每日推荐")
print(ele.exist())  # 输出True

# 按手机HOME键

ele.refresh()  # 给元素刷新信息
print(ele.exist())  # 输出False

 

图片官方例子动图

对于第3个例子wait_for_disappearance(),官方已经在源码中修复,所以以后还是直接使用wait_for_disappearance()即可。

注意

refresh()是针对Poco UI对象(UIObjectProxy实例)的API,而不是Poco实例的。

from poco.drivers.android.uiautomation import AndroidUiautomationPoco

poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

# 正确用法
poco(text="日历").refresh()

# 错误用法
poco.refresh()  # 会报错!!!

两者的区别可以看之前文章:
Poco UI对象 API汇总
Poco实例(全局操作) API汇总

源码解析

先看下其源码:

源码地址:your_python_path/site-packages/poco/proxy.py
    def invalidate(self):
        self._evaluated = False
        self._nodes = None

    # refresh is alias of invalidate
    # use poco(xxx).refresh() to force the UI element(s) to re-query
    refresh = invalidate

其实之前版本就已经存在invalidate()方法了,这次只是新增了一个别名refresh而已。
invalidate()方法其实很简单,只是将两个变量重置而已,这两个变量的含义在class UIObjectProxy(object)__init__()方法中有说明:

源码地址:your_python_path/site-packages/poco/proxy.py

# true or false whether the corresponding UI elements of this UI proxy (self) have been selected
# 此UI proxy是否已经查找到对应的UI elements了
self._evaluated = False

# the proxy object of UI elements, migh be `node` or `[nodes]`, the proxy type is specified by
# `self._nodes_proxy_is_list`
# 可能是远程node代理,也可能是远程[node]代理, 由`self._nodes_proxy_is_list`指定是何种proxy类型
self._nodes = None
self._nodes_proxy_is_list = True

 

---------------------------------------------------------------------------------

关注微信公众号即可在手机上查阅,并可接收更多测试分享~

posted @ 2022-08-12 22:36  ☆星空物语☆  阅读(465)  评论(0编辑  收藏  举报