Appium Appium 弹框处理实现

木月 · May 21, 2021 · Last by chend replied at May 24, 2021 · 2623 hits

🔔 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 条回复 时间 点赞

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

木月 #2 · May 21, 2021 Author
chend 回复

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

3Floor has deleted

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

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

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

木月 #6 · May 24, 2021 Author

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

木月 回复

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

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up