[facebook-wda]iOS App元素定位

一、定位元素工具weditor

iOS定位工具这里推荐使用weditor,安卓同样可以使用这个工具进行元素连接,appium inspect试过很多次start session连接之后总是提示连接超时,遂放弃使用该工具

二、启动定位工具

参考Android安装环境方法, 使用以下命令安装weditor

pip3 install -U weditor

确保本机已经安装iTunes,并且当前的iOS设备已经连接上且识别到(参考另一篇博文使用tidevice list命令查看)安装完成后使用以下命令开启

python -m weditor

等待网页自动开启,默认显示是这样的

模块选择iOS,默认连接是本地8100接口,点击Connect,发现会出现以下错误

 这是由于本机和iOS设备通信失败,此时使用tidevice程序发起和WebDriverAgent之间的通信,保持手机设备可以识别(非锁屏状态),然后运行以下命令

tidevice -u [设备uuid] wdaproxy -B [webdriveragent bundleid] --port 8100

[I 220611 13:38:23 _wdaproxy:125] [设备uuid] WDA check every 30.0 seconds
[D 220611 13:38:23 _wdaproxy:131] [设备uuid] launch WDA
[I 220611 13:38:24 _device:969] BundleID: [webdriveragent bundleid]
[I 220611 13:38:24 _device:985] ProductVersion: 12.5.5
[I 220611 13:38:24 _device:986] DeviceIdentifier: [设备uuid]
[I 220611 13:38:24 _device:822] SignIdentity: 'Apple Development: xxxxxxxxx@qq.com (2PQLXK79WG)'
[I 220611 13:38:24 _device:828] CFBundleExecutable: WebDriverAgentRunner-Runner
[I 220611 13:38:24 _device:859] AppContainer: /private/var/mobile/Containers/Data/Application/A26DF5B4-203E-4035-9D81-10CC86564A1A
[I 220611 13:38:24 _device:899] Launch '[webdriveragent bundleid]' pid: 986
[I 220611 13:38:25 _device:1035] Test runner ready detected
[I 220611 13:38:25 _device:1027] Start execute test plan with IDE version: 29
[I 220611 13:38:26 _device:935] WebDriverAgent start successfully

等待WDA启动之后,再次点击Connect发现weditor可以正常同步iOS设备,Connect右侧的绿色树叶图标代表已经成功连接 

接下来就可以打开需要测试的App进行元素定位了

三、WDA初始化

全局配置

import wda

wda.DEBUG = False # default False
wda.HTTP_TIMEOUT = 180.0 # default 180 seconds
wda.DEVICE_WAIT_TIMEOUT = 180.0

创建一个客户端

import wda

wda.DEBUG = False # default False
wda.HTTP_TIMEOUT = 180.0 # default 180 seconds
wda.DEVICE_WAIT_TIMEOUT = 180.0

client = wda.Client('http://localhost:8100') # url参数为默认为: http://localhost:8100, 可以修改为其他端口或者ip

设备操作 

接上面创建客户端的代码,执行前确认WDA服务正常

打开功能菜单或者App

client.session("appname") # app_name可以通过tidevice applist进行查看

# 这里我们以打开iOS设备的设置菜单为例
client.session('com.apple.Preferences')

# 还可以通过USBClient连接
client = wda.USBClient() # 仅连接一个设备可以不传参数
client = wda.USBClient("设备udid", port=8100) # 指定设备 udid 和WDA 端口号
client = wda.Client("http+usbmux://{udid}:8100".format(udid="udid")) # 通过DEVICE_URL访问
client = wda.USBClient("udid", port=8100, wda_bundle_id="webdriveragent bundleid") # 引入 wda_bundle_id 参数

针对USBClient(),初始化连接设备时不需要事先使用tidevice命令启动WDA,wda.Client()会自动启动WDA应用,确认iOS设备的设置菜单被打开

关闭功能菜单或者App 

client.close() # 关闭

# 还可以使用app_terminate
client.app_terminate('com.apple.Preferences') # 停止App命令

设备控制

# 回到手机主页面
client.home()
client.press("home")

# 增大降低音量
client.press("volumeUp")
client.press_duration("volumeUp", 1) # 长按1s音量上键
client.press("volumeDown")
client.press_duration("volumeDown", 1) # 长按1s音量下键

# 锁屏
client.locked() # 返回锁定状态True/False
client.lock()  # 锁屏
client.unlock() # 解锁

 获取设备应用信息

# 查看设备状态信息
client.status()

# 获取应用信息
client.app_current()

# 获取设备信息
client.device_info()

# 获取电量信息
client.battery_info()

# 获取分辨率
client.window_size()

四 、元素定位

通过属性值进行定位

id

client(id='element_id')

className 

client(className="element_className")

name 

client(name="element_name")

value

client(value="element_value")

label

client(label="element_label")
client(labelContains="element_label_content")

组合定位

可以进行多个属性组合进行定位,例如:

client(className="element_className", name="element_name")

子元素定位

# 子元素定位
client(className='element_className').child(name='child_element_name').exists

XPath

XPath是XML路径语言,是一种查询语言,使用路径表达式浏览XML文档中的元素和属性。XPath标准语法如下:

XPath=//tagname[@attribute='value']

// : 选择当前节点
tagname: 节点标签名
@: 选择属性
Attribute: 节点属性名
Value: 属性值

示例如下:

client(xpath='//*[@name="element_name"]')
# 或者
client.xpath('//*[@name="element_name"]')

Predicate定位 

Predicate定位是iOS原生支持的定位方式,定位速度比较快,它可以通过使用多个匹配条件来准确定位某一个或某一组元素

