Appium Hybrid混合应用测试——Native切换WebView
- Appium Hybrid混合应用测试过程中,经常需要在Native和WebView之间进行切换;
1.切换至WEBVIEW操作;
for cons in driver.contexts:
if cons.lower().startswith("webview"):
driver._switch_to.context(cons)
break
# 或 cons = driver.contexts # 获取上下文列表
driver._switch_to.context(cons[-1])
2.切换至NATIVE_APP操作;
driver._switch_to.context("NATIVE_APP")
- 切换WebView时遇到两个问题,导致无法进行WebView切换:
【问题1 contexts只能获取NATIVE_APP,无法获取WEBVIEW】
使用uiautomatorviewer定位元素,显示class值为:android.webkit.WebView
但是driver.contexts只打印出了‘NATIVE_APP’;
>>> driver.contexts
['NATIVE_APP']
【解决方案】
需要开启webview远程调试功能, Android 4.4以上,需要在应用代码中增加一下代码段开启该功能 (可由开发人员增加后重新打包给测试):
修改Activity extends CordovaActivity,设置setWebContentsDebuggingEnabled(true);
public class MyActivity extends CordovaActivity {
CordovaWebView cwv;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
this.appView.setWebContentsDebuggingEnabled(true);
}
// Set by <content src="index.html" /> in config.xml
loadUrl(launchUrl);
}
}
开启WebView远程调试功能后,重新打印contexts,成功!
>>> driver.contexts
['NATIVE_APP', 'WEBVIEW_com.sxxxxx.xxx']
【问题2 已经能够获取到WEBVIEW,但是无法切换到WEBVIEW】
查看Appium
# 发送contexts命令
> info: --> GET /wd/hub/session/c759114f-617f-461b-8341-91ca1d25515c/contexts {}
> info: [debug] Getting a list of available webviews
> info: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe -s f825d6cd shell "cat /proc/net/unix"
> info: [debug] WEBVIEW_16429 mapped to pid 16429
> info: [debug] Getting process name for webview
> info: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe -s f825d6cd shell "ps"
> info: [debug] Parsed pid: 16429 pkg: com.package.name
> info: [debug] from: u0_a256,16429,502,1975592,128716,ffffffff,00000000,S,com.package.name
> info: [debug] returning process name: com.package.name
> info: [debug] Available contexts:
> info: [debug] ["WEBVIEW_com.package.name"]
> info: [debug] Available contexts: NATIVE_APP,WEBVIEW_com.package.name
# 此处显示已成功将contexts响应给client,["NATIVE_APP","WEBVIEW_com.package.name"]
> info: [debug] Responding to client with success: {"status":0,"value":["NATIVE_APP","WEBVIEW_com.package.name"],"sessionId":"c759114f-617f-461b-8341-91ca1d25515c"}
> info: <-- GET /wd/hub/session/c759114f-617f-461b-8341-91ca1d25515c/contexts 200 395.699 ms - 112 {"status":0,"value":["NATIVE_APP","WEBVIEW_com.package.name"],"sessionId":"c759114f-617f-461b-8341-91ca1d25515c"}
> info: --> POST /wd/hub/session/c759114f-617f-461b-8341-91ca1d25515c/context {"sessionId":"c759114f-617f-461b-8341-91ca1d25515c","name":"WEBVIEW_com.package.name"}
> info: [debug] Getting a list of available webviews
> info: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe -s f825d6cd shell "cat /proc/net/unix"
> info: [debug] WEBVIEW_16429 mapped to pid 16429
> info: [debug] Getting process name for webview
> info: [debug] executing cmd: D:\Android\sdk\platform-tools\adb.exe -s f825d6cd shell "ps"
> info: [debug] Parsed pid: 16429 pkg: com.package.name
> info: [debug] from: u0_a256,16429,502,1975592,128716,ffffffff,00000000,S,com.package.name
> info: [debug] returning process name: com.package.name
> info: [debug] Available contexts: NATIVE_APP,WEBVIEW_com.package.name
> info: [debug] ["WEBVIEW_com.package.name"]
> info: [debug] Available contexts: NATIVE_APP,WEBVIEW_com.package.name
# 开始调用启动Chromedriver
> info: [debug] Connecting to chrome-backed webview
> info: Chromedriver: Changed state to 'starting'
> info: Chromedriver: Set chromedriver binary as: D:\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe
> info: Chromedriver: Killing any old chromedrivers, running: FOR /F "usebackq tokens=5" %a in (`netstat -nao ^| findstr /R /C:"9515 "`) do (FOR /F "usebackq" %b in (`TASKLIST /FI "PID eq %a" ^| findstr /I chromedriver.exe`) do (IF NOT %b=="" TASKKILL /F /PID %a))
> info: Chromedriver: No old chromedrivers seemed to exist
> info: Chromedriver: Spawning chromedriver with: D:\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe --url-base=wd/hub --port=9515
> info: Chromedriver: [STDOUT] Starting ChromeDriver 2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a) on port 9515
> Only local connections are allowed.
> info: JSONWP Proxy: Proxying [GET /status] to [GET http://127.0.0.1:9515/wd/hub/status] with no body
> info: JSONWP Proxy: Got response with status 200: "{\"sessionId\":\"\",\"status\":0,\"value\":{\"build\":{\"version\":\"alpha\"},\"os\":{\"arch\":\"x86_64\",\"name\":\"Windows NT\",\"version\":\"10.0\"}}}"
> info: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.package.name","androidUseRunningApp":true,"androidDeviceSerial":"f825d6cd"}}}
> info: JSONWP Proxy: Got response with status 200: {"sessionId":"448c057dd8e679591a99e539a6485d45","status":13,"value":{"message":"unknown error: Device f825d6cd is not online\n (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d...
> info: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.package.name","androidUseRunningApp":true,"androidDeviceSerial":"f825d6cd"}}}
> info: JSONWP Proxy: Got response with status 200: {"sessionId":"a2c6259b846570c32fa66f07b8e663ba","status":13,"value":{"message":"unknown error: Device f825d6cd is not online\n (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d...
> info: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.package.name","androidUseRunningApp":true,"androidDeviceSerial":"f825d6cd"}}}
> info: JSONWP Proxy: Got response with status 200: {"sessionId":"44a889342086cf78ea724e48b0958960","status":13,"value":{"message":"unknown error: Device f825d6cd is not online\n (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d...
> info: JSONWP Proxy: Proxying [POST /session] to [POST http://127.0.0.1:9515/wd/hub/session] with body: {"desiredCapabilities":{"chromeOptions":{"androidPackage":"com.package.name","androidUseRunningApp":true,"androidDeviceSerial":"f825d6cd"}}}
> info: JSONWP Proxy: Got response with status 200: {"sessionId":"66c261de9b5c1919eee22072feb2fa2e","status":13,"value":{"message":"unknown error: Chrome version must be >= 43.0.2357.0\n (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb51...
# Chromedriver开始报错!
> error: Chromedriver: Chromedriver exited unexpectedly with code null, signal SIGTERM
> info: Chromedriver: Changed state to 'stopped'
> warn: Chromedriver for context WEBVIEW_com.package.name stopped unexpectedly
> warn: Chromedriver quit unexpectedly, but it wasn't the active context, ignoring
# 此处报了重要的错误信息:Chrome version must be >= 43.0.2357.0,chromedriver=2.18.343845
> error: Chromedriver: Error: An unknown server-side error occurred while processing the command. (Original error: unknown error: Chrome version must be >= 43.0.2357.0
> (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a),platform=Windows NT 10.0 x86_64))
> at JWProxy.command$ (lib/proxy.js:133:15)
> at tryCatch (D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\regenerator\runtime.js:67:40)
> at GeneratorFunctionPrototype.invoke [as _invoke] (D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\regenerator\runtime.js:315:22)
> at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\regenerator\runtime.js:100:21)
> at GeneratorFunctionPrototype.invoke (D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\regenerator\runtime.js:136:37)
> at bound (domain.js:284:14)
> at GeneratorFunctionPrototype.runBound (domain.js:297:12)
> at run (D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\node_modules\core-js\library\modules\es6.promise.js:89:39)
> at D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\node_modules\core-js\library\modules\es6.promise.js:100:28
> at flush (D:\Appium\node_modules\appium\node_modules\appium-chromedriver\node_modules\appium-jsonwp-proxy\node_modules\babel-runtime\node_modules\core-js\library\modules\$.microtask.js:17:13)
> at process._tickDomainCallback (node.js:381:11)
> { [Error: An unknown server-side error occurred while processing the command. (Original error: unknown error: Chrome version must be >= 43.0.2357.0
> (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a),platform=Windows NT 10.0 x86_64))]
> status: 13,
> value: { message: 'unknown error: Chrome version must be >= 43.0.2357.0\n (Driver info: chromedriver=2.18.343845 (73dd713ba7fbfb73cbb514e62641d8c96a94682a),platform=Windows NT 10.0 x86_64)' },
> httpCode: 200 }
webview控件使用的是Android自带的chrome内核,那么来看看手机自带的chrome内核版本吧;
设置>应用程序管理>全部,查找到Android System WebView应用,查看详情,显示版本号:42.0.2311.138
由此可知,Android系统自带的chrom内核版本过低,造成报错;
【解决方案】
知道了报错原因,那么来进行问题解决吧。
方案1:
根据报错信息要求的版本,下载更新Android System WebView;
方案2:
从报错信息得知Appium使用的chromedriver=2.18.343845
查看ChromeDriver官网,得知ChromeDriver2.18支持Chrome 44+
So,我们可以更新下载对应版本的ChromeDriver.exe替换D:\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win\chromedriver.exe
注:
双击执行“chromedriver.exe”,可以查看版本driver版本号;
Appium Hybrid混合应用测试——Native切换WebView的更多相关文章
- Appium Hybrid混合应用测试——Native切换WebView , 切换不了WebView (没有试过,先记录在此)
Appium Hybrid混合应用测试过程中,经常需要在Native和WebView之间进行切换: 1.切换至WEBVIEW操作: for cons in driver.contexts: if co ...
- Appium解决native+webview混合型APP(公众号、小程序)切换webview后元素无法定位问题
问题:最近在做一个安卓+H5混合开发的APP自动化测试,发现在从native切换到webview后,元素仍然无法找到,报错:no such element 思路:于是思考webview会不会像web页 ...
- Appium 学习二:切换Webview
由于测试的APP是混合应用,即包含了原生代码和web网页. 混合应用在应用程序中嵌入了Webview,Webview是用来访问网页的一个控件.Webview内核也分为原生和第三方(比如腾讯X5内核) ...
- 基于webview的Hybrid app和React Native及html5
基于webview的Hybrid app和React Native及html5 React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iO ...
- Appium混合应用测试
Appium测试混合应用 混合应用即是原生应用中间混着html页面,需要在两种类型的页面之间跳转. 测试Android混合应用 前期设置 4.4以下版本使用automationName:Selendr ...
- native和webview切换
native和webview 标签(空格分隔): native和webview 现在目前大部分的app都是native和webview混合,对应的native上的元素可以通过uiautomatorvi ...
- Appium切换webview时候报chromedriver版本问题
前言 用appium切换webview的时候报chrome和chromedriver版本的问题:session not created exception: Chrome version must b ...
- Appium 解决微信公众号、小程序切换 webview 后无法定位元素的问题
如何切换webview进入小程序请参考https://testerhome.com/topics/12003 脚本思路:进入webview后会存在多个handle同Web页签一样,获取所有的handl ...
- Hybrid App 和 React Native 开发那点事
简介:Hybrid App(混合模式移动应用)开发是指介于Web-app.Native-App这两者之间的一种开发模式,兼具「Native App 良好用户交互体验的优势」和「Web App 跨平台开 ...
随机推荐
- "远程服务器返回错误: (500) 内部服务器错误"错误处理
公司购买的百傲瑞达一卡通软件,提供Restful API调用,使用SoapUI能够调用成功,但在C#里用代码调用时一直报错:"远程服务器返回错误: (500) 内部服务器错误" 找 ...
- double保留两位小数
public static String format(double dValue, int lScale) { // ////负数,则装化为正数后进行四舍五入 boolean bFlag = fal ...
- Python 进程间数据交互
进程间通信:进程之间必须需要中间件. 不同进程间内存是不共享的,要想实现两个进程间的数据交换 Queues:实现传输两个进程的数据 线程queue,访问数据只能在一个进程内进行线程与线程之间的 ...
- 【题解】Luogu P3931 SAC E#1 - 一道难题 Tree
原题传送门 题目几乎告诉你要用最大流 先进行搜索,将树的叶子节点都连到一个虚拟点T上,流量为inf(这样不会干扰到前面部分的最大流) 其他边按树的形态连边,以根节点为S,跑一变最大流即可求出答案 #i ...
- jsp传Array数组到后台
jsp页面传递对象数组到后台的需求 JSP: //保存 $("#submitBtn").click(function(){ var flag = true; var eachfla ...
- [c/c++] programming之路(24)、字符串(五)——字符串插入,字符串转整数,删除字符,密码验证,注意事项
1.将字符串插入到某位置(原字符串“hello yincheng hello cpp hello linux”,查找cpp,找到后在cpp的后面插入字符串“hello c”) 需要用到strstr字符 ...
- ant_<target>标签含义与使用
<target>标记目标 目标是一个或多个任务的集合,任务是一段可执行的代码:构建文件中包含一个项目,在项目内部声明了所有目标: <target name = "run&q ...
- [转载]Black-Scholes 模型中 d1,d2 是怎么得到的?如何理解 Black-Scholes 模型?
https://www.optbbs.com/thread-253244-1-1.html
- ORM查询条件
模板: from django.db import models class Article(models.Model): title = models.CharField(max_length=20 ...
- C#以太坊基础入门
在这一部分,我们将使用C#开发一个最简单的.Net控制台应用,来接入以太坊节点,并打印 所连接节点旳版本信息.通过这一部分的学习,你将掌握以下技能: 如何使用节点仿真器 如何在命令行访问以太坊节点 如 ...