iOS WebView/H5调试新姿势

前言

Sonic平台周边生态sib推出新功能webinspector啦!给iOS进行H5测试带来什么不一样的体验呢?往下继续查看吧

sib使用文档

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 · GitHubsonic-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-proxyRemoteDebug/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中。

大体设计

iOS WebView/H5调试新姿势_第1张图片

不同调试协议之间的API差异 概览

iOS WebView/H5调试新姿势_第2张图片

在自己项目应用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就可以啦!

iOS WebView/H5调试新姿势_第3张图片

不过该功能当前还在继续完善,还有很多可以优化的空间,欢迎大家参与建设~

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 https://sonic-cloud.wiki/d/17...

你可能感兴趣的:(chrome-devtools)