之前我们在终端试着调用过WDA API, 今天我们在看一个Python封装的api库
https://github.com/openatx/facebook-wda
安装方式(一):
pip install --pre facebook-wda
安装方式(二):
git clone https://github.com/openatx/facebook-wda.git cd facebook-wda/ python setup.py install
用Xcode开启WDA 会话, 然后再编写和执行脚本
import wda # Enable debug will see http Request and Response # wda.DEBUG = True # get env from $DEVICE_URL if no arguments pass to wda.Client # http://localhost:8100 is the default value if $DEVICE_URL is empty c = wda.Client() # Show Status print c.status()
输出:
/usr/bin/python2.7 /Users/jackey/Documents/iOS/code/iOS-Auto/Python_Client/Python_Client.py {u'ios': {u'ip': u'192.168.1.101', u'simulatorVersion': u'11.2.1'}, u'state': u'success', u'os': {u'version': u'11.2.1', u'name': u'iOS'}, u'build': {u'time': u'Dec 25 2018 11:48:43'}, u'sessionId': u'24AFBCFD-8CA0-4E4F-BEC3-21AD1170D880'} Process finished with exit code 0
返回Home Screen
# Press home button
c.home()
截屏
# Take a screenshot c.screenshot('screen.png')
打开和关闭app
# Open app s = c.session('NOVA.ProductDemo') # print app oritation print s.orientation # Close app s.close()
还可用一下方式代替上面的代码:
with c.session('NOVA.ProductDemo') as s: print s.orientation
使用浏览器打开指定网站, 然后关闭
# 使用safari浏览器打开百度 s = c.session('com.apple.mobilesafari',['-u', 'http://www.baidu.com']) print s.orientation # 关闭浏览器 s.close()
打印app的bundle_id和sessionid
# open app s = c.session('NOVA.ProductDemo') # Current bundleId and session Id print s.bundle_id, s.id
输出:
/usr/bin/python2.7 /Users/jackey/Documents/iOS/code/iOS-Auto/Python_Client/Python_Client.py NOVA.ProductDemo E56C8902-DDB6-485A-8B0B-AA907CF55C59 Process finished with exit code 0
截屏保存为png
# Screenshot return PIL.Image
# Requires pillow, installed by "pip install pillow"
s.screenshot().save("s.png")
截屏并旋转90度
from PIL import Image
s.screenshot().transpose(Image.ROTATE_90).save("correct.png")
调整显示方向
# Open url with safari s = c.session('com.apple.mobilesafari',['-u','http://www.baidu.com']) print s.orientation # Wait 5s time.sleep(5) # Print orientation print s.orientation # Change orientation s.orientation = wda.LANDSCAPE
获取屏幕尺寸
# Get width and height
print s.window_size()
模拟touch
# Simulate touch s.tap(200, 200)
Click, 类似tap, 但支持小数
s.click(200, 200) s.click(0.5, 0.5) # click center of screen s.click(0.5, 200) # click center of x, and y(200)
滑动
# Simulate swipe, utilizing drag api
# 从(x1,y1)划向(x2,y2) s.swipe(x1, y1, x2, y2, 0.5) # 0.5s
# 从屏幕右边往左划 s.swipe_left()
# 从屏幕左边往右划 s.swipe_right()
# 从屏幕底部往上划 s.swipe_up()
# 从屏幕顶部往上划 s.swipe_down()
长按
# tap hold s.tap_hold(x, y, 1.0)
关闭键盘
# Hide keyboard (not working in simulator), did not success using latest WDA s.keyboard_dismiss()
查找元素element
# For example, expect: True or False # using id to find element and check if exists s(id="URL").exists # return True or False # using id or other query conditions s(id='URL') s(name='URL') s(text="URL") # text is alias of name s(nameContains='UR') s(label='Address') s(labelContains='Addr') s(name='URL', index=1) # find the second element. index starts from 0 # combines search conditions # attributes bellow can combines # :"className", "name", "label", "visible", "enabled" s(className='Button', name='URL', visible=True, labelContains="Addr")
高阶查询
s(xpath='//Button[@name="URL"]') s(classChain='**/Button[`name == "URL"`]') s(predicate='name LIKE "UR*"') s('name LIKE "U*L"') # predicate is the first argument, without predicate= is ok
例如:
# Open app s = c.session('NOVA.ProductDemo') print s.window_size() s.click(100,640) e = s(text='京东超市').get(timeout=10)
如果提示:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
需要在代码中添加:
import sys reload(sys) sys.setdefaultencoding('utf8')
或者在所有中文字符串前加上u, 比如u'白色'
元素操作: (点击、滑动、设置文本...)
举例:
# Open app s = c.session('NOVA.ProductDemo') print s.window_size() s.click(100,640) e = s(text='京东超市').get(timeout=10) e.tap() # tap element
如果每次都先用get获取element, 再执行操作代码比较冗余
可以按如下方式使用, 省去get
s(text='京东超市').tap()
但如果想要获取元素的属性, 就必须先使用get方法
print s(text='京东超市').get().value
先判断存在再点击
s(text='京东超市').click_exists() # 如果没有找到标签则立即返回 s(text='京东超市').click_exists(timeout=5.0) # 等待5s
判断标签是否存在
# 判断标签是否存在 print s(text='京东超市').exists
找到所有匹配的标签
# 找到所有匹配的标签, 返回数组 e_array = s(text='京东超市').find_elements() print len(e_array)
用脚标获取指定匹配的元素
# 找第二个匹配的元素 print s(text='京东超市')[1].exists
获取属性
print s(text='京东超市').text print s(text='京东超市').class_name print s(text='京东超市').value print s(text='京东超市').bounds
输出
京东超市 None None Rect(x=15, y=129, width=56, height=20)
其他操作
# Use child to search sub elements s(text='Dashboard').child(className='Cell').exists # Default timeout is 10 seconds # But you can change by s.set_timeout(10.0) # do element operations e.tap() e.click() # alias of tap e.clear_text() e.set_text("Hello world") e.tap_hold(2.0) # tapAndHold for 2.0s e.scroll() # scroll to make element visiable # directions can be "up", "down", "left", "right" # swipe distance default to its height or width according to the direction e.scroll('up') # Set text e.set_text("Hello WDA") # normal usage e.set_text("Hello WDA ") # send text with enter e.set_text("") # delete 3 chars # Wait element gone s(text='Dashboard').wait_gone(timeout=10.0) # Swipe s(className="Image").swipe("left") # Pinch s(className="Map").pinch(2, 1) # scale=2, speed=1 s(className="Map").pinch(0.1, -1) # scale=0.1, speed=-1 (I donot very understand too) # properties (bool) e.accessible e.displayed e.enabled # properties (str) e.text # ex: Dashboard e.className # ex: XCUIElementTypeStaticText e.value # ex: github.com # Bounds return namedtuple rect = e.bounds # ex: Rect(x=144, y=28, width=88.0, height=27.0) rect.x # expect 144
Alert操作
print s.alert.exists print s.alert.text s.alert.accept() # Actually do click first alert button s.alert.dismiss() # Actually do click second alert button s.alert.wait(5) # if alert apper in 5 second it will return True,else return False (default 20.0) s.alert.wait() # wait alert apper in 2 second s.alert.buttons() # example return: ["设置", "好"] s.alert.click("设置")
自动处理alert
import wda s = wda.Client().session() def _alert_callback(session): session.alert.accept() s.set_alert_callback(_alert_callback) # do operations, when alert popup, it will auto accept s(type="Button").click()
最后给个演示百度搜索的例子:
# -*-coding:utf-8 -*- import wda # Create WDA Client my_drive = wda.Client() # Open www.baidu.com with safari my_session = my_drive.session('com.apple.mobilesafari',['-u','https://www.baidu.com']) # Set text my_session(className = 'SearchField').set_text(u'白色') # Click Search Button my_session(text = u'百度一下').click()