前言
Sonic平台周边生态sib推出新功能webinspector啦!给iOS进行H5测试带来什么不一样的体验呢?往下继续查看吧
iOS web测试基础原理浅谈
当前的主流H5调试,基本上都是基于浏览器开放的debug ws服务来进行的。我们通过连接这些ws,然后发送对应的协议过去,即可达到debug的目的,例如iOS获取elements,则需要按照协议通过ws发送getDocument方法到webkit里面,等待ws server返回对应的element信息。iOS的webkit protocol详细可参考:WebKit/Source/JavaScriptCore/inspector/protocol at main · WebKit/WebKit · GitHub ,里面通过划分域的形式,已经将协议分为主要的20-30个文件。
如何开启iOS web debug服务?
不同于安卓只需要简单的去开发者模式里开启webview的debug模式,iOS由于其封闭性,开启web debug非常麻烦。我们需要发送相关的DTX协议给iOS内置的com.apple.webinspector(参考:sonic-gidevice/webinspector.go at main · SonicCloudOrg/sonic-gidevice · GitHub 、sonic-ios-bridge/src/webinspector at main · SonicCloudOrg/sonic-ios-bridge · GitHub )。
大体流程如下:通过gidevice启动相关的webinspector server方法,随后DTX发送对应的connect id到webinspector,
这时候会返回对应的DTX信息,我们会根据DTX信息的case标志(Selector参数)进行webinspector client的初始化处理。
该过程中会得到当前设备中的webkit应用pid和base page信息(根据一些技术文章,如果iOS的应用有developer证书,则可以开启H5调试,后续开发维护时会进行验证其真实性)。根据这些pid和page信息,当需要对某个webkit应用进行web debug时,创建一个senderid,并将其发送到webinspector中,让webkit开启debug服务,我们只需要发送相关的协议信息就行。
协议兼容
虽然iOS的webkit inspector是发展最早的一个网页调试器,但是由于iOS的封闭性和其他的一些因素,后续的其他内核的浏览器调试并没有使用iOS的webkit调试协议,基于易用性考虑,sonic参考google/ios-webkit-debug-proxy 、RemoteDebug/remotedebug-ios-webkit-adapter 这两个项目,用golang重写了一遍,只需要使用sib的webinspector adapter模式,即可通过chrome devtool简单调试iOS的safari。核心思路是sib将发送协议信息这个关键步骤做成ws服务,采用双向代理的模式,通过SonicCloudOrg/sonic-ios-webkit-adapter 拦截iOS webkit调试协议和Chrome DevTools Protocol协议之间的特异方法,将其转换成双方可接受的调试协议和返回结果。
案例
如果我们需要获取当前页面下导航栏中的历史信息时,Chrome DevTools Protocol的做法是ws里发送Page域中的getNavigationHistory方法到当前调试的应用中,等待返回的结果就行。比较可惜的是,这个方法直接发送到iOS webkit中,iOS webkit会返回信息告知并没有这个方法,不过iOS webkit可以通过曲线救国的方式达到类似的效果。首先,我们先看Chrome DevTools Protocol中getNavigationHistory的返回信息是什么(参考:Chrome Devtools Protocol )
{
"id": "TransitionType",
"description": "Transition type.",
"type": "string",
"enum": [
"link",
"typed",
"address_bar",
"auto_bookmark",
"auto_subframe",
"manual_subframe",
"generated",
"auto_toplevel",
"form_submit",
"reload",
"keyword",
"keyword_generated",
"other"
]
}
{
"name": "getNavigationHistory",
"description": "Returns navigation history for the current page.",
"returns": [
{
"name": "currentIndex",
"description": "Index of the current navigation history entry.",
"type": "integer"
},
{
"name": "entries",
"description": "Array of navigation history entries.",
"type": "array",
"items": {
"$ref": "NavigationEntry"
}
}
]
}
{
"id": "NavigationEntry",
"description": "Navigation history entry.",
"type": "object",
"properties": [
{
"name": "id",
"description": "Unique id of the navigation history entry.",
"type": "integer"
},
{
"name": "url",
"description": "URL of the navigation history entry.",
"type": "string"
},
{
"name": "userTypedURL",
"description": "URL that the user typed in the url bar.",
"type": "string"
},
{
"name": "title",
"description": "Title of the navigation history entry.",
"type": "string"
},
{
"name": "transitionType",
"description": "Transition type.",
"$ref": "TransitionType"
}
]
}
由返回结构可知,最重要的是url和titile(其他信息可自定义生成),所以思路可以这样:
通过中间层拦截到这个特异性的方法,然后将这个方法替换成iOS webkit protocol下Runtime域的evaluate方法(evaluate方法的使用说明参考:iOS webkit protocol Runtime),发送window.location.href,获取全局windows对象下的location.href结果,然后再次使用Runtime域evaluate方法,发送window.title,获取全局windows对象下的title结果,然后按照getNavigationHistory的返回结构组合获取到的这些信息,再返回到devtool中。
大体设计
不同调试协议之间的API差异 概览
在自己项目应用API兼容库
go get -u github.com/SonicCloudOrg/sonic-ios-webkit-adapter
应用方向
通过sib的webinspector adapter功能,不只是sonic的H5,任何基于Chrome DevTools Protocol开发的相关框架都可以用于操作iOS的H5。目前sonic持续维护 SonicCloudOrg/sonic-ios-webkit-adapter 项目,用作iOS H5自动化的底层框架,如auto touch、性能采集等,以及提供给前端一个开源易用的iOS webdebug tool,而如果不使用adapter,则是暴露原生的iOS webkit ws服务,可以通过iOS webkit debug tool工具进行调试(参考: webkit-webinspector ),在后续版本中,我们将会对devtool进行二次开发,完善sonic的H5自动化前端。
在sib中使用
sib webinspector
启动后开启chrome的debug模式
chrome --remote-debug-port=9999
然后打开chrome的devtools工具,远程连接webinspector的调试ws就可以啦!
不过该功能当前还在继续完善,还有很多可以优化的空间,欢迎大家参与建设~
FAQ
-
Q:为什么用golang来写?和ios-webkit-debug-proxy、remotedebug-ios-webkit-adapter有什么区别吗?
-
F:我们使用golang的最大一个原因是其多个平台的兼容性,使用起来不需要额外的配置环境,而且以往的iOS相关H5测试大多需要搭配xcode、Mac环境,但是配合sib使用就可以做到脱离Mac跨平台使用,还摆脱了nodejs的依赖。虽然ios-webkit-debug-proxy项目也是跨平台的,但是其本身使用C语言,项目里有大量指针操作,对于没学过C语言的同学来说这个很折磨人。至于remotedebug-ios-webkit-adapter项目,除了摆脱nodejs以外,其最大问题是作者已经不再维护了,综合考虑之下决定使用golang重写这个项目,便于后期的维护和拓展。
-
Q:使用过程中某个protocol方法不支持怎么办?
-
F:目前项目只是初步完成,还有很多功能未完成,欢迎提issue或pr,也欢迎熟悉Chrome DevTools Protocol协议和iOS webkit debug protocol协议的大佬加入一起维护项目。
-
Q:二次开发chrome devtool的原因是为什么?
-
F:因为在两个协议之间兼容时,sonic很被动,无论是Chrome DevTools Protocol协议还是iOS webkit debug protocol协议发生更改,都导致adapter里需要花费大量的时间进行适配,我们需要提高自身的主动权。
原文来自Sonic wiki iOS WebView/H5调试新姿势 - Sonic - 用户社区