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个元素组成

图片Placeholder,是一个Text类型的元素,是整个输入框的一个提示文本展示

图片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'属性的值

 

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

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

posted @ 2022-04-17 17:44  ☆星空物语☆  阅读(885)  评论(0编辑  收藏  举报