Poco API精讲之元素属性操作attr、setattr……
上期回顾:Poco API精讲之focus()
以下基于
python3.8;airtestIDE1.2.13;airtest1.2.4;pocoui1.0.85
注意:Poco框架和Airtest框架很多API是同名的,但使用方法完全不一样!!!
具体Poco框架和Airtest框架是什么关系,可以看之前文章:Airtest Project——UI自动化利器介绍
之前讲了Poco框架的元素定位,今天我们讲下元素定位成功后,都可以对元素进行哪些操作。
我们以官方Unity小游戏Demo为例,如“pearl”这个文本元素,我们通过AirtestIDE选中后,在Log查看窗就可以看到其详细属性信息了。
我们挑常用的看下:
type : Text # 类型为Text
name : name # 名称是name
text : pearl # 文本是pearl
visible : True # 元素可见
pos : [0.2421603, 0.6666666] # 元素中心的屏幕相对坐标,如果0.2421603*屏幕长度=绝对坐标点
size : [0.1234445, 0.055555556] # 元素在屏幕相对坐标的长宽,如果0.1234445*屏幕长度=元素绝对长度
anchorPoint : [0.5, 0.5] # 锚点位置-中心
clickable : False # 元素不可点击
1.attr(name)
获取元素属性值
参数:
name - 属性名称,如name、type、text、visible、pos、clickable等
返回:
属性值,如果属性不存在返回None
异常:
PocoNoSuchNodeException:元素不存在
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def attr(self, name):
# to optimize performance speed, retrieve only the first matched element.
# 优化速度,只选择第一个匹配到的节点
nodes = self._do_query(multiple=False)
val = self.poco.agent.hierarchy.getAttr(nodes, name)
if six.PY2 and isinstance(val, six.text_type):
# 文本类型的属性值,只在python2里encode成utf-8的str,python3保持str类型
# 这是为了在写代码的时候,无论py2/3始终可以像下面这样写
# node.attr('text') == '节点属性值'
val = val.encode('utf-8')
return val
第1行:获取元素信息(即上面例子中的所有属性值)
第2行:在元素信息中取得指定属性的值
之后是为了兼容Python2,现在我们都用Python3,可以忽略。
示例:
poco(text='pearl').attr("name") # 值为name
poco(text='pearl').attr("text") # 值为pearl
2.setattr(name, val)
设置元素的属性的值。
参数:
name - 属性名称,如name、type、text、visible、pos、clickable等
val - 值
异常:
InvalidOperationException:非法操作。当设置失败时抛出。
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def setattr(self, name, val):
nodes = self._do_query(multiple=False)
try:
return self.poco.agent.hierarchy.setAttr(nodes, name, val)
except UnableToSetAttributeException as e:
raise InvalidOperationException('"{}" of "{}"'.format(str(e), self))
和attr()一样,先获取元素信息,之后去设置元素属性的值。
需要注意的是并不是所有属性都可以修改。比如上例中的pearl元素的text属性就是一个不可修改的属性。但如果是Input类元素的text属性,则是可修改的。
比如这个输入框,其实一共由3个元素组成
Text,也是一个Text类型的元素,是整个输入框的已输入内容的文本展示
pos_input,才是InputField类型的元素,此类型元素才可设置Text属性
示例:
# 给输入框设置值为"测试工程师小站"
# 该元素Text属性无法修改,操作不生效
poco(text="").setattr("text", "测试工程师小站")
# 该元素Text属性无法修改,操作不生效
poco("Placeholder").setattr("text", "测试工程师小站")
# 该元素可操作,可操作后,实际是poco(text="")的text值被修改为了'测试工程师小站'
# 所以再用poco(text="")的话就无法定位到了,应该用poco(text="测试工程师小站")
poco("pos_input").setattr('text','测试工程师小站')
如果你觉得很迷惑,实际跑一下,看看结果。
3.get_text()
获取元素'text'属性值
返回:
'text'属性值,没有时返回None
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def get_text(self):
text = self.attr('text')
return text
可以看到源码很简单,就是通过attr()获取'text'属性的值
示例:
poco("Placeholder").get_text() # 返回"Enter text..."
4.set_text(text)
设置元素'text'属性值
参数:
text - 文本内容
异常:
InvalidOperationException:非法操作。当无法设置时抛出。
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def set_text(self, text):
return self.setattr('text', text)
很简单,就是通过setattr()设置'text'属性的值
示例:
# 所以上面设置输入框内容的操作也可以这样写
poco("pos_input").set_text("测试工程师小站")
5.get_name()
获取元素'name'属性值
返回:
'name'属性值
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def get_name(self):
return self.attr('name')
很简单,就是通过attr()获取'name'属性的值
示例:
# 以例1演示
poco(text='pearl').get_name() # 返回"name"
6.get_size()
获取元素在屏幕相对坐标中的大小
返回:
[width, height] in range of 0 ~ 1
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def get_size(self):
return self.attr('size')
很简单,就是通过attr()获取'size'属性的值
示例:
# 以例1演示
poco(text='pearl').get_size() # 返回[0.1234445, 0.055555556]
7.get_position(focus=None)
获取元素在屏幕上的相对坐标
参数:
focus - 元素相对坐标,如[0.1,0.1],指元素长、宽各10%的位置,即左上角,取值范围0~1
返回:
相对坐标,如[0.498,0.35555]
异常:
PocoNoSuchNodeException:元素不存在
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def get_position(self, focus=None):
focus = focus or self._focus or 'anchor'
if focus == 'anchor':
pos = list(map(float, self.attr('pos')))
elif focus == 'center':
x, y = map(float, self.attr('pos'))
w, h = self.get_size()
ap_x, ap_y = map(float, self.attr("anchorPoint"))
fx, fy = 0.5, 0.5
pos = [x + w * (fx - ap_x), y + h * (fy - ap_y)]
elif type(focus) in (list, tuple):
x, y = map(float, self.attr('pos'))
w, h = self.get_size()
ap_x, ap_y = map(float, self.attr("anchorPoint"))
fx, fy = focus
pos = [x + w * (fx - ap_x), y + h * (fy - ap_y)]
else:
raise TypeError('Unsupported focus type {}. '
'Only "anchor/center" or 2-list/2-tuple available.'.format(type(focus)))
return pos
通过focus值的不同情况,返回屏幕相对坐标。但不管是哪种情况,都是通过attr()获取'pos'属性的值,然后再去计算出需要的值。
示例:
# 以例1演示
# 直接返回默认的pos值
poco(text='pearl').get_position() # 返回[0.2421603, 0.6666666]
# 返回元素中心点在屏幕的相对坐标
poco(text='pearl').get_position('center') # 返回[0.2421603, 0.6666666]
# 返回元素相对坐标[0.1,0.1](即元素左上角)在屏幕的相对坐标
poco(text='pearl').get_position([0.1,0.1]) # 返回[0.1927825, 0.6444443776]
如果你不太清楚坐标系的具体概念,可以看:Airtest和Poco坐标详解
8.get_bounds()
获取元素在屏幕相对坐标系中的边界
返回:
[top, right, bottom, left] in range of 0 ~ 1
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def get_bounds(self):
size = self.get_size()
top_left = self.get_position([0, 0])
# t, r, b, l
bounds = [top_left[1], top_left[0] + size[0], top_left[1] + size[1], top_left[0]]
return bounds
第1行:get_size()的源码是self.attr('size')
,最上面我们讲属性的时候知道size属性记录了元素在屏幕相对坐标的长宽
第2行:返回元素即左上角(左上顶点)在屏幕的相对坐标
第3行:左上顶点有了,长宽有了,就能计算出四条边在屏幕相对坐标的边界值了
示例:
# 以例1演示
# 注意返回的顺序是[top, right, bottom, left]
poco(text='pearl').get_bounds() # 返回[0.638888822, 0.30388255, 0.6944443779999999, 0.18043805]
9.exists()
判断元素是否存在。
返回:
True if exists otherwise False
源码解析:
# 源码位置:your_python_path\site-packages\poco\proxy.py
def exists(self):
try:
return self.attr('visible')
except (PocoTargetRemovedException, PocoNoSuchNodeException):
return False
很简单,就是通过attr()获取'visible'属性的值
---------------------------------------------------------------------------------
关注微信公众号即可在手机上查阅,并可接收更多测试分享~