Appium+java+Android 六(进入微信小程序之-NATIVE_APP切换webview页面(context))

2018.12.28上午 博主苟延残喘中,可能会上演从入门到放弃
2018.12.28下午,博主终于解决了困扰了整整一天的问题,不会表演从入门到放弃了,那么这个问题是啥呢?就是切换context出现了问题。
由于博主要做的是小程序的自动化测试,由于微信有很多个小程序,每个小程序的进程都不同,所以我们首先要查看当前小程序是在哪个进程中。只有知道小程序在哪个进程之后才能切换到当前进程中,而如何切换呢?就用context来切换了。

一.查看当前小程序的进程

手机打开小程序,电脑命令行输入adb shell dumpsys activity top| findstr ACTIVITY
然后输入adb shell +刚刚得到的数字
就可以得到当前进程名
在这里插入图片描述

二.进入小程序

我贴代码了

private AppiumDriver appiumDriver;

@BeforeClass
public void setcapability() throws MalformedURLException {
	
//com.tencent.mm:appbrand0
DesiredCapabilities cap=new DesiredCapabilities();


cap.setCapability(CapabilityType.BROWSER_NAME, "");
cap.setCapability("platformName", "Android"); // 指定测试平台
cap.setCapability("deviceName", "RSY5LZ89F67SJZYT"); // 指定测试机的ID,通过adb命令`adb devices`获取
cap.setCapability("platformVersion", "5.1");//指定手机的安卓版本
cap.setCapability("recreateChromeDriverSessions", true);
cap.setCapability("autoWebview", true);

//ChromeOptions使用来定制启动选项,因为在appium中切换context识别webview的时候,把com.tencent.mm:toolsmp的webview识别成com.tencent.mm的webview.
//所以为了避免这个问题,加上androidProcess名

ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand0");
cap.setCapability(ChromeOptions.CAPABILITY, options);

//初始化会默认将chrome浏览器打开,需要将Browser置为空
cap.setBrowserName("");
cap.setCapability("unicodeKeyboard", "True");// 使用Unicode输入法,默认 false
cap.setCapability("resetKeyboard", "True");// 在使用了unicode输入法测试结束后,重置输入法到原有状态。如果单独使用,将会被忽略。默认值 false

// 每次启动时覆盖session,否则第二次后运行会报错不能新建session
cap.setCapability("sessionOverride", true);

// 将上面获取到的包名和Activity名设置为值
		cap.setCapability("appPackage", "com.tencent.mm");
		cap.setCapability("appActivity", "com.tencent.mm.ui.LauncherUI");
		
		// A new session could not be created的解决方法
		cap.setCapability("appWaitActivity", "com.tencent.mm.ui.LauncherUI");

appiumDriver = new AndroidDriver(new URL("http://10.10.1.111:4723/wd/hub"), cap);

}

@Test
public void plus() throws Exception {
	// 休眠一下
	Thread.sleep(5000);
	// 找到微信的发现并点击
	appiumDriver.findElementByName("发现").click();
	// 点击发现里面搜一搜
	Thread.sleep(5000);
	appiumDriver.findElementByName("搜一搜").click();

	Thread.sleep(2000);

	// 点击搜索框
	appiumDriver.findElement(By.id("com.tencent.mm:id/ht")).click();
	appiumDriver.findElement(By.id("com.tencent.mm:id/ht")).sendKeys("猜歌王");

	Thread.sleep(3000);

	// 点击搜索结果中的猜歌王(采用adb命令坐标点击的方式)
	Runtime.getRuntime().exec("adb shell input tap 400 400");//需要算出屏幕的宽和高
	System.out.println("1");

	Thread.sleep(4000);

	// 点击猜歌王小程序
	Runtime.getRuntime().exec("adb shell input tap 400 750");
	System.out.println("2");

	// 等待小程序加载完成
	Thread.sleep(10000);

	// 获取到所有的contexts
	System.out.println("所有的contexts:" + appiumDriver.getContextHandles());

	// 切换到小程序webview对应的context中
	switchToWindow("WEBVIEW_com.tencent.mm:appbrand0",appiumDriver);
	System.out.println("3");
	Thread.sleep(2000);

	// 获取到所有的handles
	
	Set<String> windowHandles = appiumDriver.getWindowHandles();
	System.out.println("所有的windowsHandles" + windowHandles);
	
	// 遍历所有的handles,找到当前页面所在的handle:如果pageSource有包含你想要的元素,就是所要找的handle
	// 小程序的页面来回切换也需要:遍历所有的handles,切换到元素所在的handle
	for (String windowHandle : windowHandles) {
	    System.out.println("切换到对应的windowHandle:" + windowHandle);
	    appiumDriver.switchTo().window(windowHandle);
	    Thread.sleep(2000);
	    if (appiumDriver.getPageSource().contains("排位赛")) {
	    	System.out.println("4");
	        break;
	    }
	}
  System.out.println("5");



@AfterClass
public void tearDown() throws Exception {
	
	Thread.sleep(5000);
	appiumDriver.quit();
}

/**
* Switch to NATIVE_APP or WEBVIEW
* @param sWindow window name
*/
private void switchToWindow(String sWindow,AppiumDriver driver) {
       Set<String> contextNames = driver.getContextHandles();
       for (String contextName : contextNames) {
              if (contextName.contains(sWindow)) {
                      driver.context(contextName);
                      break;
               }
       }
}}

注意,如果想要从webview页面再切换回nativeapp页面的话,只要再加入一行代码:appiumDriver.context(“NATIVE_APP”);
要从nativeapp页面再回到刚刚的webview页面的话,就加入这一行代码:
appiumDriver.context(“WEBVIEW_com.tencent.mm:tools”);
demo:
在这里插入图片描述
接下来我详细讲一下我遇到的问题

三.切换context报错(两种类型错误)

1.如果你和我一样代码没有问题,但就是卡在这里执行不下去,建议你去看看你的appium日志。我的截图是这样的
在这里插入图片描述
这时候你可以往下面翻一下,会看到这么两句话:

(Session info: chrome=57.0.2987.132)
(Driver info: chromedriver=2.18.343845

这里对应的就是你的ChromeDriver和Chrome的版本
接下来我们看一下Chromedriver和Chrome对应的参照表
在这里插入图片描述
可以看出57版本的Chrome支持的是2.28版本的Chromedriver,与我安装的不一致,这时候就需要去换Chromedriver的版本了。
首先我们先在appium的安装路径中找到自带的Chromedriver,一般在D:\Appium\Appium\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win 中。找到之后双击查看自己的版本,这里我已经换完了。
在这里插入图片描述
如果没换的话是可以看到版本是不对应的。于是我们下载与Chrome对应的版本进行替换。下载地址在这:
Chromedriver各版本下载地址
找到对应的版本替换掉原来的Chromedriver就可以啦。
再重新运行代码,就发现程序可以正常运行啦。

2.第2种错误就是遍历所有的context只有一个nativeapp
在这里插入图片描述
如果你确实也打开了小程序和其他进程的话,那么可以尝试微信重新打开debug一下。具体微信如何debug,我在这篇博客里有提到
如何打开微信debug调试
祝你们好运。
3.如果你们后面遍历handle只有一个的话,有可能是handlecontext不对,重新在命令行里面查看一下当前进程。

猜你喜欢

转载自blog.csdn.net/qq_38941812/article/details/85318854