Appium WebDriverAgent xcode16 打包的 app 自动化真多坑(问题篇)

wupengfeng · 2024年11月12日 · 最后由 wupengfeng 回复于 2024年11月19日 · 3500 次阅读

背景

基于 airtest 维护的 wda 执行的 ios 自动化 iOS-Tagent 地址

import wda #代码执行的驱动,需要pip install python-wda

问题的出现

ios 的打包环境的 xcode 升级到 xcode16 之后,ios 自动化全军覆没

直观的问题

  • 原生 exists、click_exists 方法出现混乱,原先不存在的元素,现在变成存在,如视频全屏时的按钮,点击屏幕后按钮隐藏了,但是查看元素会变成存在,且元素在屏幕外
    • 1、开发无果、文档未见 ,准备修改之前自行封装的 exists、click_exists 方法
    • 2、初步判断为 xcode16 导致"不可见的也可能变成存在"
if element.exists:
    if element.visible:
  • 修改后大部分 exists 准确,然后出现新问题:"部分元素在旧版 xcode 打包出来的,visible 是 True,新版是的 False"

  • 执行后决定自由选择 exists 的时候是否需要判断 visible

#text/label的都不传find_by_str,指向label
#1、 self.exe_exists("""主动防御设置,警报声设置""") 只校验存在,不管visible
#2、 self.exe_exists("""警报声设置""") ,强校验,必须visible==True
#3、 self.exe_exists("""//*[@label="警报声设置"] ""","""self.driver.xpath('//*[@label="警报声设置"]') """),str_value可以随意传. 强校验,必须visible==True

def exe_exists(self, str_value, find_by_str='label'):
        #仅核心代码
        str_value = str_value
        list1 = []
        list2 = []
        if find_by_str == 'label':
            list = str_value.split(',')
            # 检查list[0]是否是整数
            if list and list[0].isdigit():#如果是 1,hello,word  ,逗号第一位是数字,后面的hello,word就是一个整体,实际判断“hello,word”
                # 合并list[1:]为一个字符串
                merged = ','.join(list[1:])
                list=[]
                list[0] = merged
            for i in list:
                if self.driver(label=i).exists:
                    if len(list) == 1:  # 只有一个数据时,按严格判断存在,直接失败
                        if self.driver(label=i).visible:
                            list1.append(i)
                        else:
                            self.add_screenshot_strs(f"visible false{i}")
                            list2.append(i)  # 加到错误列表中
                    else:
                        list1.append(i)  # 多条数据时不严格,存在就可以
                else:#完全不存在
                    self.add_screenshot_strs(f"完全不存在{i}")
                    list2.append(i)  # 加到错误列表中
        else:
            element = eval(find_by_str)#这里的find_by_str是我封装过的,实际上是个字符串,如 "driver(text="设备设置")"
            if element.exists:
                if element.visible:
        if len(list2) > 0:
            self.add_screenshot_strs(f"不存在值self.exe_exists(" + ','.join(list2))
  • click_exists 可以过分一点必须 visible==True
def click_exists_screenshot(self, find_by_str, api_value):
    self.add_screenshot_strs(f"click_exists_screenshot({find_by_str},{api_value})")
    element = eval(find_by_str)
    if element.exists:
        if element.visible == True:
            self.screenshot()
            # self.click_screenshot(find_by_str, api_value)#直接去点击 或者直接用下面的原生方法
            element.click_exists()

多次通信导致速度降低

#原先 
if self.driver(label=i).exists:
    if self.driver(label=i).visible:

#提速
if self.driver(label=i,visible=True).exists:#存在且显示

执行过程中发现可能 提速后的结果可能不正确,下面 2 种方式,方式 2 得到的 exists 为 False。对比 Xcode15 的 app 版本,确定是 Xcode16 引起的

# 方式1
if self.driver(label="更多日期").exists: #元素审查器看到的值
    if self.driver(label="更多日期").visible:
        print("存在")
# 方式2
if driver(label='更多日期',visible=True).exists:
    print("存在")

继续补救

for i in list:
    if self.driver(label=i,visible=True).exists:  #优先用提速的方式,提速失败后,再执行一次未提速的方法
        list1.append(i)
    else:
        if self.driver(label=i).exists:
            if len(list) == 1:  # 只有一个数据时,按严格判断存在,直接失败
                if self.driver(label=i).visible:
                    list1.append(i)
                else:
                    self.add_screenshot_strs(f"visible false{i}")
                    list2.append(i)  # 加到错误列表中
            else:
                list1.append(i)  # 多条数据时不严格,存在就可以
        else:#完全不存在
            self.add_screenshot_strs(f"完全不存在{i}")
            list2.append(i)  # 加到错误列表中

有其他避坑方式请留言

有其他坑 请留言

共收到 2 条回复 时间 点赞

我发现新的 wda 用 pocoUI 定位元素的位置不准

wtlwang_2024 回复

你的要定位的东西在列表上吧,新版在列表上从头找到尾,基本上都在屏幕外。
我自己的重构了,
1、优先 driver(text='模式', visible=True) 快捷指定 visible=True 找到显示区域的,但是新版这个 visible=True 可能不准 (部分 True 的可能返回 False)
2、1 找不到,再去循环查询 driver(text='模式')
element=driver(text='模式')
elementcount = element.count()
for i in range(1, elementcount + 1):
if element[i].visible:
print(str(i) + '个时是显示的')
break

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