前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebDriverAgent与Minicap在iOS真机远控上的应用实践

WebDriverAgent与Minicap在iOS真机远控上的应用实践

原创
作者头像
霍格沃兹测试开发Muller老师
发布2022-06-07 18:30:24
1.2K0
发布2022-06-07 18:30:24
举报

真机远控是一种通过浏览器远程操作智能手机的技术,主要分为两大部分关键功能:实时获取手机屏幕数据及实时传输屏幕操控数据.

开测平台中,已经实现了Android手机的远程操控方案.在此基础上,进一步研究iOS设备的远控最佳方案.本文代码部分使用python语言.

工具介绍

minicap 是开源项目 STF(SmartPhone Test Farm) 中的高速截图工具。STF利用此工具不断的传输图片信息并在web端绘制实现. iOSMinicap提供一个Socket接口用于实时从iOS设备屏幕捕获数据,它采用AVFoundation和iOS屏幕镜像功能实现。

Github地址:

https://github.com/openstf/ios-minicap

WebDriverAgent(WDA)是facebook在2015年推出的一款移动测试框架,支持模拟机和真机.WDA在iOS端实现了一个 WebDriver server ,借助这个 server 我们可以远程控制iOS设备。你可以启动、杀死应用,点击、滚动视图,或者确定页面展示是否正确。wda是iOS上一个完美的端到端的自动化解决方案.

Github地址:

https://github.com/facebook/WebDriverAgent

初步方案

ios-minicap+WDA原生版本

鉴于minicap工具在Android设备上的优秀的高速截图性能,于是首先尝试iOS-minicap在iOS设备上的应用.

此方案要求:iOS版本8以上

1、从github上下载iOS-minicap-master项目全部文件

2、下载wdapython工具包

github地址:

https://github.com/openatx/facebook-wda

3、连接iOS设备(一台)

4、启动minicap:

启动后进程不可退出

5、接收minicap从手机端传回的图片数据:

①建立socket连接到minicap提供的端口:

②读取全局header,仅读取一次.header结构如下:

代码语言:javascript
复制
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">0</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">1
</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">unsigned char</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Version (currently 1)</td>
char
(currently 1)
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">1</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">1</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">unsigned char</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Size of the header (from byte 0)</td>
 char
header (from
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">2-5</td><td style="margin: 5px 10px;" valign="top" width="60">4</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">uint32 (low endian)</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Pid of the process</td>
process
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">6-9</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">4</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">uint32 (low endian)</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Real display width in pixels</td>
width in pixels
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">10-13</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">4</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">uint32 (low endian)</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Real displayheight in pixels</td>
height in pixels
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">14-17</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">4</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">uint32 (low endian)</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Virtual display width in pixels</td>
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">18-21</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">4</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">uint32 (low endian)</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Virtual display height in pixels</td>
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">22</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">1</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">unsigned char</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Display orientation</td>
char
orientation
<td style="word-break: break-all;margin: 5px 10px;" valign="top" width="72">23</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="60">1</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="125">unsigned char</td><td style="word-break: break-all;margin: 5px 10px;" valign="top" width="142">Quirk bitflags</td>
 char

解析header:

③接收图片信息并保存至队列:

④web server采用websocket传输图片数据,ws连接open以后,开始从图片队列中取数据传送给前端显示.

6、使用WDA操作手机屏幕:

①端口映射:终端中运行命令iproxy 8100 8100,保持进程运行中.

②用命令行启动WDA:

测试WDA是否启动成功可以通过操作命令是否超时来判断:

③web server建立新的一条websocket连接,用于接收浏览器页面的鼠标操作,用于WDA操作手机屏幕的参数.

7、整体运行效果如图:

优化方案

WDA屏幕图片接口及控制效果优化

Num

01

原生的WDA中事件驱动速度使用同步机制,在一定程度上影响了手机的响应速度,于是在代码中做修改,去掉同步机制.提高响应速度.

Num

02

Ios-minicap的重要缺陷在于:一台PC只能支持一台手机的图片传输,目前stf团队尚未解决多台设备的问题.不符合目前开测平台的大量真机远控需求.并且minicap的启动会杀掉WDA的test进程,造成两者的启动顺序必须严格控制.给程序增加了不稳定性及操作的复杂性.于是借助iOS开发团队的工程师对WDA代码进行了修改:添加了快速截屏的功能,并增加一个socket子线程(端口号:8888)可以对外传输图片.因此新方案代码修改如下:

1.新增端口映射:iproxy 8888 8888. 用于用于接收手机端的图片传送.多个手机连接时,需要多个PC端口映射到手机端的8888端口.

2.图片数据没有minicap中的全局header,每张图片的数据结构为:

其中Data_length标明后续的Pic_data的数据长度.

3.图片接收及保存,websocket的建立与minicap相同.多台设备连接时,需要根据手机id识别映射的端口,根据其端口收取图片数据和传输操作数据.

两台设备同时操控的效果图如下:

方案对比

优化方案的优势

能够支持一台PC同时连接多台手机,截图功能和操控功能均能够完全独立;

排除minicap对WDA进程的干扰;

优化方案的劣势

WDA截图及传输的速度不如minicap,造成屏幕显示的帧率不如minicap,帧率差别约在30%,在显示效果上会失去一定的流畅度.

参考文献

【藏经阁】iOS多机远程控制技术:

http://www.sohu.com/a/240584209_744135

WebDriverAgent简介:

https://testerhome.com/topics/4904

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档