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

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

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

  • 相关阅读:
    day32-python阶段性复习六
    golang 项目中坑
    golang crawler
    router
    golang in ubuntu
    go channel 案例分析
    go channel learning
    bee go + mgo
    URL escape and unescape
    [转]good sample of Go
  • 原文地址:https://www.cnblogs.com/songzhenhua/p/16156508.html
Copyright © 2020-2023  润新知