• Poco API精讲之点击click()、long_click()、double_click()


    上期回顾:Poco API精讲之 等待 wait


    以下基于
    python3.8;airtestIDE1.2.13;airtest1.2.4;pocoui1.0.85

    注意:Poco框架和Airtest框架很多API是同名的,但使用方法完全不一样!!!一定不要搞混了,我初学时也经常搞混,这点一定要注意!
    具体Poco框架和Airtest框架是什么关系,可以看之前文章:Airtest Project——UI自动化利器介绍

    今天讲一下Poco最基本的操作click()、long_click(),大家不要和Airtest框架的click()也叫touch()弄混了。
    Airtest框架的touch()是基于绝对坐标或图片的;Poco的click是基于元素的。
    Airtest的touch()详情可以看之前的文章:Airtest API精讲之touch()

    Poco的click分两种,一种是基于全局操作的click、一种是基于UI对象的click,不明白的可以看之前的文章
    Poco实例(全局操作) API汇总
    Poco UI对象 API汇总

    click

    1.1 Poco基于全局操作的click

    click(pos)
    按屏幕相对坐标点击
    上面说Airtest框架的click是基于绝对坐标,这里又说了相对坐标,不懂的可以看之前的文章:Airtest和Poco坐标详解,这里不再解释

    参数:
    pos - 相对坐标,如[0.5,0.5]

    异常:
    InvalidOperationException: 坐标在屏幕以外时报错

    源码解析:

    # 源码位置:your_python_path\site-packages\poco\pocofw.py
        def click(self, pos):
            if not (0 <= pos[0] <= 1) or not (0 <= pos[1] <= 1):
                raise InvalidOperationException('Click position out of screen. pos={}'.format(repr(pos)))
            ret = self.agent.input.click(pos[0], pos[1])
            self.wait_stable()
            return ret

    首先我们知道Poco的click是基于屏幕相对坐标,相对坐标是把屏幕长宽抽象为0-1的长度,所以源码中首先判断一下X,Y坐标是不是小于0或大于1,是的话就表明坐标在屏幕以外,是无法点击到的,所以需要拋出一个超屏的错误。如果在屏幕内,则通过代理执行点击。这里用到代理的原因是不同Poco类型的操作底层实现是不一样的,Poco设计上使用了代理类,这样你无需关心每一种的底层实现,直接通过调用代理即可。

    另外根据源码我们还学会一招,就是判断元素是否在屏幕内,比如你的脚本要适配各种型号的手机,在大的手机上你要点的元素直接就显示在屏幕上,在小的手机上你要点的元素需要滑动才能显示在屏幕上,就可以通过这种办法来判断。

    示例:

    from airtest.core.api import *
    from poco.drivers.unity3d import UnityPoco

    auto_setup(__file__)

    poco = UnityPoco()

    # 基于全局操作的click,点击屏幕左上角
    poco.click([0.1,0.1])


    # 判断元素是否在屏幕内,是的话直接点击,否则滑动后再点击
    button = poco("测试工程师小站")
    p = button.get_position()
    if 0 < p[0] < 1 and 0 < p[1] < 1:
        poco.click(p)  # 也可以写成button.click()
    else:
        swipe()  # 具体swipe参数需要根据实际情况定
        poco.click(p)  # 也可以写成button.click()

    1.2 Poco基于UI对象的click

    click(focus=None, sleep_interval=None)
    单击元素,如果UI对象是一组元素则点击第1个

    参数:
    focus - 元素相对坐标,如[0.1,0.1],指元素长、宽各10%的位置,即元素左上角,取值范围0~1
    sleep_interval - 休息间隔

    异常:
    PocoNoSuchNodeException:元素不存在

    源码解析:

    # 源码位置:your_python_path\site-packages\poco\proxy.py
        @wait
        def click(self, focus=None, sleep_interval=None):
            focus = focus or self._focus or 'anchor'
            pos_in_percentage = self.get_position(focus)
            self.poco.pre_action('click', self, pos_in_percentage)
            ret = self.poco.click(pos_in_percentage)
            if sleep_interval:
                time.sleep(sleep_interval)
            else:
                self.poco.wait_stable()
            self.poco.post_action('click', self, pos_in_percentage)
            return ret

    第1行,获取元素的锚点,默认为中心点,不知道锚点的去看坐标系介绍。
    第2行,根据锚点,算出要点击的相对坐标
    第4行,根据相对坐标执行点击,可以看到,基于UI对象的click最终也是调用的基于全局操作的click

    另外说下此处click()头上的@wait装饰器,就是加了一个wait_for_appearance()的等待:

    # 源码位置:your_python_path\site-packages\poco\proxy.py
    def wait(func):
        @wraps(func)
        def wrapped(proxy, *args, **kwargs):
            try:
                return func(proxy, *args, **kwargs)
            except PocoNoSuchNodeException as e:
                try:
                    proxy.wait_for_appearance(timeout=proxy.poco._pre_action_wait_for_appearance)
                    return func(proxy, *args, **kwargs)
                except PocoTargetTimeout:
                    raise e
        return wrapped

    wait装饰器逻辑:首先尝试直接执行原方法,如果报PocoNoSuchNodeException的错,则通过wait_for_appearance()等待
    对装饰器不熟的可以看:Python三大器之装饰器

    示例:
    点击默认点在 anchorPoint 上,每个UI都会有一个 anchorPoint ,也就是检视器(Inspector)中UI包围盒的那个红点,大部分情况下 anchorPoint 都在UI包围盒的正中央。如果想指定其他的点击位置,可以传一个参数到 click 方法中,这个参数是一个用list或tuple表示的2维向量,其 [x, y] 值分别表示相对于包围盒左上角的偏移量,左上角为 [0, 0] ,右下角为 [1, 1] ,具体用法请见:Airtest和Poco坐标详解

    poco("测试工程师小站").click()  # 点击元素中心
    poco("测试工程师小站").click([0.1,0.1])  # 点击元素左上角
    poco("测试工程师小站").click([0.9,0.9], sleep_interval=3)  # 点击元素右下角,之后休息3秒

    long_click

    long_click就是比click多了一个时间参数,其他都一样

    2.1 Poco基于全局操作的long_click

    long_click(pos, duration=2.0)
    长按

    参数:
    pos - 相对坐标,如[0.5,0.5]
    duration - 长按时长,默认2秒

    异常:
    InvalidOperationException: 坐标在屏幕以外时报错

    源码解析:

    # 源码位置:your_python_path\site-packages\poco\pocofw.py
        def long_click(self, pos, duration=2.0):
            try:
                duration = float(duration)
            except ValueError:
                raise ValueError('Argument `duration` should be <float>. Got {}'.format(repr(duration)))

            if not (0 <= pos[0] <= 1) or not (0 <= pos[1] <= 1):
                raise InvalidOperationException('Click position out of screen. {}'.format(repr(pos)))
            return self.agent.input.longClick(pos[0], pos[1], duration)

    和click基本一样,就是多了一步检测duration参数合法性

    示例:

    from airtest.core.api import *
    from poco.drivers.unity3d import UnityPoco

    auto_setup(__file__)

    poco = UnityPoco()

    # 长按屏幕左上角10秒
    poco.long_click([0.1,0.1], 10)

    2.2 Poco基于UI对象的long_click

    long_click(duration=2.0)
    长按

    参数:
    duration - 持续时间,默认2秒

    源码解析:

    # 源码位置:your_python_path\site-packages\poco\proxy.py
        @wait
        def long_click(self, duration=2.0):
            try:
                duration = float(duration)
            except ValueError:
                raise ValueError('Argument `duration` should be <float>. Got {}'.format(repr(duration)))

            pos_in_percentage = self.get_position(self._focus or 'anchor')
            self.poco.pre_action('long_click', self, pos_in_percentage)
            ret = self.poco.long_click(pos_in_percentage, duration)
            self.poco.post_action('long_click', self, pos_in_percentage)
            return ret

    和click基本一样,就是多了一步检测duration参数合法性

    示例:

    poco("测试工程师小站").long_click(10)  # 长按元素中心10秒

    double_click()

    不知是忘了还是啥原因,实际官方在Unity Poco中并未实现double_click,所以直接运行会报错。但我们可以自己封装一个

    from airtest.core.api import *
    from poco.drivers.unity3d import UnityPoco

    auto_setup(__file__)

    poco = UnityPoco()

    qasite_double_click(poco_ins):
        # 等待元素出现
        poco_ins.wait_for_appearance()
        # 获取元素屏幕相对坐标
        p = poco_ins.get_position()
        # 转换为屏幕绝对坐标
        pos = poco.agent.input.get_target_pos(p[0], p[1])
        # 调用Airtest框架的双击
        double_click(pos)


    button = poco("测试工程师小站")
    qasite_double_click(button)

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

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

  • 相关阅读:
    sql server分布式事务解决方案 (笔记)
    深入理解Datatable(笔记)
    SQLSERVER 2005 实现文件读写操作
    局部变量、全局变量、堆、堆栈、静态和全局
    分布式事务DISTRIBUTED TRANSACTION
    SQLSEVER2005中找不到存储过程xp_getfiledetails 解决办法
    模式窗口
    理解析构函数的执行过程
    Oracle分页
    DataTable导出到Excel、GSV (转)
  • 原文地址:https://www.cnblogs.com/songzhenhua/p/16213603.html
Copyright © 2020-2023  润新知