Appium系列|测试脚本实现 (五)

2019-07-24 09:44:07 浏览数 (1)

WebView操作

这节课我们会来介绍下WebView的操作,之前我们介绍的都是原生控件的操作,WebView和其他原生控件的操作有点差别,WebView里面包含的控件用之前的定位方式没办法直接定位到,需要借助其他工具来查看其里面具体控件的定位方式,然后通过xpath或css定位方式来进行WebView里面控件的定位。

那么什么样的控件是WebView控件呢,可以打开开源中国应用,然后点击进入资讯详情页面,打开uiautomatorviewer工具查看下,如果控件类型是android.webkit.WebView的控件就是WebView控件,如下所示:

包含WebView这里面的子控件用之前的定位方式不好定位到,这时候可以打开谷歌浏览器,然后输入chrome://inspect

然后点击下图所示的inspect按钮

在出现的页面点击下图所示的有个箭头的按钮,然后在窗口左侧点击想定位的地方,接着右侧html代码视图里就会自动定位到你在左侧所选的控件,然后鼠标右键选择Copy Xpath,就可以获得你想定位的控件的xpath了,我们就可以通过这个路径来进行webview里面子控件的定位

如果这个工具不可以用,看下你是否符合它所要求的如下的几个前置条件:

在具体编写WebView操作之前我们需要来添加几个WebView处理的方法,WebView需要想进行句柄切换,切换完才能进行WebView内的操作,我们在Helper添加如下方法:

代码语言:javascript复制
 //webview相关操作的API
    //通过xpath定位
    public WebElement findByXpath(String xpath){
        return driver.findElementByXPath(xpath);
    }
    
    //获取当前的句柄
    public Set<String> getContextHandlers(){
        return driver.getContextHandles();
    }
    
    //切换执行环境
    public void content(String name){
        driver.context(name);
    }

因为切换webview句柄的方法很多测试脚本都会使用到,这时候可以在PageCommon里添加如下方法:

代码语言:javascript复制
    public void switchToWebView(){
        Set<String> handlers = helper.getContentHandlers();
        for(String handler : handlers){
            System.out.println("===============" handler);
        }
        helper.content("XXXA");
    }

    public void switchToNative(){
        helper.content("XXXB");
    }

上面的切换到WebView句柄或者原生的句柄的字符串我们还不能知道是什么,先用"XXXA"和"XXXB"设置下去,等下在测试脚本里先调用下switchToWebView方法,在这个方面里会输出当前的所有句柄,然后我们在根据输出的内容来替换这两个参数值。

这时候可用新建一个测试类WebViewTest来进行WebView操作的示例,编写如下测试代码:

代码语言:javascript复制
import appium.common.BasicTestCase;
import org.testng.annotations.Test;

public class WebViewTest extends BasicTestCase {

    @Test
    public void testWebView() throws Exception {
        //点击首页第1行
        pageHelper.getPageNews().clickNewsItem(2);
        Thread.sleep(3000);
        pageHelper.getPageCommon().switchToWebView();
    }
}

执行下这个脚本,然后看下控制台输出:

得到WebView和native的句柄后更新PageCommon为如下所示:

代码语言:javascript复制
  public void switchToWebView(){
        Set<String> handlers = helper.getContentHandlers();
        for(String handler : handlers){
            System.out.println("===============" handler);
        }
        helper.content("WEBVIEW_net.oschina.app");
    }

    public void switchToNative(){
        helper.content("NATIVE_APP");
    }

假设我们需要获取第一段的内容,可以在PageNewsDetail添加如下两个方法:

代码语言:javascript复制
    //根据传递的xpath查找第一段的控件
    public WebElement getWebViewFirstLine(String xpath){
        return helper.findByXpath(xpath);
    }

    //获取第一段控件的内容
    public String getWebViewFirstLineContent(String xpath){
        return helper.getText(getWebViewFirstLine(xpath));
    }

然后通过Chrome inspect得到的XPath为:/html/body/div/p[1](这个值根据上面介绍的方法更新成你自己取到的值),编写如下代码:

代码语言:javascript复制
package appium.testcases;

import appium.common.BasicTestCase;
import org.testng.annotations.Test;

public class WebViewTest extends BasicTestCase {

    @Test
    public void testWebView() throws Exception {
        //点击首页第1行
        pageHelper.getPageNews().clickNewsItem(2);
        Thread.sleep(3000);
        pageHelper.getPageCommon().switchToWebView();
        String content = pageHelper.getPageNewsDetail().getWebViewFirstLineContent("/html/body/div/p[1]");
        System.out.println(content);
    }
}

执行这个脚本可能会出现如下的错误:

说明你使用的Chrome driver的版本和你的Chrome版本不匹配,我们可以去如下的URL下载匹配的版本的Chrome driver,然后在我们的脚本里指定使用这个版本的driver就可以避免这种错误了

https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md

这个文档里列出了不同的Chrome所匹配的driver

根据操作系统选择对应的压缩包下载,下载完后解压缩,然后拷贝chromedriver文件到测试工程根目录下。查看我使用的模拟器版本为51.0.xxx所以我下载的是51.0对应连接的驱动。接着修改测试父类,然后指定Chrome driver使用的是根目录下的这个driver,更新完后的父类如下所示:

代码语言:javascript复制
package appium.common;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

import java.io.File;
import java.net.URL;

public class BasicTestCase {
    //声明静态的对象引用driver
    static AppiumDriver driver;
    private Helper helper;
    public PageHelper pageHelper;

    @BeforeMethod
    public void setUp() throws Exception {
        File app = new File(System.getProperty("user.dir"), "AUT/osc.apk");
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("deviceName", "My Android Device");
        capabilities.setCapability("app", app.getAbsolutePath());
        capabilities.setCapability("appPackage", "net.oschina.app");
        capabilities.setCapability("appActivity", "net.oschina.app.AppStart");
        capabilities.setCapability("noReset", true);
        capabilities.setCapability("unicodeKeyboard", true);
        File chromeDriverPath = new File(System.getProperty("user.dir"));
        //如果是windows就是.exe的,Mac直接是chromedriver      
      capabilities.setCapability("chromedriverExecutable",chromeDriverPath.getAbsolutePath() "/chromedriver.exe");
        driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
        helper = new Helper(driver);
        pageHelper = new PageHelper(helper);
        //跳转到我的设置页面
        pageHelper.getPageCommon().goToMySettingsTab();
        //判断是否是登录状态,是的话就退出,不是的话就不做处理
        if("aotu12345aotu".equals(pageHelper.getPageMySettings().getNickName())){
            pageHelper.getPageMySettings().clickSettingsBtn();
            pageHelper.getPageSettings().clickLogout();
        }
        //回到首页,每个测试脚本的入口就是首页
        pageHelper.getPageCommon().goToHomeTab();
    }


    @AfterMethod
    public void tearDown() throws Exception {
        driver.quit();
    }

    //添加获取driver对象引用的方法

    public static AppiumDriver getDriver(){
        return  driver;
    }


}

再次执行下脚本可以发现成功打印出WebView文本内容了。

0 人点赞