转载:https://blog.csdn.net/baidu_37711332/article/details/82584928
时下H5应用很火,微信公众号,微信小程序,支付宝服务窗等,其应用跟PC端的Web应用有共同也有区别之处,但其实H5应用跟pc端的web应用是差不多的,其本质都是web应用,都是要通过浏览器或者Webview浏览器进行操作,只不过H5应用更多的是运行在手机端而不是PC端。由于设备端不一样,H5应用是在手机端,没法像PC端的WEB应用那么简单,所以很多时候,可能是把H5划归到APP自动化进行管理的。既然有这么多共同之处,那么有没有办法把它封装成一种浏览器,归类到Web自动化测试中呢,达到跟WEB UI统一的操作入口?看了思寒的微信Webview自动化测试方法的帖子,给了我灵感,特分享出来
网上流传的H5自动化测试有两种方案,一种是利用PC端谷歌浏览器的设备UA模式,模拟手机浏览器,一种是利用Appium连接手机,进入应用切换到Webview;一种方案是比较简单的,但是没有办法完全模拟手机浏览器的环境,所以采用第二种方法。下面说下具体的过程
一、将apium注册到selenium gird
采用Appium 的方式,Appium Driver启动方式与Webdriver的启动方式略有不同,那么如何达到统一的入口呢?Selenium有一种分布式解决方案Selenium Grid,如果把Appium Server 注册到Selenium Grid hub上就实现了统一的入口了。appium 注册到selenium grid的方法,网上有很多例子,但经过实验发现,有几个地方需要特别注意:
1、注册node节点的时候需指定udid, 2、启动的时候要顺带启动appium 内置的chromedriver,3、appium 地址,grid hub地址不能指定为127.0.0.1,不然其他机器就没办法通过ip进行访问了。下面是我的appium 注册代码:
nodeconfig如下:
{
"capabilities": [
{
"browserName": "chrome",
"version": "5.0.1",
"maxInstances": 1,
"platform": "ANDROID",
"udid":"127.0.0.1:62001",
"deviceName":"127.0.0.1:62001"
}
],
"configuration": {
"cleanUpCycle": 2000,
"timeout":30000,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"hub":"192.168.1.103:4455/grid/register",
"url":"http://192.168.1.103:4723/wd/hub",
"host": "192.168.1.103",
"port": 4723,
"maxSession": 1,
"register": true,
"registerCycle": 5000,
"hubPort": 4455,
"hubHost": "192.168.1.103"
}
}
appium 启动脚本:
appium --address 192.168.1.103 --port 4723 --bootstrap-port 4724 --chromedriver-port 8000 --session-override --nodeconfig D:\auto\appium-node\appium-node.json
二、设计testbase(浏览器启动和关闭)类
原理:由于微信浏览器没有像PC浏览器一样有网址输入口,所以需要通过文件传输助手输入自己设计的网址入口地址(类似hao123入口)
public class TestBaseCase {
public static WebDriver driver;
public static String description;
public Log log=new Log(this.getClass().getSuperclass());
public void setup( String driver,String nodeURL) throws MalformedURLException {
log.info("------------------开始执行测试---------------");
log.info("读取xml配置:浏览器:"+driver+";gridNodeURL:"+nodeURL);
try {
this.driver=setRemoteDriver(driver,nodeURL);
} catch (Exception e) {
log.error("没有成功浏览器环境配置错误");
}
this.driver.manage().window().maximize();
}
@AfterTest
public void tearDown() {
try {
this.driver.close();
this.driver.quit();
}catch (Exception e) {
log.info("android driver 退出需切换会NATIVE_APP");
AndroidDriver androidDriver=(AndroidDriver) driver;
androidDriver.quit();
}
}
private WebDriver setRemoteDriver(String browsername,String nodeURL) throws MalformedURLException
{
switch (browsername)
{
case "FirefoxDriver" :
DesiredCapabilities capabilities=DesiredCapabilities.firefox();
capabilities.setBrowserName("firefox");
capabilities.setPlatform(Platform.WINDOWS);
driver= new RemoteWebDriver(new URL(nodeURL), capabilities);
break;
case "ChormeDriver":
DesiredCapabilities dcchorme=DesiredCapabilities.chrome();
dcchorme.setBrowserName("chrome");
dcchorme.setVersion("46.0.2490.86 m");
dcchorme.setPlatform(Platform.WINDOWS);
driver=new RemoteWebDriver(new URL(nodeURL), dcchorme);
break;
case "WeiXIN":
DesiredCapabilities capability = new DesiredCapabilities();
capability.setCapability("app", "");
capability.setCapability("appPackage", "com.tencent.mm");
capability.setCapability("appActivity", ".ui.LauncherUI");
capability.setCapability("deviceName", "127.0.0.1:62001");
capability.setCapability("fastReset", "false");
capability.setCapability("fullReset", "false");
capability.setCapability("noReset", "true");
capability.setCapability("unicodeKeyboard", "True");
capability.setCapability("resetKeyboard", "True");
//关键是加上这段
ChromeOptions options2 = new ChromeOptions();
options2.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
capability.setCapability(ChromeOptions.CAPABILITY, options2);
//启动微信浏览器
log.info("启动微信浏览器");
driver= new AndroidDriver(new URL(nodeURL), capability);
driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);
sleep(5);
log.info("点击微信搜索菜单");
WebElement webElement=driver.findElement(By.xpath("//*[@content-desc='搜索']"));
webElement.click();
log.info("输入文件字符串");
webElement=driver.findElement(By.xpath("//*[@text='搜索']"));
webElement.click();
webElement.clear();
webElement.sendKeys("文件");
sleep(4);
log.info("点击文件传输助手");
webElement=driver.findElement(By.xpath("//*[@text='文件传输助手']"));
webElement.click();
sleep(8);
log.info("发送跳转网站的网页URL");
webElement= driver.findElement(By.xpath("//*[@resource-id='com.tencent.mm:id/z4']"));//不同微信版本,定位不一样
webElement.sendKeys("http://192.168.1.103:8080/openurl/open.html");
log.info("点击发送按钮");
webElement=driver.findElement(By.xpath("//*[@text='发送']"));
webElement.click();
sleep(3);
log.info("点击网址");
webElement=driver.findElement(By.xpath("//*[@text='"+"http://192.168.1.103:8080/openurl/open.html"+"']"));
webElement.click();
sleep(3);
log.info("切换到微信webView");
//Webdriver转AndroidDriver
AndroidDriver androidDriver=(AndroidDriver) driver;
androidDriver.context("WEBVIEW_com.tencent.mm:tools");
driver=androidDriver;
case "HtmlUnitDriver":
this.driver=new HtmlUnitDriver();
break;
default:
this.driver=new FirefoxDriver();
break;
}
return driver;
}
}
三、设计网址入口网页
<html>
<head>
<meta charset="GBK"/>
<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js">
</script>
</head>
<body style="text-align:center">
<div>
<input id="url" type="text"/>
<input id="openurl" type="button" value="打开网页"/>
</div>
<script>
$("#openurl").click(function(){
var url=$("#url").val();
location.href=url;
}
)
</script>
</body>
</html>
四、设计open方法
//微信浏览器操作
public void openWeiXinBrowser(String url) {
WebElement webElement=driver.findElement(By.id("url"));
log.info("输入网址:"+url);
webElement.sendKeys(url);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
webElement=driver.findElement(By.id("openurl"));
log.info("点击打开网页");
webElement.click();
}
五、设计截图方法
public class ScreenShot {
public WebDriver driver;
private String screenName;
Log log =new Log(this.getClass());
public void setscreenName(String screenName)
{
this.screenName=screenName;
}
public ScreenShot(WebDriver driver)
{
this.driver=driver;
}
private void takeScreenshot(String screenPath) {
try{
scrFile=((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
}catch (Exception e)//关键就在于此
{
//appium 内chrome没法截图,需用原生app下进行截图
System.out.println("进入到了webview 截图需切换回 NATIVE_APP content");
AndroidDriver driver2=((AndroidDriver) driver);//关键就在于此
log.info("contextName:"+driver2.getContext());
System.out.println(driver2.getContextHandles());
// log.info(driver2.getContextHandles().toString());
log.info("切换到NATIVE_APP进行app截图");
driver2.context("NATIVE_APP");
scrFile=((TakesScreenshot) driver2).getScreenshotAs(OutputType.FILE);
log.info("切换回微信webviw");
driver2.context("WEBVIEW_com.tencent.mm:tools");
}
try {
Files.copy(scrFile, new File(screenPath));
log.error("错误截图:"+screenPath);
} catch (Exception e) {
e.printStackTrace();
}
}
public void takeScreenshot() {
String screenName =this.screenName+ ".jpg";
File dir = new File("test-output\\snapshot");
if (!dir.exists())
{dir.mkdirs();}
String screenPath = dir.getAbsolutePath() + "\\" + screenName;
this.takeScreenshot(screenPath);
}
}
到此就完成了微信浏览器入口统一,这里面的坑是AndroidDriver的Contentext方法并没有在Webdriver里定义,而微信截图等很多地方需要切换Contentext才能操作,而要达到入口统一肯定需要通过Webdriver接口作为浏览器的管理;这个坑在网上也没有答案,冥思苦想后终于想出了类型转换的方法,我也是佩服自己能想出接口与实现类之间类型转换的方法。
本文链接:https://my.lmcjl.com/post/12704.html
4 评论