Java 如何使用appium自动化/测试Android混合应用程序?

Java 如何使用appium自动化/测试Android混合应用程序?,java,android,selenium-webdriver,appium,Java,Android,Selenium Webdriver,Appium,我正在尝试使用appium自动化一个混合应用程序。我已经完成了全部的安装准备工作,并使用示例apk文件进行了测试。我在获取混合应用程序的对象属性时遇到了问题。我无法使用Appium inspector或uiautomatorviewer检查ID。它只显示我的应用程序的一个类 我还需要启用WebView调试,以便 SetWebContentsDebug已启用 在WebView类中为true。有人能帮我怎么做吗 一些博客说要保留driver.context(“web_view”);但我不清楚该怎么做

我正在尝试使用appium自动化一个混合应用程序。我已经完成了全部的安装准备工作,并使用示例apk文件进行了测试。我在获取混合应用程序的对象属性时遇到了问题。我无法使用Appium inspector或uiautomatorviewer检查ID。它只显示我的应用程序的一个类

我还需要启用WebView调试,以便 SetWebContentsDebug已启用

在WebView类中为true。有人能帮我怎么做吗

一些博客说要保留driver.context(“web_view”);但我不清楚该怎么做。请帮助解决这个问题。 谢谢

这是我的java类
下面是我为WEBView与本机视图的组合编写的混合应用程序代码示例。希望对你有帮助

