0x01 简介
WebDriverAgent一款自动化iOS测试工具,相当于在iphone上安装一个软件作为服务端,然后接受处理来自mac客户端的请求。
0x01 安装
#安装WebDriverAgent
git clone https://github.com/facebook/WebDriverAgent.git
brew install carthage
brew install node
cd WebDriverAgent && sudo ./Scripts/bootstrap.sh
#安装libimobiledevice
brew install --HEAD libimobiledevice
#安装imobiledevice
brew install imobiledevice
#安装facebook-wda
pip install --pre facebook-wda
0x02 配置
- 基本设置
iphone 屏幕常亮、wifi 连接以及后续设置信任开发者。
- 配置证书
cd WebDriverAgent
open WebDriverAgent.xcodeproj
WebDriverAgentLib -> Signing
WebDriverAgentRunner -> Product Bundle Identifier -> com.facebook.WebDriverAgentRunerfdfdasf //修改BundleID避免重名
WebDriverAgentRunner -> Signing
Product -> Destination -> xxx的iphone
Product -> Scheme -> WebDriverAgentRunner
View -> Debug Area -> Activate Console
Product -> Test
sudo iproxy 8100 8100
- 验证
http://localhost:8100/inspector
http://localhost:8100/status
ideviceinstaller -l //查看所有应用Bundle ID
- 定位元素
图片浏览器定位,鼠标放上去就能显示当前坐标,比如GIMP或者在线网站
0x03 facebook-wda语法
- 基本操作
import wda
wda.DEBUG = True #开启debug模式方便查看API
c = wda.Client("http://192.168.1.101:8100")
c.home() #点击主页按钮
c.source(accessible = True) #获取页面源码
c.screenshot('screen.png') #截图只能保存png
- 会话操作
import wda
wda.DEBUG = True
c = wda.Client("http://192.168.1.101:8100")
s = c.session()
with c.session("com.apple.Health") as s:
print s.window_size() #获取尺寸
s.tap(200,200) #模拟触摸
s.double_tap(200,200) #双次触摸
s.tap_hold(100, 100, press_time) #在 (100, 100) 的位置按压 press_time 后松开
# s.swipe(X1,Y1,X2,Y2, 0.5)# 0.5秒
# s.swipe_left()
# s.swipe_right()
# s.swipe_up()
# s.swipe_down()
# #抽头保持
# s.tap_hold(X,Y, 1.0)
- 操作元素
import wda
wda.DEBUG = True
c = wda.Client("http://192.168.1.101:8100")
with c.session("com.apple.Health") as s:
s(text='Dashboard').get().tap()
s(text = ' Dashboard ').find_elements() #查找所有匹配元素,返回元素对象数组
s(text = 'Dashboard ').child(className = ' Cell ')#使用子元素搜索子元素
s.set_text("Hello WDA\n") # 发送文本
s.set_text("\b\b\b") # 删除三个字符
s(text='Dashboard').wait_gone(timeout=10.0)
s(className="Image").swipe("left")#像图片左滑动
RECT = e.bounds#例如:矩形(X = 144,Y = 28,宽度= 88.0,高度= 27.0)
- 弹框操作
弹框可以用alert进行处理或者直接s(name=u'知道了').tap()
session.alert.accept()
0x04 常见案例
- 下载以及登录APP
# -*- coding:utf-8 -*-
# !/usr/bin/env python
import time
import wda
wda.DEBUG = True
c = wda.Client("http://localhost:8100/")
def download():
s = c.session("com.apple.mobilesafari", ["-u", "https://itunes.apple.com/app/id590338362"])
e = s(name=u'打开').get(timeout=10, raise_error=False)
e.tap()
time.sleep(5)
if s(className='Button', name=u'获取').exists:
s(className='Button', name=u'获取').get(timeout=2, raise_error=False).tap()
s(className='Button', name=u'安装').get(timeout=30, raise_error=False).tap()
elif s(className='Button', name=u'重新下载').exists:
s(className='Button', name=u'重新下载').get(timeout=10, raise_error=False).tap()
else:
exit()
def alert_callback(session):
"""
处理不知何时就会突然弹出的警告框
"""
btns = set([u'不再提醒', 'OK', u'知道了', 'Allow', u'允许']).intersection(session.alert.buttons())
if len(btns) == 0:
raise RuntimeError("Alert can not handled, buttons: " + ', '.join(session.alert.buttons()))
session.alert.click(list(btns)[0])
def login():
USERNAME = 'xxxx'
PASSWORD = 'xxxx'
s = c.session('com.netease.cloudmusic')
s.set_alert_callback(alert_callback)
if s(name=u'发现音乐', type='Button').wait(3, raise_error=False): # 开头有2s的广告,所以这里需要等待3s
return # 已经登录直接跳过
s(name=u'登录/注册').tap()
s.set_alert_callback(alert_callback)
s(name=u'手机号登录').tap()
s(type='TextField').set_text(USERNAME + '\n')
s(type='SecureTextField').set_text(PASSWORD + '\n')
s(name=u'登录').click_exists(timeout=3.0)
assert s(name=u'发现音乐', type='Button').wait(5.0)
def main():
download()
time.sleep(180)
login()
if __name__ == "__main__":
main()
- 答题
# -*- coding:utf-8 -*-
# !/usr/bin/env python
# 通过wda截图然后PIL剪裁定位文字后用OCR识别并放入搜素引擎找出词频最高的一个即答案。
import wda
import webbrowser
import base64
import time
import io
import requests
from PIL import Image
import urllib.parse
wda.DEBUG = True
c = wda.Client()
while True:
time.sleep(0.5)
c.screenshot('1.png')
im = Image.open("1.png")
region = im.crop((75, 315, 1167, 789))
imgByteArr = io.BytesIO()
region.save(imgByteArr, format='PNG')
image_data = imgByteArr.getvalue()
base64_data = base64.b64encode(image_data)
r = requests.post('https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic',
params={'access_token': "24.3ad800dedc42aa06d955e786a8b304f9.2592000.1530559010.282335-11341238"}, data={'image': base64_data})
result = ''
for i in r.json()['words_result']:
result += i['words']
result = urllib.parse.quote(result)
webbrowser.open('https://baidu.com/s?wd=' + result)
input("> Next")
- 批量删除短信
import time
import wda
c = wda.Client()
with c.session('com.apple.MobileSMS') as s:
while 1:
s.swipe(300, 300, 100, 300, 0.5) # 左滑
s.tap_hold(c.session().window_size().width * 3 - 20, 900, 0.2) # 点击删除
- 自动点击
import time
import wda
wda.DEBUG = True
c = wda.Client("http://localhost:8100/")
def tap():
s = c.session("com.yaymedialabs.putong")
while 1:
s(name='home user dislike button', type='Button').click_exists()
#time.sleep(0.1)
tap()
0x05 引用
iOS 真机如何安装 WebDriverAgent
使用 Python 库 facebook-wda 完成网易云音乐 iOS 客户端的自动化测试
iOS自动化实践——WebDriverAgent(六)
微信「跳一跳」破解程序开发记录
---The END---