ATX ATX 文档 - iOS 控件操作 API

codeskyblue · January 21, 2017 · Last by codeskyblue replied at October 12, 2019 · 7100 hits
本帖已被设为精华帖!

补充说明

部分接口已经过期,请参考最新的文档 https://testerhome.com/topics/9854

前言

这天万里无云,PM指数50以下,正式写文章的好日子。ATX群里一直都有人说需要一篇iOS操作的接口列表,被我拖延到了现在,快过年了,坚决不能拖延到年后。
接口手册按照我以前的风格肯定是写到Github的README里面的,但是这样有个坏处,就是看不到浏览数,也没法评论,修改起来也不是很方便。最头疼的是贴图不方便。所以最终决定把接口手册放到Testerhome上,一来可以帮testerhome导入点流量,另外该要的功能也都有了。

为了方便快速书写,用到了一些简称。比如ATX代表AutomatorX,WDA代表WebDriverAgent

环境搭建部分可以独立成章,但文章我不想主要介绍这个,所以都只是简单的提了下,通过提到的线索你依然可以搭建起来环境。
主要部分还是介绍接口,而且接口会根据Github上的代码变更随时更新。

环境准备

  • Mac电脑
  • iPhone手机(实在没有,用模拟器也行)
  • WebDriverAgent 首页有说明,把他运行起来就好。
  • Python(这个要会用)目前ATX兼容py2.7,理论上兼容py3.4但是还没测试过
  • AutomatorX

    ATX(AutomatorX的简称)的安装不看文档也可以,反正也不难,两个命令就装好了

    pip install --pre --upgrade atx
    pip install opencv_python

接口列表

为了方便调用WDA,于是写了一个纯Python的WDA客户端facebook-wda,如果有些接口下面的文章没有提到,在该项目的README,或者代码中或许可以发现一些彩蛋。

连接设备

如果连接的是真机的话,还需要通过iproxy将手机监听的8100端口转发到本地来。

这里假设你启动的WDA的地址是http://localhost:8100

import atx

d = atx.connect("http://localhost:8100")

后面的接口都会默认你已经有d这个变量了

应用的启停

需要知道应用的bundleId,可以通过ideviceinstaller -l查到。

d.start_app('com.apple.Health') # 启动默认的健康程序
d.stop_app()

基本操作

屏幕大小,这里是实际显示的大小。截图是多大,返回的就是多大

dis = d.display
print dis.width, dis.height

截图

image = d.screenshot() # 返回PIL图片
image.save("screen.png") # 保存成文件,这个是PIL的基础用法。其他的什么旋转,抠图,还有很多

坐标点击

d.click(20, 30)

滑动

d.swipe(300, 400, 300, 100, 1.0) # (300, 400)滑动到 (300, 100) 时间1.0s (默认0.2s)

其他

d.home() # 点击Home

选择控件

浏览器打开WDA的inspector窗口

右上角的用户图标,我们可以根据Class,Name,Label来定位

# 根据所有属性定位
elem = d(class_name="Button", name="profile", label="profile")
# 使用下标定位,界面上的第2Button(下标是从0开始的)
elem = d(class_name="Button", index=1)
elem = d(class_name="Button")[1] # 跟上面的命令等价

通过xpath定位

xpath有很多的规则,我用的很少,欢迎高手留言补充。这种操作比较慢,但是功能强大

elem = d(xpath="//Button")

控件操作

elem.exists # 判断控件是否存在
len(elem) # 返回符合条件元素的个数

elem.click() # 等待并点击
elem.click(timeout=5.0) # 5s之内还有出现符合条件的元素,直接跑异常。timeout目前默认都是90s
elem.wait(timeout=5) # 等待目标的出现
elem.tap_hold(2) # 长按2s

# elem.swipe('up') # 这个接口目前没有了,有待更新

elem.bounds # 返回namedtuple,这个坐标体系还需要乘以 d.scale 才能转化成ATX的坐标体系。
# Returns
# Rect(x=279, y=29, width=25, height=25)

# 获取元素的属性
elem.class_name
elem.text # 这个跟inspector中的Name一个意思
elem.value
elem.enabled # 是否启用
elem.displayed # 这个还真的很少用

刚才的应用进入到用户界面,点击Edit,会进入到这个界面,正好可以演示下怎么输入这个功能

用inspector可以看到元素的结构是这个样子的

输入框

为了确保不被所谓的联想字符,自动修正所干扰,打开输入法设置界面,将所谓的联想输入都关闭掉。
是否支持中文呢?刚试了下,竟然支持(自己都觉得惊讶)

为了找到输入框,不得不用复杂的xpath了,xpath的使用我参考了这篇文章http://www.cnblogs.com/songshu120/p/5182043.html

elem = d(xpath="//Cell[@label='First Name']/TextField")
elem.set_text("James") # 设置文本
elem.value # 获取刚刚输入的文本
elem.clear_text() # 清空刚刚输入的文本

除了这种方法还有另外一种方法

elem.click() # 使输入框处于激活状态
d.type("James")
d.type("\b\b") # 删除两个字符

Scroll

s(text="Vitals").scroll() # scroll to visible
s(text="Login").scroll().click() # 滑到到该元素,然后点击
s(text="Hello").scroll(direction="right", timeout=5.0) # 指定滑动的方向向右,方向有4up | down | left | right
# 有点尴尬了,我也不记得下面两个是干什么用的了
s(text="Hello").scroll(text="World")
s(text="Hello").scroll(text_contains="World")