public class Hybrid_App {

public static void main(String[] args) throws MalformedURLException, InterruptedException{

    DesiredCapabilities capabilities = new DesiredCapabilities();

    capabilities.setCapability("deviceName", "Atom 2x");
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("platformVersion", "5.1");

    capabilities.setCapability("appPackage","***YourHydridAppPkg****");
    capabilities.setCapability("appActivity", "****YourlauchableActivity***");

    AndroidDriver driver= new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

    Thread.sleep(4000);

    Set<String> contextHandles = driver.getContextHandles();

    Map<String,String> hashMap= new HashMap<String,String>();

    for(String contextname:contextHandles){

        if(contextname.contains("NATIVE")){

            hashMap.put("native", contextname);

        }else{
            hashMap.put("webview", contextname);
        }
    }

    //native page - Native 
    driver.context(hashMap.get("native"));

    WebDriverWait wait= new WebDriverWait(driver, 50);
    WebElement ele_voucher = wait.until(ExpectedConditions.visibilityOfElementLocated(
            By.xpath("//*[@class='android.view.View'][@index='9'][@content-desc='VOUCHERS']")));

    System.out.println(ele_voucher.isDisplayed());

    Thread.sleep(6000);
    ele_voucher.click();

    Thread.sleep(9000);

    //second page - Native
    driver.context(hashMap.get("native"));

    Thread.sleep(5000);
    driver.findElementByXPath("//*[@class='android.view.View'][@index='17'][@content-desc='REDEEM']").click();

    Thread.sleep(8000);

    System.out.println("----Third page----"+" uname,pwd element");

    //third page - Webview
    driver.context(hashMap.get("webview"));

    Thread.sleep(6000);

    driver.findElementByXPath("//input[@class='x-input-email'][@type='email'][@name='email']").sendKeys("descbatch@gmail.com");

    WebElement ele_pwd = driver.findElementByXPath("//input[@class='x-input-password'][@type='password'][@name='password']");

    ele_pwd.click();
    Thread.sleep(4000);
    ele_pwd.sendKeys("12345");

    Thread.sleep(6000);


    System.out.println("----Third page----"+" Sign in element");

    //fourth page - Native
    driver.context(hashMap.get("native"));

    Thread.sleep(6000);
    driver.findElementByXPath("//*[@class='android.view.View'][@index='69'][@content-desc='SIGN IN']").click();
    Thread.sleep(6000);

    driver.sendKeyEvent(AndroidKeyCode.BACK);


}
公共级混合动力应用程序{
publicstaticvoidmain(字符串[]args)抛出畸形的durlexception、InterruptedException{
DesiredCapabilities=新的DesiredCapabilities();
能力。设置能力(“deviceName”、“Atom 2x”);
能力。设置能力(“平台名”、“安卓”);
能力。设置能力(“平台版”、“5.1”);
能力。设置能力(“appPackage”、“ppkg****”);
能力。设置能力(“appActivity”,“*****YourlauchableActivity***”);
AndroidDriver=新的AndroidDriver(新URL(“http://127.0.0.1:4723/wd/hub(能力),;
睡眠(4000);
设置contextHandles=driver.getContextHandles();
Map hashMap=新hashMap();
for(字符串contextname:contextHandles){
if(contextname.contains(“本机”)){
hashMap.put(“本机”,contextname);
}否则{
put(“webview”,contextname);
}
}
//本机页面-本机
上下文(hashMap.get(“本机”);
WebDriverWait wait=新的WebDriverWait(驱动程序,50);
WebElement ele_凭证=等待.直到(ExpectedConditions.visibilityOfElementLocated(
通过.xpath(“/*[@class='android.view.view'][@index='9'][@content desc='dictionals']);
System.out.println(ele_凭证.isDisplayed());
睡眠(6000);
ele_凭证。单击();
睡眠(9000);
//第二页-本机
上下文(hashMap.get(“本机”);
睡眠(5000);
driver.findelementbypath(“/*[@class='android.view.view'][@index='17'][@content desc='redeme'])。单击();
睡眠(8000);
System.out.println(“----第三页----”+“uname,pwd元素”);
//第三页-网络视图
上下文(hashMap.get(“webview”);
睡眠(6000);
driver.findelementbypath(//input[@class='x-input-email'][@type='email'][@name='email']])descbatch@gmail.com");
WebElement ele_pwd=driver.findelementbypath(//input[@class='x-input-password'][@type='password'][@name='password']);
ele_pwd.click();
睡眠(4000);
ele_pwd.sendKeys(“12345”);
睡眠(6000);
System.out.println(“----第三页----”+“登录元素”);
//第四页-本机
上下文(hashMap.get(“本机”);
睡眠(6000);
driver.findelementbypath(“/*[@class='android.view.view'][@index='69'][@content desc='SIGN'])。单击();
睡眠(6000);
driver.sendKeyEvent(AndroidKeyCode.BACK);
}

}

下面使用我为WEBView原生视图组合编写的混合应用程序代码示例。希望对你有帮助

public class Hybrid_App {

public static void main(String[] args) throws MalformedURLException, InterruptedException{

    DesiredCapabilities capabilities = new DesiredCapabilities();

    capabilities.setCapability("deviceName", "Atom 2x");
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("platformVersion", "5.1");

    capabilities.setCapability("appPackage","***YourHydridAppPkg****");
    capabilities.setCapability("appActivity", "****YourlauchableActivity***");

    AndroidDriver driver= new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

    Thread.sleep(4000);

    Set<String> contextHandles = driver.getContextHandles();

    Map<String,String> hashMap= new HashMap<String,String>();

    for(String contextname:contextHandles){

        if(contextname.contains("NATIVE")){

            hashMap.put("native", contextname);

        }else{
            hashMap.put("webview", contextname);
        }
    }

    //native page - Native 
    driver.context(hashMap.get("native"));

    WebDriverWait wait= new WebDriverWait(driver, 50);
    WebElement ele_voucher = wait.until(ExpectedConditions.visibilityOfElementLocated(
            By.xpath("//*[@class='android.view.View'][@index='9'][@content-desc='VOUCHERS']")));

    System.out.println(ele_voucher.isDisplayed());

    Thread.sleep(6000);
    ele_voucher.click();

    Thread.sleep(9000);

    //second page - Native
    driver.context(hashMap.get("native"));

    Thread.sleep(5000);
    driver.findElementByXPath("//*[@class='android.view.View'][@index='17'][@content-desc='REDEEM']").click();

    Thread.sleep(8000);

    System.out.println("----Third page----"+" uname,pwd element");

    //third page - Webview
    driver.context(hashMap.get("webview"));

    Thread.sleep(6000);

    driver.findElementByXPath("//input[@class='x-input-email'][@type='email'][@name='email']").sendKeys("descbatch@gmail.com");

    WebElement ele_pwd = driver.findElementByXPath("//input[@class='x-input-password'][@type='password'][@name='password']");

    ele_pwd.click();
    Thread.sleep(4000);
    ele_pwd.sendKeys("12345");

    Thread.sleep(6000);


    System.out.println("----Third page----"+" Sign in element");

    //fourth page - Native
    driver.context(hashMap.get("native"));

    Thread.sleep(6000);
    driver.findElementByXPath("//*[@class='android.view.View'][@index='69'][@content-desc='SIGN IN']").click();
    Thread.sleep(6000);

    driver.sendKeyEvent(AndroidKeyCode.BACK);


}
公共级混合动力应用程序{
publicstaticvoidmain(字符串[]args)抛出畸形的durlexception、InterruptedException{
DesiredCapabilities=新的DesiredCapabilities();
能力。设置能力(“deviceName”、“Atom 2x”);
能力。设置能力(“平台名”、“安卓”);
能力。设置能力(“平台版”、“5.1”);
能力。设置能力(“appPackage”、“ppkg****”);
能力。设置能力(“appActivity”,“*****YourlauchableActivity***”);
AndroidDriver=新的AndroidDriver(新URL(“http://127.0.0.1:4723/wd/hub(能力),;
睡眠(4000);
设置contextHandles=driver.getContextHandles();
Map hashMap=新hashMap();
for(字符串contextname:contextHandles){
if(contextname.contains(“本机”)){
hashMap.put(“本机”,contextname);
}否则{
put(“webview”,contextname);
}
}
//本机页面-本机
上下文(hashMap.get(“本机”);
WebDriverWait wait=新的WebDriverWait(驱动程序,50);
WebElement ele_凭证=等待.直到(ExpectedConditions.visibilityOfElementLocated(
通过.xpath(“/*[@class='android.view.view'][@index='9'][@content desc='dictionals']);
System.out.println(ele_凭证.isDisplayed());
睡眠(6000);
ele_凭证。单击();
睡眠(9000);
//第二页-本机
上下文(hashMap.get(“本机”);
睡眠(5000);
driver.findelementbypath(“/*[@class='android.view.view'][@index='17'][@content desc='redeme'])。单击();
睡眠(8000);
System.out.println(“----第三页----”+“uname,pwd元素”);
//第三页-网络视图
上下文(hashMap.get(“webview”);
睡眠(6000);
driver.findelementbypath(//input[@class='x-input-email'][@type='email'][@name='email']])descbatch@gmail.com");
WebElement ele_pwd=driver.findelementbypath(//input[@class='x-input-password'][@type='password'][@name='password']);
ele_pwd.click();
睡眠(4000);
ele_pwd.sendKeys(“12345”);
睡眠(6000);
System.out.println(“----第三页----”+“登录元素”);
//第四页-本机
上下文(hashMap.get(“本机”);
睡眠(6000);
driver.findelementbypath(“/*[@class='android.view.view'][@index='69'][@content desc='SIGN'])。单击();
睡眠(6000);
driver.sendKeyEvent(AndroidKeyCode.BACK);
}
}