Two driver instances in one session

The problem

I’m automating the following scenario:

  • user launches mobile Chrome browser and navigate to the website
  • they click a button and it opens a pre-installed Android native app
  • verify that the app is launched
    As for now, I know how to create one driver in a session and test either native app or mobile web (or hybrid) app.
    Question: how to launch a native app and a web browser simultaneously and switch the contexts.

Environment

  • Appium version: 1.8.1
  • Mobile platform/version under test: Android 8.0.0
  • Real device or emulator/simulator: Galaxy S8 (real device)

Code To Reproduce Issue

This is how I create the driver instance to test the native app:

public void setUpForNativeApp() throws IOException, InterruptedException {
        File apkFile = findFileByMask(System.getProperty("user.dir"), ".*\\.apk");
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Samsung Galaxy S7 edge");
        capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        capabilities.setCapability(AndroidMobileCapabilityType.NO_SIGN, "true");
        capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.<<the_app_I_am_testing>>");
        capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, "com.<<the_app_I_am_testing>>.ui.mainactivity.<<the_app_I_am_testing>>MainActivity");
        capabilities.setCapability("autoGrantPermissions", "true"); //grant permission to system dialogues such as location
        capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 30);
        capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
        capabilities.setCapability(MobileCapabilityType.APP, apkFile.getAbsolutePath());
        setUp(capabilities);
}

This is how I create the driver instance to test the mobile web site:

public void setUpForNativeApp() throws IOException, InterruptedException {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Samsung Galaxy S7 edge");
        capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
        capabilities.setCapability(AndroidMobileCapabilityType.NO_SIGN, "true");
        capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 30);
        capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
        capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
        setUp(capabilities);
}

This is the SetUp() method:

 public void setUp(DesiredCapabilities capabilities) throws IOException, InterruptedException {
        FileInputStream fileInputStream = new FileInputStream(System.getProperty("user.dir") + "/src/main/resources/user.properties");
        prop.load(fileInputStream);
        killUiAutomatorServer();
        setupType.setUp(capabilities);
        String appiumEndpoint = setupType.getAppiumEndpoint();
        System.out.println(".......Connecting to Appium on " + appiumEndpoint);
        driver = new AndroidDriver(new URL(appiumEndpoint), capabilities);
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        System.out.println(".......Starting Appium driver");
}

And this is how I’m about to switch contexts:

Set contextNames = driver.getContextHandles();
        for (Object contextName : contextNames)     // NATIVE_APP or CHROMIUM
            if (contextName.toString().contains("NATIVE_APP")) driver.context(contextName.toString());

I’m sure lots of you have encountered this problem.

Please help.