警告框

目前封装的一般般,但也可以酬和着用

d.session.alert.text # 当前弹出框的文本
d.session.alert.accept() # 点击弹出框的确认
d.session.alert.dismiss() # 点击弹出框的取消

DONE

真是多呀,写了这么久。不幸的是还是没有写完。ATX还有图像识别这一块,篇幅差不多也可以写跟这篇一样多了。先写这么多吧,累死我了,打游戏去了。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 50 条回复 时间 点赞

辛苦辛苦!

👍 👍 👍 👍 👍 明年我正好要写接口,给我点启示,非常谢谢,

我看这定位控件/操作控件这套东西,怎么感觉不像是接口自动化呢?接口自动化不是应该脱离UI层吗?个人愚见

标题写歧义了,开始我也误解了。
这是ATX的API说明文档。

#5楼 @among29 稍等,我改下

辛苦,辛苦!
👏

retry to connect, error: HTTPConnectionPool(host='127.0.0.1', port=8100): Read timed out. (read timeout=10). 麻烦问一下这个操作超时时间如何设置更改

#8楼 @yundanfengqing007 你操作什么了?

#8楼 @yundanfengqing007 你执行了什么操作,怎么会超时

写了一个循环依次点击button[1~5],点到第三个button时就会超时,前2个可以正常点击。如果只点击第3个button也是正常的。好诡异,不过前2个button点击速度也是挺慢的

#11楼 @yundanfengqing007 打开调试,可以查看下执行了哪些HTTP请求。估计还是WDA出了啥问题

import wda

wda.DEBUG = True

@codeskyblue 你好楼主,我想问下你这个ATX能否支持webview中的页面元素获取,我看你这个demo基本都是native的

能并发么?

#16楼 @sixleaves 理论上没问题,我只试过同时开模拟器和手机

#17楼 @codeskyblue 我发现多机器(指手机)直接并行编译WDA会有问题,不知道你怎么解决的~

#19楼 @codeskyblue 😂 我说的就是命令行啊,xcodebuild那条命令

恒温 将本帖设为了精华贴 14 Feb 08:37

更加期待ATX在游戏测试方面的实践

#22楼 @Lihuazhang 很不幸的是,内部推广的也一般,所以没多少实践可以分享的

#24楼 @Lihuazhang 如今的情况是社区的活跃度要大于内部的

恒温 回复

最近也在看游戏自动化测试方面的,看了腾讯的GA方案,但不支持iOS,还有网易的这个AutomatorX(基于OpenCV, 和Google 2015在GTA上分享的方案一样),不知道还有其他可用的第三方么?

codeskyblue 回复

这个webview也适合ios么

sixleaves 回复

前段时间听说sikuli支持移动端了,不知道是不是支持iOS

jmei 回复

还没封装进来,但是最终也只是简单的封装selenium。Android的webview已经集成进来了

codeskyblue 回复

不支持真机,貌似是支持模拟器。

32Floor has been deleted
codeskyblue 回复

你好,我在多真机运行几十条测试用例的过程中,时不时碰到http连接断掉的情况,有什么办法监控wda的状态么,想断掉就自动重启wda

jmei 回复

命令行启动,失败了会自动退出的

比如live photo,我想长按,要怎么实现。
API操作的有更详细的文档吗

loneyao 回复

d.session.tap_hold(x, y, duration=1) 这种方法,一些没有提到的方法可以在这里找到
https://github.com/openatx/facebook-wda

codeskyblue 回复

好的,谢谢了。

翔哥😀 😀 😀

cg 回复

谁呀

codeskyblue 回复

现在atx支持ios的webview测试了么,求分享经验

codeskyblue #41 · May 19, 2017 作者
jmei 回复

目前还没有集成到 ATX中

codeskyblue ATX 资料快速索引 中提及了此贴 21 Jun 19:39

环境:python3.6

代码如下

import atx

d = atx.connect("http://localhost:8100")
d.start_app(bundleId)

我在调用start_app(bundleId)时,报下面的错误,请问有遇到过着种情况吗:

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/atx/drivers/ios_webdriveragent.py", line 74, in start_app
self._session = self._wda.session(bundle_id)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/__init__.py", line 207, in session
res = self._request('session', 'POST', data=data)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/__init__.py", line 143, in _request
return httpdo(urljoin(self._target, base_url), method, data)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/wda/__init__.py", line 75, in httpdo
response = fn(url, data=data, timeout=10)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/api.py", line 112, in post
return request('post', url, data=data, json=json, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/adapters.py", line 490, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
'''
meitian 回复

你这个问题解决了吗?如何解决的呢

雨雾恨 回复

没解决,现在没有在用atx

请问这个操作支持ios10以上的系统吗??

何畅 回复

有人试过支持ios11的

执行速度怎么样? 应该比appium快吧

用WDA的inspector去抓界面元素,不会很慢吗?

lang.feng 回复

会呀

codeskyblue 回复

那你还是用这个抓界面吗?我这有时一直刷新状态刷不出来,醉了,请问你有更好的办法吗?

codeskyblue 回复

IOS的H5页面现在也支持了吗

想问一下atx可以模拟ctrl+v操作吗?比如我在页面点击一个按钮‘复制链接’,怎么如何把复制的链接赋值给一个变量,或者保存本地

bianwancheng 回复

有这个接口,但貌似不太好使

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up