Android 7.0 +Appium 1.6.3
我们一个 app 里面除了 native 页面,还有 H5 页面,那么其实小程序也不过是正常的webview(webview 是一个基于 webkit 引擎、展现 web 页面的控件),本质还是H5(H5 是 HTML5 的简称)。我们对 app 做 UI 自动化时,可以操作 app 的 H5 页面,那么同样的我们也可以操作微信 app 的小程序。
app 里面可以打开一个 webview,webview 中加载 H5 页面,即包含关系是:app > webview > H5。
通过在微信中点击打开http://debugx5.qq.com
,或者直接扫下面二维码
,进入微信 X5 调试页面的配置
点击信息,然后勾选【打开 TBS 内核 Inspector 调试功能】
打开后我们对于微信就有更多的操作性,在chrome://inspect/#devices
中也能看到更多的页面
手机连接电脑,终端输入:adb devices,查看是否连接成功。如下展示设备号则为连接成功
进入小程序,以【天天连连线】为例,在 Chrome 浏览器访问chrome://inspect/#devices
(温馨提示:需要 *** 才能查看页面元素)
有没有小伙伴想问 57.0.2987.132 是什么意思,这是android system Webview的版本。android system Webview是安卓的一个浏览器内核,手机上的应用可以通过调用它来直接显示网页内容。那么对我们有什么影响吗,我们可以把它当成我们的 Chrome 浏览器版本 chrome=57.0.2987.132,它要跟我们的 chromedriver 版本对应 (如果不对应会导致上下文切换失败,无法进行后面的操作),我们才能正常操作 webview。我们可以理解为 appium 会调 chromedriver,chromedriver 去调 android system Webview,最后 android system Webview 可以控制我们小程序的 webview。
上面两张图好像是一个页面,但是显示不一样?左边的图是 macaca 的 app-inspector 中的,它显示的跟我手机页面一致,右边是 Chrome 的 inspect 页面,地址是:https://servicewechat.com/wxbc6682586d0990ea/14/page-frame.html
,即是个 HTML 页面。所以如果小程序页面中用 native 写出来的控件,在 Chrome 的 inspect 页面是显示不出来的,因为它只显示 HTML 元素,也支持我们定位 HTML 元素。左边的 macaca 的 app-inspector 对于 native 元素的定位是肯定没问题的,但是如果有些 HTML 元素我们用 app-inspector 不好定位时,可以选择 Chrome 的 inspect。
微信里面的小程序多不胜数,不同的小程序可能运行在不同的进程中。我们知道 app 的页面层会分 native 和 webview,像上一张图中,小程序 webview 页面地址https://servicewechat.com/wxbc6682586d0990ea/14/page-frame.html
后缀是 html,即是一个 webview。我们使用 appium 做 UI 自动化时默认上下文是NATIVE_APP。
adb shell dumpsys activity top | grep ACTIVITY
adb shell ps 23498
我们可以看到,当前的小程序运行在com.tencent.mm:appbrand0
中,记住这个进程,记住啦。
appium 控制小程序,跟我们正常不同的一点就是:需要添加chromeoptions,值为{'androidProcess': 'com.tencent.mm:appbrand0'}
,androidProcess的值就是com.tencent.mm:appbrand0
,即小程序的进程。
附:python 写的一个简单 demo
from appium import webdriver
desired_caps = {
'platformName': 'Android',
'fastReset': 'false',
'noReset': True,
'platformVersion': '7.0',
'deviceName': '58d1a05c',
'appPackage': 'com.tencent.mm',
'appActivity': 'com.tencent.mm.ui.LauncherUI',
'fullReset': 'false',
# 'unicodeKeyboard': 'True',
# 'resetKeyboard': 'True',
'chromeOptions': {
'androidProcess': 'com.tencent.mm:appbrand0'
}
}
driver = webdriver.Remote('http://0.0.0.0:4723/wd/hub', desired_caps)
driver.find_element_by_android_uiautomator('text("微信")').click() #点击微信Tab
# 定义一个滑动屏幕的方法
def swipeDown(t):
x = driver.get_window_size()['width']
y = driver.get_window_size()['height']
x1 = int(x * 0.5) # x坐标
y1 = int(y * 0.25) # 起始y坐标
y2 = int(y * (0.25 + t)) # 终点y坐标
driver.swipe(x1, y1, x1, y2, 500)
swipeDown(0.4) # 向下滑动屏幕的40%,准备从顶部进入小程序
driver.find_element_by_android_uiautomator('text("天天连连线")').click() #点击顶部的图标进入小程序
print driver.contexts # 打印当前所有的上下文
# [u'NATIVE_APP', u'WEBVIEW_com.tencent.mm:appbrand0', u'WEBVIEW_com.tencent.mm:support', u'WEBVIEW_com.tencent.mm:tools', u'WEBVIEW_com.tencent.mm:appbrand1']
driver.switch_to.context('WEBVIEW_com.tencent.mm:appbrand0') #切换上下文为WEBVIEW_com.tencent.mm:appbrand0
driver.find_element_by_xpath("/html/body/wx-view/wx-view[4]/wx-form/span/wx-button").click() # 这个是HTML页面的元素
最后关于 switch_to.context 上下文切换的问题,我想说一下的就是,最开始自己用的一个乐视超级手机,想操作 webview 页面,切换上下文偶尔切换成功,这个偶尔很致命,找了很久没找到原因,然后不经意间换了一台小米手机,代码没变,但切换失败?不存在的。
还有就是自己看过不少 appium 操作 webview 的文章,基本都是说操作 webview 前要切换上下文,有些说划重点说不需要切换 webview,我亲身感受是,是的,有些 webview 元素不切换也可以操作,但是有些 webview 不切换就操作不了,坑挺多的。建议就是操作 H5 前首先确认chromedriver 版本对应,不切上下文能操作就不切 (因为个人觉得 native 稳定一点),切了上下文还不好使,那就换手机试试吧。
欢迎交流指正,感谢阅读。