很多 apk 会在原生的 app 中内嵌如 web 页面,以减小开发工作量,增加兼容性,所以当我们使用 appium 对此类 apk 进行自动化测试时,就不可避免的会遇到需要在原生应用和 h5 界面中进行切换的操作,下面对这一过程中遇到的问题分别从 android 应用和 ios 应用两个方面进行总结。
方法一:
Set<String>contexts=driver.getContextHandles();
driver.context((String)contexts.toArray()[1]); //选取webview开头的context
方法二(官方示例):
driver.getContextHandles().forEach((handle) -> {
if (handle.contains("WEBVIEW")) {
driver.context(handle);
}
});
使用方法一获取 contexts 时,发现只能获取到原生的 context,不能获取到 WebView 的 context。如下:
经过在网上查找方法,发现 android4.4 以上需要开启 webView 的远程调试开关。方法如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);}
一般情况下 RD 会将上述开关设置在 apk 包中,作为一个 debug 的总开关,此时我们只需要找 RD 要一个开启 debug 模式的 aok 安装包就可以了。
解决了 WebView 上下文的问题之后,以为就可以顺利运行了,没想到还是报错,内容如下:
错误内容是:Chrom version must be >=60.0.3112.0。提示我们谷歌浏览器的版本比较低。
看到这个提示的时候我也很疑惑,我也没有用到 Chrome,为什么会提示这样的错误呢?原因是 android 系统底层是通过 ChromeDriver 来调用 WebView 的。
所以上述错误的原因是因为 ChromeDriver 的版本不匹配导致。那么应该是什么和什么匹配,又应该如何匹配呢?
答案:
需要 android 系统的 Android Sysytem WebView 版本和 ChromeDriver 的版本相匹配。其中 Android Sysytem WebView 是指 android 系统的 web 应用,可以在手机上查看气其当前版本(如果在系统应用中找不到,可以在手机的应用市场上搜索)。
匹配规则如下:其中 “支持的 Chrome 版本” 就是指 Android Sysytem WebView 的版本
相同问题:https://testerhome.com/topics/8493
https://www.cnblogs.com/sao-fox/p/6396984.html
版本匹配:http://blog.csdn.net/cz9025/article/details/70160273
解决方法
既然知道了问题出现的原因,那么就有方法解决。解决方法如下:
查看当前 Android Sysytem WebView 的版本,下载对应的 ChromeDriver,放到如下目录 (mac):
/Applications/Appium 2.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/
在进行 ios 设备的上下文切换时,也出现了无法获取 WebView 的现象(同 android)。一开始也以为 ios 可以通过带代码中设置 webview 的 debug 开关来解决此问题,但是后来和几个 RD 沟通过后发现 ios 并没有类似的支持,所以只能另寻他法。
通过查看 log,发现 ios_webkit_debug_proxy 没有被调起,如果想要真机调试 WebView,就必须通过 ios_webkit_debug_proxy。
通过如下命令进行安装
brew install ios-webkit-debug-proxy
安装之后运行如下命令查看是否能够调起 ios-webkit-debug-proxy
ios_webkit_debug_proxy -c XXXXXXXXXX:27753 -d XXXXXXXXXX表示设备UDID
运行上述命令发现报错如下:
Could not connect to lockdownd. Exiting.: Permission denied
通过查找资料,发现网上大部分的解决方案是执行如下命令:
sudo chmod -R 777 /var/db/lockdown/
但是,执行该命令之后还有可能出现其他问题,并且该命令只能在本期启动 ios-webkit-debug-proxy 时起作用,不能永久生效。
解决方案如下:
brew uninstall ideviceinstaller
brew uninstall libimobiledevice
brew install --HEAD libimobiledevice
brew link --overwrite libimobiledevice
brew install ideviceinstaller
brew link --overwrite ideviceinstaller
过程中如果出现失败的现象,可以根据 log 的提示进行处理。
经过上述处理,已经解决了 ios-webkit-debug-proxy 无法启动的问题,但是 appium 如何获取 WebView 上下文的问题仍然存在。
解决方法就是先启动 ios-webkit-debug-proxy,在调用 appium 的自动化脚本,就可以获取 WebView 了。
注意:ios 真机需要启动 web 检查器
位置:设置—》Safari—》高级—》web 检查器
注意:在获取 WebView 之前,最后先 Thread.sleep(1000) 几秒,保证 apk 中内嵌的 WKWebView 已经加载出来。
解决上述问题之后,如果直接运行测试脚本会报出如下错误:
是因为我没没有开启 ios-webkit-debug-proxy。而每次手动开启 ios-webkit-debug-proxy 是一件很麻烦的事情,我们作自动化的目的就是解放双手嘛。
后来阅读了官方的解释之后,发现 ios-webkit-debug-proxy 可以通过设置 DesiredCapabilities 来调起,代码如下:
cap.setCapability("startIWDP",true);
好啦,至此,我的 ios 设备和 android 设备都能够完美兼容 WebView 啦