【问题标题】:Switching between two apps in appium iOS在 appium iOS 中的两个应用程序之间切换
【发布时间】:2018-10-19 15:10:48
【问题描述】:

我有一个测试用例,我必须在 iPhone 中 1. 在应用 A 中执行任务。 2.切换到Safari浏览器并执行任务 3.再次切换回App A,继续其他任务

目前我可以执行 1 和 2,然后切换回 App A,但从 safari 浏览器切换后我无法在 App A 中执行任何任务。我所做的如下。

首先启动应用程序 A 我使用了以下代码

public void createAppiumDriver() throws MalformedURLException, InterruptedException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "iPhone 7 Plus");
capabilities.setCapability("platformName", "iOS");
capabilities.setCapability("platformVersion", "11.2"); 
capabilities.setCapability("autoWebView", true);
capabilities.setCapability("app", getProperties().getProperty("appURL"));
capabilities.setCapability("autoAcceptAlerts", true);
capabilities.setCapability("useNewWDA", true);
capabilities.setCapability("startIWDP",true);
iosDriver = new IOSDriver(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);}

为了从我的应用切换到 Safari,我使用以下代码开始了一个新会话以切换到 safari

public void openSafari() throws MalformedURLException {
DesiredCapabilities capabilities2 = new DesiredCapabilities();
capabilities2.setCapability("deviceName", "iPhone 7 Plus");
capabilities2.setCapability("platformName", "iOS");
capabilities2.setCapability("platformVersion", "11.2");
capabilities2.setCapability("browserName", "Safari");
capabilities2.setCapability("autoAcceptAlerts", true);
capabilities2.setCapability("useNewWDA", true);
iosDriver2 = new IOSDriver(new URL("http://0.0.0.0:4723/wd/hub"), capabilities2);
iosDriver2.get("https://www.gmail.com");}

现在我遇到的问题是再次从 safari 浏览器切换回 App A 以执行一些任务,此时我再次创建了一个新会话,如下所示

public void switchToNutrifix() throws MalformedURLException, InterruptedException {
DesiredCapabilities capabilities3 = new DesiredCapabilities();
capabilities3.setCapability("deviceName", "iPhone 7 Plus");
capabilities3.setCapability("platformName", "iOS");
capabilities3.setCapability("platformVersion", "11.2"); //Replace this with your iOS version
capabilities3.setCapability("autoWebView", true);
capabilities3.setCapability("app", getProperties().getProperty("appURL"));
capabilities3.setCapability("autoAcceptAlerts", true);
capabilities3.setCapability("useNewWDA", true);
capabilities3.setCapability("startIWDP",true);
iosDriver3 = new IOSDriver(new URL("http://0.0.0.0:4723/wd/hub"), capabilities3);}

现在的问题是应用程序 A 再次从 Safari 中打开,但它无法识别应用程序中的元素。我什至将上下文正确更改为 webview,但在从 Safari 浏览器切换后,它仍然无法在 App A 中执行任何任务。有人可以告诉我我在这里做错了什么或另一种方法来进行此切换。

我通常得到的错误是

May 09, 2018 6:43:42 PM org.openqa.selenium.support.ui.ExpectedConditions findElement
WARNING: WebDriverException thrown by findElement(By.xpath: //div[@class='login-content purpose']/h2)
org.openqa.selenium.remote.SessionNotFoundException: A session is either terminated or not started (WARNING: The server did not provide any stacktrace information)

appium 日志显示

debug] [iOS] No key id found. Choosing first id from page array
[debug] [iOS] Page change not referring to currently selected app, ignoring.

