Hybrid应用自动化
webview
- Android系统控件
- 用来展示web页面
- 在系统中作为单独的系统应用存在(特殊)
基于UIAutomator+ChromeDriver
native部分走UIAutomator,webview部分走Chromedriver,两者结合混搭,从而实现Hybrid自动化
准备工作
- Step1:准备android 4.4+版本以上的手机/模拟器
- Step2:在app源码中将webview调试模式打开--请开发帮忙去打开webview.setWebContentsDebuggingEnabled(true);
- Step3:安装UC开发者工具 (这是它的官网:https://dev.ucweb.com/)--识别App内嵌的web页面元素的,识别webview版本,识别web页面元素
- Step4:下载webview对应匹配的chromedriver
chromeDriver下载地址:https://npm.taobao.org/mirrors/chromedriver
替换Appium自带的chromeDriver:
Appium.exe所在路径\resources\app\node_modules\appium\node_modules\appium
chromedriver\chromedriver\win
脚本编写
- Step1:识别 - webview视图
- Step2:获取所有的contexts:driver.getContextHandles();
- Step3:切换 - 切换到webview视图:driver.context(webview视图);
- Step4:定位 - 定位webview中的元素,并执行操作:web网页元素定位和操作。
- Step5:切换 - 切换回默认的视图:driver.context(native视图)
理解Context
- 在程序中context我们可以理解为当前对象在程序中所处的一个环境/状态
- native界面和webview界面分属于不同的context,前者基于Andriod原生控件,后者是Web网页
- native默认是”NATIVE_APP”,webview则默认是”WEBVIEW_被测进程名称”
- 两者的运行环境不同因此需要进行上下文(context)切换
Set<String> contextNames = driver.getContextHandles();
for (String contextName : contextNames) {
// 用于返回被测app是NATIVE_APP还是WEBVIEW,如果两者都有就是混合型App
System.out.println(contextName);
if(contextName.contains("WEBVIEW")){
// 让appium切换到webview模式以便查找web元素
driver.context(contextName);
System.out.println("切换到webview:"+contextName);
}
}
实例:从native页面切换到web页面
//获取当前context
System.out.println("进入到apple社区之前的:"+driver.getContextHandles());
//点击主页上的apple社区
driver.findElement(MobileBy.AndroidUIAutomator("new UiSelector().text(\"apple社区\")")).click();
Thread.sleep(3000);
//NATIVE_APP 原生页面对应的context(模式名)
//WEBVIEW_com.apple.apple2 web页面对应的context
System.out.println("进入到apple社区之后的:"+driver.getContextHandles());
//App自动化代码执行默认是用的native模式,如果要定位web页面的元素信息,就必须要切换到web模式下
//重点:切换context
driver.context("WEBVIEW_com.apple.apple2");
//定位web元素信息
//driver.findElement(By.xpath("//a[text()='注册']")).click();
driver.findElement(By.xpath("//a[@href='http://shoppingarea.com/login' and @class='index-bottom__item']")).click();
// //a[@href='http://shoppingarea.com/login' and @class='index-bottom__item']
driver.findElement(By.id("name")).sendKeys("13230567889");
driver.findElement(By.id("Password")).sendKeys("23456");
driver.findElement(By.id("Login")).click();