继上篇文章腾讯FAutoTest解读源码写出来之后
这篇文章则是将其中的精华抽出,并引导你如何使用简短的代码,实现FAT的功能。
我们这次用雪球股票这个App当我们的测试项目,直接使用Xposed强行开启项目的WebView Debug模式,如果测试自己的App,并且有开发在旁边也可以让他/她加句法代码
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) {
WebView.setWebContentsDebuggingEnabled(true);
}
在我之前写过的文章 Android WebView研究笔记有提到过Xposed这个应用
:App,点击实盘交易
就进入了WebView接口,WebView接口上的所有内容都不是原生控件了。
使用下面的命令找出雪球的pid
$ adb shell ps | grep xueqiu
u0_a133 4433 566 1634988 264956 SyS_epoll_ 0000000000 S com.xueqiu.android
u0_a133 4510 566 1208020 78048 SyS_epoll_ 0000000000 S com.xueqiu.android:pushservice
然后再执行个命令
$ adb shell cat /proc/net/unix | grep --binary-file=text webview
0000000000000000: 00000002 00000000 00010000 0001 01 1433219 @webview_devtools_remote_4433
这里看到的Android了监听@webview_devtools_remote_4433
其中的4433对应的是雪球的PID(注:名字可能不会这么规范,可能是。webview_devtools_remote_m6x_4433
,也可能是browser_webview_devtools_remote_22091
)
我们接着用亚行向前命令将网页视图调试转发到本地。
$ adb forward tcp:5000 localabstract:webview_devtools_remote_4433
$ curl localhost:5000/json/version
{
"Android-Package": "com.xueqiu.android",
"Browser": "Chrome/62.0.3202.84",
"Protocol-Version": "1.2",
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0.1; SM901 Build/MXB48T; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36",
"V8-Version": "6.2.414.37",
"WebKit-Version": "537.36 (@957d898f0f6e46cd9661d91d2bae899f34c1c4b6)",
"webSocketDebuggerUrl": "ws://localhost:5000/devtools/browser"
}
通过此信息我们也可以确定当前连接的webview devtools确实是雪球的。
接下来访问localhost:5000/json/list
该地址,可以获取到webview所有打开的界面。(访问localhost:5000 / json也可以)
webview就是一个简化修改版的浏览器。每一个页面对应一个标签。
$ curl localhost:5000/json/list
[ {
"description": "{\"attached\":true,\"empty\":false,\"height\":1698,\"screenX\":0,\"screenY\":222,\"visible\":true,\"width\":1080}",
"devtoolsFrontendUrl": "http://chrome-devtools-frontend.appspot.com/serve_rev/@957d898f0f6e46cd9661d91d2bae899f34c1c4b6/inspector.html?ws=localhost:5000/devtools/page/2c1c9bfc-e941-42a9-bfc1-0b1f2f73e553",
"id": "2c1c9bfc-e941-42a9-bfc1-0b1f2f73e553",
"title": "实盘交易",
"type": "page",
"url": "file:///data/user/0/io.va.exposed/virtual/data/user/0/com.xueqiu.android/files/com.xueqiu.android.h5/modules/broker/tradeHome.html",
"webSocketDebuggerUrl": "ws://localhost:5000/devtools/page/2c1c9bfc-e941-42a9-bfc1-0b1f2f73e553"
} ]
因为Chrome DevTools Protocal(CDP)是基于WebSocket协议的,我用门python websocket_client
库来进行下交互。
import websocket
import json
from pprint import pprint
conn = websocket.create_connect("ws://localhost:5000/devtools/page/2c1c9bfc-e941-42a9-bfc1-0b1f2f73e553")
conn.write(json.dumps({"id": 1, "method": "Runtime.evaluate", "params": {"expression": "window.location.toString()"}}))
data = conn.recv()
pprint(data)
# 输出:{"id":1,"result":{"result":{"type":"string","value":"https://-- 一个很长的网址--"}}}
发送的消息格式跟jsonrpc 2.0协议几乎一模一样。
Github的上搜了搜,发现有专门针对铬Devtools协议的写库https://github.com/fate0/pychrome,下面的代码用pychome库重写一下,并加入XPath获取元素的功能
JS如何使用XPath参考了: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_using_XPath_in_JavaScript
import pychrome
import json
browser = pychrome.Browser("http://localhost:5000")
tab = None
for t in browser.list_tab():
t.start()
hidden = t.call_method("Runtime.evaluate", expression="document.hidden")["result"]["value"]
if not hidden: # 页面处于激活状态
tab = t
break
t.stop()
else:
raise RuntimeError("no activated tab")
# 获取 按钮(天气)的中心坐标
ret = tab.call_method("Runtime.evaluate", expression="""
(function(){
var xpath = '//*[contains(text(), "天气")]'
var obj = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
var button = obj.iterateNext();
var rect = button.getBoundingClientRect()
// [rect.left, rect.top, rect.right, rect.bottom]
var x = (rect.left + rect.right)/2
var y = (rect.top + rect.bottom)/2;
return JSON.stringify([x, y])
})
"""
x, y = json.loads(ret['result']['value'])
# 执行点击操作
tab.Input.synthesizeTapGesture(x=x, y=y, duration=200, tapCount=1)
# 等价于 tab.call_method("Input.synthesizeTapGesture", x=x, y=y, duration=200, tapCount=1)
tab.stop()
tab.wait(5) # 等待thread进程退出
到这个地方,我们就实现了通过XPath查找对应空间,然后单击的功能。继续扩展下,说不定能够弄出一个webview测试框架出来。
作者:codeskyblue
原文链接:https://testerhome.com/topics/19461
转载文章时务必注明原作者及原始链接,并注明「发表于 TesterHome 」,并不得对作品进行修改。