Appium Appium 弹框处理实现

木月 · 2021年05月21日 · 最后由 chend 回复于 2021年05月24日 · 3433 次阅读

🔔 Appium iOS 针对弹框处理

问题:

在元素定位时,抛出 UI 未加载完成前导致的定位失败,大部分的 UI 定位失败原因。除非代码有问题,绝大多数的失败,就是各种各样的弹框,导致的失败。

思路:

在元素定位时,设置预期最长等待的时间段,在此时间段内,循环定位元素,如果查找到匹配元素,则返回对象,中断循环,如果元素未定位,则尝试去定位设置好的预期的弹框/异常对象,如果匹配到元素,则处理掉,然后继续查找预期元素,直到定位成功或者超时报错。

实现

1)提前设置好可能存在弹框,我这里是用 yaml 文件记录的,区分了授权弹框 和 异常的弹框(因为我们的 App 的异常都是用弹框的形式来提示用户的)

permission:
  - Type: id # 定位异常元素的属性类型
    Value: 'cmbc close'  # 定位异常元素的属性值
    ClickType: id# 定位成功后,点击位置的元素的属性类型
    ClickValue: 'cmbc close' # 定位成功后,点击位置的元素的属性值

APP:
  - Type: id
    Value: '未知异常'
    ClickType: xpath
    ClickValue: '//XCUIElementTypeButton[@name="确定"]'

2)元素定位方法封装,这里只写了个 demo,未完善各种异常捕获,细节逻辑处理等


def find_element(driver, type, value):
    time_out = 10  # 最长时间10秒
    end_time = time.time() + time_out
    while end_time > time.time():
        element = driver.find_element(type, value)
        if isinstance(element, WebElement):
            LogSys.logInfo('assert is_enabled&is_displayed')
            if element.is_enabled() and element.is_displayed():
                return element
        for item in Config.permission:
            Target = driver.find_element(type=item['Type'], value=item['Value'])
            # 处理掉弹框
            if isinstance(Target, WebElement):
                LogSys.logInfo("命中弹框,处理掉弹框后,再执行一遍findUiObject方法")
                Alert.alertAccept()
                Config.permission.remove(item)
                LogSys.logWarning(Config.permission)

        for item in Config.app:
            Target = driver.find_element(type=item['Type'], value=item['Value'])
            # 处理掉弹框
            if isinstance(Target, WebElement):
                LogSys.logInfo("命中弹框,处理掉弹框")
                driver.find_element(type=item['ClickType'], value=item['ClickValue']).click()

    SetFail("预期时间内,未定位到元素",'pic_name')
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 6 条回复 时间 点赞

代码优化建议: 按照你文章中说的思路, 其实使用一个装饰器来捕获异常然后根据异常类型做对应的处理,根据异常消息判断是否需要重试. 其实会更友好

chend 回复

你逻辑有问题,如果是需要中断用例执行的弹框,你就不要设置异常点击列表里面,这里肯定是添加一些异常的,对用例本身没影响的弹框,像授权,像测试环境服务异常的一些弹框,和用例没关系的

3楼 已删除

driver.find_element(type=item['Type'], value=item['Value'])

find_element 是自定义的么? 为什么用关键词 type, 默认自带不是 by 么?

while 循环里也不加个 sleep(500) 啥的。心疼 CPU 宝宝 10 秒钟。

这只是分享逻辑的 demo,大家不要拿去直接用,我自己的逻辑都是摘出来的

木月 回复

逻辑没问题,我意思是实现这样的装饰器结构, 然后具体哪些弹窗是需要点击的, 哪些是错误弹出需要中断用例的, 你可以在装饰器中得到弹窗的信息去判断. 而不是说一箩筐的就直接点击不处理信息的.
甚至这个基础之上可以任意拓展, 比如你定义一套正常弹窗信息的字符串格式, 或者异常的一套格式,然后正则匹配. 再或者你可以自定义错误异常类型, 用来控制哪些流程遇到弹窗需要处理重试哪些不需要. 大同小异

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册