基本比较

符号说明示例
===等于name == “通知”
>大于name > 10
<小于name < 10
>==>大于等于name >= 10
<==<小于等于name <= 10
!=<>不等于name != “通知”

集合操作

符号说明示例
ANY , SOME满足表达式的任意元素ANY children.age < 18
ALL满足表达式的所有元素ALL children.age < 18
NONE不包含满足表达式的任意元素NONE children.age < 18
IN元素在集合中name IN { ‘Ben’, ‘Melissa’, ‘Nick’ }
BETWEEN位于某个范围1 BETWEEN { 0 , 33 }
array[index]数组array中指定索引的元素
array[FIRST]数组中的第一个元素
array[LAST]数组中的最后一个元素
array[SIZE]指定数组大小

布尔值

符号说明示例
TRUEPREDICATETRUE
FALSEPREDICATEFALSE

逻辑运算符

符号说明示例
AND, &&逻辑与name="通知" AND label="通知"
OR, ||逻辑或
NOT, !逻辑非

字符串比较

关键字说明示例
BEGINSWITH以某个字符串开始name BEGINSWITH "屏幕"
ENDSWITH以某个字符串结束name ENDSWITH "时间"
CONTAINS包含name CONTAINS "使用时间"
LIKE通配符name LIKE '*Total: $*'
MATCHES正则匹配value MATCHES '.*of 7'

默认情况下,字符串比较是大小写和变音敏感的,可以在关键字后面加上[cd][c]不区分大小写,[d]表示不区分变音符号

变音符号是附加在字母上的符号,用于提示发音或区分相似的单词。很多语言使用变音符,比如法语、西班牙语等。比如法语单词:Pêche 桃子

classChain定位

classChain是Predicate和Xpath定位的结合,搜索效率比XPath更高

class chain 定位方法由mykola-mokhnach开发,和XPath比较类似,可以实现分层查询,但它的查询性能更高,通过将class chain查询映射到一系列的XCUITest调用中,仅查找子节点,不像XPath那样递归地查询整个UI树

儿子节点搜索

选择儿子元素,类似于XPath语法中的反斜杠/,示例如下:

XCUIElementTypeWindow[`label BEGINSWITH "text"`][-1] # 选择label以foo开头的最后一个
XCUIElementTypeWindow/XCUIElementTypeButton[3] # 选择window的儿子元素XCUIElementTypeButton的第3个(索引从1开始)
XCUIElementTypeWindow/*[3]  # 选择window的第3个儿子元素
XCUIElementTypeWindow # 选择所有子窗口
XCUIElementTypeWindow[2] # 选择第二个窗口
XCUIElementTypeWindow[2]/XCUIElementTypeAny # 选择第二个子窗口的所有子元素

子孙节点搜索

类似于XPath语法中的双反斜杠//,示例如下:

**/XCUIElementTypeCell[`name BEGINSWITH "A"`][-1]/XCUIElementTypeButton[10] # 选择name以A开头的最后一个Cell元素的第10个子元素
**/XCUIElementTypeCell[`name BEGINSWITH "B"`] # 选择name以B开头的所有Cell元素
**/XCUIElementTypeCell[`name BEGINSWITH "C"`]/XCUIElementTypeButton[10] # 选择name以C开头的第一个Cell元素的第10个子元素
**/XCUIElementTypeCell[`name BEGINSWITH "D"`]/**/XCUIElementTypeButton # 选择name以D开头的第一个Cell元素下所有后代Button

 五、元素

单个元素实例

client(定位元素).find_elements()

 多个元素实例

client(nameCntains='element_name').find_elements()

还可以通过索引返回单个元素实例

client(nameCntains='element_name', index=2).find_elements()  # 返回匹配的第三个元素
# 或者
client(nameCntains='element_name')[2].find_elements()

判断元素是否存在

client(定位元素).exists  # 返回True或者False

获取元素属性 

element = client(元素定位)

# 获取元素属性有以下几类,返回结果以实际为准
element.className    # XCUIElementTypeButton属性
element.name         # XCUIElementTypeButton属性
element.visible      # True
element.value        # 空
element.label        # label元素名称
element.text         # 当前定位元素方式内容
element.enabled      # True
element.displayed    # True
element.accessible   # True

x, y, w, h = element.bounds # Rect(x=, y=, width=, height=)

六、元素操作

点击元素click\tap

# 元素点击
client(定位方式).tap()
client(定位方式).tap_hold(2.0) # 长按2秒
client(定位方式).click()
client(定位方式).click_exists() # 返回True或者False
client(定位方式).click_exists(timeout=5.0) # 超时等待5秒

#坐标点击
client.tap(x, y)        # 通过坐标进行点击
client.click(x, y)      # 通过坐标进行点击
client.double_tap(x, y)  # 双击

输入set_text/清除clear_text

element= client(元素定位)

# 输入
element.set_text('contenct')

# 清除
element.clear_text()

# 删除多个字符
element.set_text("\b\b\b\n")  # 删除3个字符

# 输入文本+确认
element.set_text('contenct\n')  # \n为确认,类似于输入完按Enter换行

滑动swipe 

WDA的滑动方式有两种 ,一个是根据坐标滑动,一个是安装方向滑动

client.swipe(fx, fy, tx, ty, duration=0.5) # 从(fx, fy)滑到(tx, ty),坐标值可以是迅速值或者百分比,duration单位秒
client.swipe_left()        # 向左滑动
client.swipe_right()       # 向右滑动
client.swipe_up()          # 向上滑动
client.swipe_down()        # 向下滑动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值