之前我们在终端试着调用过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. /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

返回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. /Users/jackey/Documents/iOS/code/iOS-Auto/Python_Client/Python_Client.py
NOVA.ProductDemo E56C8902-DDB6-485A-8B0B-AA907CF55C59 Process finished with exit code

截屏保存为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() # Print orientation
print s.orientation # Change orientation
s.orientation = wda.LANDSCAPE

获取屏幕尺寸

# Get width and height
print s.window_size()

模拟touch

# Simulate touch
s.tap(, )

Click, 类似tap, 但支持小数

s.click(, )
s.click(0.5, 0.5) # click center of screen
s.click(0.5, ) # click center of x, and y()

滑动

# Simulate swipe, utilizing drag api
# 从(x1,y1)划向(x2,y2)
s.swipe(x1, y1, x2, y2, 0.5) # .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=) # find the second element. index starts from # 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(,)
e = s(text='京东超市').get(timeout=)

如果提示:

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(,)
e = s(text='京东超市').get(timeout=)
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='京东超市')[].exists

获取属性

print s(text='京东超市').text
print s(text='京东超市').class_name
print s(text='京东超市').value
print s(text='京东超市').bounds

输出

京东超市
None
None
Rect(x=, y=, width=, height=)

其他操作

# Use child to search sub elements
s(text='Dashboard').child(className='Cell').exists # Default timeout is 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 .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\n") # send text with enter
e.set_text("\b\b\b") # delete chars # Wait element gone
s(text='Dashboard').wait_gone(timeout=10.0) # Swipe
s(className="Image").swipe("left") # Pinch
s(className="Map").pinch(, ) # scale=, speed=
s(className="Map").pinch(0.1, -) # scale=0.1, speed=- (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=, y=, width=88.0, height=27.0)
rect.x # expect

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() # if alert apper in second it will return True,else return False (default 20.0)
s.alert.wait() # wait alert apper in 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- -*-

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()

iOS自动化探索(三)WebDriverAgent Python Client的更多相关文章

  1. 【Mac + Python3.6 + ATX基于facebook-wda】之IOS自动化(三):facebook-wda库--API学习以及附录:Github上对WDA的问题解答

    下面简单介绍facebook-wda库--API的学习 import wda # debug模式,会在run运行时控制台生成消息 wda.DEBUG = False # False 关闭,True开启 ...

  2. iOS自动化探索(一)WebDriverAgent安装

    WebDriverAgent FaceBook推出的一款iOS移动测试框架, 支持真机和模拟器, 同时支持USB, 官方是这样介绍的: https://github.com/facebook/WebD ...

  3. iOS自动化探索(六)自动化测试框架pytest - fixtures

    Fixture介绍 fixture是pytest特有的功能,它用pytest.fixture标识,定义在函数前面.在编写测试函数的时候,可以将此函数名称做为传入参数,pytest将会以依赖注入方式,将 ...

  4. iOS自动化探索(七)自动化测试框架pytest - 测试报告

    这里我们单独来看下关于如何生存测试报告 准备测试代码如下: #coding: utf- import pytest @pytest.fixture() def login(): print '输入账号 ...

  5. iOS自动化探索(五)自动化测试框架pytest - Assert断言的使用

    使用assert语句进行断言 pytest允许使用标准的python assert语法,用来校验expectation and value是否一致 代码演示: def func(): def test ...

  6. iOS自动化探索(四)自动化测试框架pytest - 安装和使用

    自动化测试框架 - pytest pytest是Python最流行的单元测试框架之一, 帮助更便捷的编写测试脚本, 并支持多种功能复杂的测试场景, 能用来做app测试也能用作函数测试 官方文档: ht ...

  7. iOS自动化探索(二)WDA API的使用

    前面我们已经安装好了WebdriverAgent, 现在可以用Facebook官方提供的API来进行一些操作 WDA API官方页面: https://github.com/facebook/WebD ...

  8. iOS自动化探索(十)代码覆盖率统计

    iOS APP代码覆盖率统计 今年Q3季度领导给加了个任务要做前后端代码覆盖率统计, 鉴于对iOS代码代码比较熟就选择先从iOS端入手,折腾一整天后终于初步把流程跑通了记录如下 覆盖率监测的原理 Xc ...

  9. iOS自动化探索(九)使用Jenkins自动化打包并发布iOS App

    继前一篇: Mac环境下安装Jenkins Jenkins安装好后, 我们试着创建一个iOS自动打包并发布的任务 iOS App构建必须在MAC上面使用xcode进行,所以我们要安装下xcode集成插 ...

随机推荐

  1. 008-查看JVM参数及值的命令行工具

    1. HotSpot vm中的各个globals.hpp文件  查看jvm初始的默认值及参数 globals.hpp globals_extension.hpp c1_globals.hpp c1_g ...

  2. Angular4中常用管道(转载)

    Angular4中常用管道 通常我们需要使用管道实现对数据的格式化,Angular4中的管道和之前有了一些变化,下面说一些常用的管道. 一.大小写转换管道 uppercase将字符串转换为大写 low ...

  3. MariaDB日志

    1.查询日志:一般来说不开开启(会产生额外压力,并且不一定有价值),query log 记录查询操作:可以记录到文件(file)中也可记录到表(table)中 general_log=ON|OFF g ...

  4. likely(x)与unlikely(x) __builtin_expect

    本文讲的likely()和unlikely()两个宏,在linux内核代码和一些应用中可常见到它们的身影.实质上,这两个宏是关于GCC编译器内置宏__builtin_expect的使用. 顾名思义,l ...

  5. cmd 命令 记忆

    1,“开始”—>“运行”,输入cmd,回车.<或 win+R> 2,出现“命令提示符”的窗口,一般情况下是 C:\Documents and Settings\Administrat ...

  6. Asp.Net中OnClientClick与OnClick的区别

    当我们当击这个按钮时,自动先执行的客户端,再执行服务器端的.如果客户端返回的是false,那么服务器端对应的方法永远不会执行.这样就达到检测,只有通过才去执行服务器端的方法.

  7. Apache 域名跳转配置

    域名跳转 就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等 .   参数格式 参数: Apache mod_rewrite 规 ...

  8. 跳出弹窗页面禁止滚动(PC端和手机端)

    pc端如何实现 1.当弹窗显示时,为body元素添加属性:overflow:hidden, 当关闭弹窗时移除该属性即可2.在弹窗的div上设置 @scroll.stop.prevent 3.前端页面弹 ...

  9. 饭卡管理系统学生E-R图

    - 2 - 1.1 可行性分析 1.1.1 项目背景 近年来学生食堂饭卡的使用给高校餐饮管理带来了一次革命, 从结算方式到账户管理, 从卫生便捷到数据统计等,不仅给就餐者带来了方便,也使餐饮结算手段发 ...

  10. 聊聊这两天在linux安装PHP7遇到的坑,真的是坑死人不偿命啊

    前情摘要: 这两天要在虚拟机上部署项目,用于测试在linux上项目效果怎样,然后这两天就一直在部署apache+mysql+php 其实部署还是很简单的具体的apache和mysql部署方法请看其他两 ...