关于chrome-devtools:iOS-WebViewH5调试新姿势

2次阅读

共计 4356 个字符,预计需要花费 11 分钟才能阅读完成。

前言

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

正文完
 0