【问题讨论】:

    标签: automation automated-tests appium ios-ui-automation appium-ios


    【解决方案1】:
    public class SwitchBtnAppsiOS {
    
    public AppiumDriver<RemoteWebElement>iosDriver;
    
    public DesiredCapabilities createAppiumDriver()
        throws MalformedURLException, InterruptedException {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("deviceName", "iPhone 7 Plus");
        capabilities.setCapability("platformName", "iOS");
        capabilities.setCapability("platformVersion", "11.2"); 
        capabilities.setCapability("autoWebView", true);
        capabilities.setCapability("app", getProperties().getProperty("appURL"));
        capabilities.setCapability("autoAcceptAlerts", true);
        capabilities.setCapability("useNewWDA", true);
        capabilities.setCapability("startIWDP",true);
        return capabilities;
    }
    
    
    public DesiredCapabilities openSafari() 
        throws MalformedURLException {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("deviceName", "iPhone 7 Plus");
        capabilities.setCapability("platformName", "iOS");
        capabilities.setCapability("platformVersion", "11.2");
        capabilities.setCapability("browserName", "Safari");
        capabilities.setCapability("autoAcceptAlerts", true);
        capabilities.setCapability("useNewWDA", true);
        return capabilities;
    }
    
    public void switchBetweenApps() throws MalformedURLException, InterruptedException
    {
        DesiredCapabilities nativeAppCaps = createAppiumDriver();
        iosDriver = new IOSDriver<>(new URL("http://0.0.0.0:4723/wd/hub"), nativeAppCaps);
    
        /**
         * Perform the actions on native app
         */
    
        DesiredCapabilities webCaps = createAppiumDriver();
        iosDriver = new IOSDriver<>(new URL("http://0.0.0.0:4723/wd/hub"), webCaps);
        iosDriver.get("https://www.gmail.com");
    
        /**
         * Perform the actions on safari browser 
         */
    
        // Again switch to native app
        iosDriver = new IOSDriver<>(new URL("http://0.0.0.0:4723/wd/hub"), nativeAppCaps);
    }
    }
    
    1. 无论您在何处使用驱动程序实例,都会传递最新的驱动程序实例。
    2. 如果是这种情况,请使用 RemoteWebElement 而不是 MobileElement。

    【讨论】:

      【解决方案2】:

      由于XCode 9 Appium 支持多个会话,我建议使用2 个同时会话:app 和 safari:

      1. 为原生应用创建驱动程序(例如driver1对象)
      2. 希望您在应用程序中需要,保持驱动程序实例处于活动状态

      提示:你可以把它放在后台: driver.runAppInBackground(Duration.ofMinutes(1));

      1. 为 safari 创建驱动程序(例如 driver2 对象)
      2. 如果您不需要,请关闭driver2
      3. 继续为原生应用使用driver1

      【讨论】:

      • 我尝试使用 driver.runAppInBackground(5);但它所做的是应用程序进入后台等待 5 秒钟并再次弹出而不移动到 safari 浏览器。只有在它在 5 秒后弹出后,它才会进入 safari。所以我使用了 driver.runAppInBackground(-1) 所以它不会再次自动弹出。但我不知道如何在使用 safari 后恢复应用程序。我尝试使用 driver.launchapp() 但它只是重新安装应用程序并且无法识别应用程序中的元素。
      • 您是否尝试创建 2 个驱动程序实例?这是唯一的方法,因为使用 appium/XCUITest 您很可能无法在单个会话中检查 2 个应用程序。
      【解决方案3】:

      有一种更好的方式来切换黑白 iOS 应用程序,而不是按照上面答案中的建议一次又一次地创建驱动程序会话

      IOSDriver driver = new IOSDriver<>(new URL("http://localhost:4723/wd/hub"), capabilities);
      
      try {
      HashMap<String, Object> args = new HashMap<>();
      args.put("bundleId", SWITCH_APP_BUNDLE_ID);
      driver.executeScript("mobile: launchApp", args);
      
      /*
      TODO code for switch app
      */
      
      
      // Now reactivate  AUT App
      args.put("bundleId", AUT_APP_BUNDLE_ID);
      driver.executeScript("mobile: activateApp", args);
      
      /*
      TODO code for AUT App
      */
      } 
      finally {
      // quit driver     
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-13
        • 1970-01-01
        • 1970-01-01
        • 2020-08-23
        • 2016-05-17
        • 2014-05-04
        • 2016-07-27
        • 1970-01-01
        相关资源
        最近更新 更多