facebook-wda:iOS 自动化的强大 Python 客户端
facebook-wda 是一个基于 Python 语言的客户端库,用于进行 iOS 平台的 UI 自动化测试。它的本质是一个“指挥官”,通过发送 HTTP 命令,远程控制一个运行在 iOS 设备上的服务端程序(即 WebDriverAgent),从而模拟用户的真实操作,如点击、滑动、输入文字等。
它遵循典型的 Client-Server (客户端-服务器) 架构:
Server 端 (WebDriverAgent - WDA):
这是一个由 Facebook 开源,后由 Appium 团队维护的项目。
它需要被编译并安装到你的 iOS 设备或模拟器上。
启动后,它会在设备上作为一个服务运行,监听一个端口(通常是 8100),并等待来自客户端的指令。
它的职责是:直接与 iOS 系统的 Accessibility 层交互,查找 UI 元素、执行操作、获取页面信息。
Client 端 (facebook-wda):
这就是我们编写的 Python 脚本。
它的职责是:提供一套简洁的 Python API。当你调用这些 API(如 click, scroll)时,facebook-wda 会将其转换为 HTTP 请求(遵循 WebDriver 协议),发送给远端的 WDA 服务。
相关网址:
facebook-wda github(https://github.com/openatx/facebook-wda)
安装
pip install facebook-wdaQuickStart
在开始之前,在ios安装并启动WebDriverAgent(facebook-wda将依赖这个去驱动ios中的软件),启动办法:
首先使用xcodebuild安装并开启wda
xcodebuild -project /path/to/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination "id=<你的设备UDID>" test成功开启wda后,将端口转发到本地
tidevice -u [你的设备UDID] relay [本地端口] 8100
# 例如: 为 UDID 为 123456 的设备将本地 8200 端口转发到设备的 8100 端口
tidevice -u 123456 relay 8200 8100如果是ios17以下,则可以直接使用tidevice唤醒wda并自动转发端口:
tidevice wdaproxy -B com.facebook.wda.WebDriverAgent.Runner --port 8200命令运行完成后,保持终端以防中断wda的唤醒,在浏览器中输localhost:8200/status 检查是否成功唤醒了wda
然后如下代码保存在main.py,并运行:
import wda
import time
# 1. 连接设备
c = wda.Client("http://localhost:8200") # 指定server地址和ios设备的端口
print("设备信息:", c.status())
# 2. 启动设置应用
s = c.session('com.apple.Preferences')
print("会话已创建")
# 3. 进入通用设置
try:
# 等待并点击"通用"
s(name='General').wait(5.0).click()
print("已进入通用设置")
# 等待并点击"关于本机"
s(name='About').wait(5.0).click()
print("已进入关于本机")
# 获取设备名称
device_name = s(name='Name')
device_name.wait(3.0)
if device_name:
print("设备名称:", device_name.text)
# 截图保存
c.screenshot('about_page.png')
print("截图已保存")
# 返回两次
s.tap(50, 50) # 点击左上角返回
time.sleep(1)
s.tap(50, 50) # 再次返回
except Exception as e:
print("操作失败:", e)
c.screenshot('error.png')
# 4. 关闭会话
s.close()
print("自动化完成")wda全局设置
wda.DEBUG = True # 打开调试模式
wda.HTTP_TIMEOUT = 180.0 # http请求超时时间设置
wda.DEVICE_WAIT_TIMEOUT = 180.0 # 等待设备超时时间设置设备操作(Client)
在开始 Client 操作前,保持 WebDriverAgent 的唤醒状态
初始化Client
有两种方法初始化Client
第一种,使用wda.Client的方法初始化,这种方法支持连接在某个服务器中的设备:
c = wda.Client("http://localhost:8123") # 指定server地址和ios设备的端口第二种,使用wda.USBClient的方法初始化,这种方法支持直接指定连接本地设备的udid:
c = wda.USBClient(udid="设备udid", port=8123) # 指定设备的udid和端口wda.USBClient这个方法实际是把url改http+usbmux://设备udid:8123/status ,需要设备支持usbmux通信协议。MacOS原生支持,Windows需要安装并配置 libimobiledevice(官方下载地址:https://libimobiledevice.org/#downloads)或 iTunes 套件
iOS 17+ 引入了新的 RemoteXPC+QUIC 通信协议,取代了旧版协议,所以建议使用第一种方法初始化Client,连接本地指定为localhost即可
等待wda服务正常运作
c.wait_ready(timeout=120)获取设备信息
获取设备基础信息
c.info
c.device_info()获取设备wda服务状态
c.status()获取电量信息
c.battery_info() # 区间为[0, 1], 1为满电, 0为没电获取分辨率
c.window_size()按键模拟
c.press("home") # 也可以直接调用c.home()
c.press_duration("volumeUp", 1) # 长按音量增加按键1s, "volumeDown"是音量减少按键锁屏
检查设备是否锁屏
c.locked()锁屏
c.lock()解锁
c.unlock()截图
c.screenshot("screen.png")应用管理
启动应用
c.app_launch("com.apple.Preferences") # 通过包名启动应用
c.app_activate("com.apple.Preferences") # 通过包名激活应用(不在后台则直接启动)终止应用
c.app_stop("com.apple.Preferences") # 通过包名终止应用
c.app_terminate("com.apple.Preferences") # 通过包名终止应用获取设备当前打开的应用
c.app_current()获取app当前状态
c.app_state("com.apple.Preferences") # value 1(没有运行) 2(后台运行) 4(前台运行,在当前页面显示状态)