Sunday, 10 May 2020

MobileAutomation - Handle Pop-ups, Alerts and Prompts in Automate and App Automate Tests

This article shows you how to handle user permission pop-ups, alerts, and prompts in your automated tests on BrowserStack.

Introduction

Some functionalities in your web apps may need user-permissions. For instance:
  • access to device location,
  • access camera and/or microphone,
  • permission to show notifications,
  • access to device storage, etc.
The browser then triggers a pop-up box with 'Confirm’ or 'Deny' interactions. This article shows how to automate those interactions on remote browsers and real mobile devices.

Common permission pop-ups (on desktop and mobile):

This section contains the common permission pop-ups and how you can automate them on Desktop and Real Mobile Devices.

1. "Know your location" pop-up

You can test what happens when your web app is allowed to (or blocked from) accessing the device location, using Automate.
Know Your LocationUse Device Location
Desktop:
The snippet below lets you automate an 'Allow' or 'Block' interaction when the remote Chrome browser asks for location.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class AllowGeoLocationPopup {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + ACCESS_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("browser_version", "75.0");
    caps.setCapability("os", "Windows");
    caps.setCapability("os_version", "10");

    // INIT CHROME OPTIONS
    ChromeOptions options = new ChromeOptions();
    Map < String, Object > prefs = new HashMap < String, Object > ();
    Map < String, Object > profile = new HashMap < String, Object > ();
    Map < String, Object > contentSettings = new HashMap < String, Object > ();

    // SET CHROME OPTIONS
    // 0 - Default, 1 - Allow, 2 - Block
    contentSettings.put("geolocation", 1);
    profile.put("managed_default_content_settings", contentSettings);
    prefs.put("profile", profile);
    options.setExperimentalOption("prefs", prefs);

    // SET CAPABILITY
    caps.setCapability(ChromeOptions.CAPABILITY, options);
    WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
    driver.get("https://the-internet.herokuapp.com/geolocation");
    driver.findElement(By.xpath("//*[@id='content']/div/button")).click();
    Thread.sleep(5000);
    driver.quit();
  }
}

Mobile:
The snippet below lets you automate an 'Allow' or 'Block' interaction when the remote Chrome browser asks an Android device for location.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;

import java.net.URL;
import java.util.Set;

public class AllowGeoLocationPopup {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + AUTOMATE_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("browserName", "android");
    caps.setCapability("device", "Samsung Galaxy S10");
    caps.setCapability("realMobile", "true");
    caps.setCapability("os_version", "9.0");
    AppiumDriver driver = new AndroidDriver(new URL(URL), caps);
    driver.get("https://the-internet.herokuapp.com/geolocation");
    driver.findElement(By.xpath("//*[@id='content']/div/button")).click();
    Thread.sleep(5000);
    // To accept/block the popup, you need to switch the context to “NATIVE_APP“ and click on the Allow/Block button.
    driver.context("NATIVE_APP");
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    Thread.sleep(5000);
    driver.quit();
  }
}


2. "Use your camera" and "Use your microphone" pop-up

You can test what happens when your web app is allowed to (or blocked from) accessing camera or microphone, using Automate.
Use Camera AndroidUse Microphone Android
Use Camera AndroidUse Microphone Android
Desktop:
The snippet below lets you automate an 'Allow' or 'Block' interaction when your web app requests access to camera or microphone.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.URL;

public class AllowCameraPopupChrome {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + AUTOMATE_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {

    //Configure ChromeOptions to pass fake media stream
    ChromeOptions options = new ChromeOptions();
    options.addArguments("use-fake-device-for-media-stream");
    options.addArguments("use-fake-ui-for-media-stream");

    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("browser_version", "75.0");
    caps.setCapability("os", "Windows");
    caps.setCapability("os_version", "10");
    caps.setCapability(ChromeOptions.CAPABILITY, options);
    WebDriver driver = new RemoteWebDriver(new URL(URL), caps);

    //WebCam Test
    driver.get("https://webcamtests.com/check");
    Thread.sleep(5000);
    driver.findElement(By.id("webcam-launcher")).click();
    Thread.sleep(2000);

    //Mic Test
    driver.get("https://www.vidyard.com/mic-test/");
    Thread.sleep(2000);
    driver.findElement(By.xpath("(//*[@class='button' and text()='Grant access'])[1]")).click();
    Thread.sleep(2000);

    driver.quit();
  }
}

Mobile:
The snippet below lets you automate an 'Allow' or 'Block' interaction on Android devices when the remote Chrome browser asks for access to camera or microphone.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;

import java.net.URL;

public class AllowCameraPopupChromeMobile {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + AUTOMATE_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("device", "Samsung Galaxy S10");
    caps.setCapability("realMobile", "true");
    caps.setCapability("os_version", "9.0");
    AppiumDriver driver = new AndroidDriver(new URL(URL), caps);

    //WebCam Test
    driver.get("https://webcamtests.com/check");
    Thread.sleep(2000);
    driver.findElement(By.id("webcam-launcher")).click();
    Thread.sleep(2000);
    // To accept/block the popup, you need to switch the context to “NATIVE_APP“ and click on the Allow/Block button.
    driver.context("NATIVE_APP");
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    Thread.sleep(2000);

    driver.context("CHROMIUM");

    //Mic Test
    driver.get("https://webcammictest.com/check-microphone.html");
    Thread.sleep(2000);
    driver.findElement(By.xpath("//button[contains(@class, 'button') and text()='Check my microphone']")).click();
    Thread.sleep(2000);
    driver.context("NATIVE_APP");
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    Thread.sleep(2000);

    driver.quit();
  }
}


3. "Show notifications" pop-up

You can test what happens when your web app is allowed to (or blocked from) showing notifications, using Automate.
Show Notification RequestShow Notification Request
Desktop:
The snippet below lets you automate an 'Allow' or 'Block' interaction when your web app requests permission to show notifications.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class AllowNotificationPopupDesktop {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + AUTOMATE_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("browser_version", "75.0");
    caps.setCapability("os", "Windows");
    caps.setCapability("os_version", "10");

    // INIT CHROME OPTIONS
    ChromeOptions options = new ChromeOptions();
    Map<String, Object> prefs = new HashMap<String, Object>();
    Map<String, Object> profile = new HashMap<String, Object>();
    Map<String, Object> contentSettings = new HashMap<String, Object>();

    // SET CHROME OPTIONS
    // 0 - Default, 1 - Allow, 2 - Block
    contentSettings.put("notifications", 1);
    profile.put("managed_default_content_settings", contentSettings);
    prefs.put("profile", profile);
    options.setExperimentalOption("prefs", prefs);

    // SET CAPABILITY
    caps.setCapability(ChromeOptions.CAPABILITY, options);

    WebDriver driver = new RemoteWebDriver(new URL(URL), caps);

    driver.get("https://web-push-book.gauntface.com/demos/notification-examples/");
    driver.findElement(By.xpath("//*[@class='js-notification-overview' and text() = 'Example Notification']")).click();
    Thread.sleep(2000);
    driver.quit();
  }
}

Mobile:
The snippet below lets you automate an 'Allow' or 'Block' interaction on Android devices when the remote Chrome browser asks for permission to show notifications.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;

import java.net.URL;
import java.util.Set;

public class AllowNotificationPopupMobile {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + AUTOMATE_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("browserName", "android");
    caps.setCapability("device", "Samsung Galaxy S10");
    caps.setCapability("realMobile", "true");
    caps.setCapability("os_version", "9.0");
    AppiumDriver driver = new AndroidDriver(new URL(URL), caps);

    driver.get("https://web-push-book.gauntface.com/demos/notification-examples/");
    driver.findElement(By.xpath("//*[@class='js-notification-overview' and text() = 'Example Notification']")).click();
    Thread.sleep(2000);

    Set contextHandles = driver.getContextHandles();
    // To accept/block the popup, you need to switch the context to “NATIVE_APP“ and click on the Allow/Block button.
    driver.context("NATIVE_APP");
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    Thread.sleep(2000);
    driver.quit();
  }
}

Mobile-Only permission pop-ups

This section shows how you can automate scenarios involving app permission pop-ups—on real mobile devices.

1. "Storage access permission" pop-up on Android devices

You can test what happens when your web app is allowed to (or blocked from) accessing device storage on Android devices, in Automate.
Storage Access Chrome
The snippet below lets you automate an 'Allow' or 'Block' interaction on Android devices when the remote Chrome browser asks for permission to access device storage.
Code Snippet
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;

import java.net.URL;

public class AllowFileDownloadPopupChromeMobile {
  public static final String USERNAME = "USERNAME";
  public static final String AUTOMATE_KEY = "ACCESS_KEY";
  public static final String URL = "https://" + USERNAME + ":" + AUTOMATE_KEY + "@hub-cloud.browserstack.com/wd/hub";

  public static void main(String[] args) throws Exception {
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.setCapability("browser", "Chrome");
    caps.setCapability("browserName", "android");
    caps.setCapability("device", "Samsung Galaxy S10");
    caps.setCapability("realMobile", "true");
    caps.setCapability("os_version", "9.0");

    AppiumDriver driver = new AndroidDriver(new URL(URL), caps);
    driver.get("https://the-internet.herokuapp.com/download");
    driver.findElement(By.linkText("some-file.txt")).click();
    Thread.sleep(2000);

    // To accept/block the popup, you need to switch the context to “NATIVE_APP“ and click on the Allow/Block button.
    driver.context("NATIVE_APP");
    driver.findElement(By.xpath(".//android.widget.Button[@text='Continue']")).click();
    driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
    Thread.sleep(2000);
    driver.quit();
  }
}


2. Automatically grant all app permissions for Android apps

The autoGrantPermissions is an Appium capability. When enabled, your Android app gets all the permissions listed in the manifest file of the APK, upon install.
The sample below shows how to enable autoGrantPermissions capability for your test:
Code Snippet
caps.setCapability("autoGrantPermissions", "true");


3. Allow / Deny all app permissions for iOS apps

autoAcceptAlerts and autoDismissAlerts are Appium capabilities. When enabled, the iOS device accepts (or rejects) all access requests, upon install. This includes location, contacts, photos, and more.
Note: These capabilities do not work on XCUITest scripts.
The sample below shows how to enable autoAcceptAlerts or autoDissmissAlerts capabilities for your test:
Code Snippet
caps.setCapability("autoAcceptAlerts", "true");
//OR
caps.setCapability("autoDissmissAlerts", "true");


4. Allow / Deny any app permission pop-up on Android and iOS devices

For more selective test scenarios, you would want to accept some app permission pop-ups and deny the others. To automate these interactions, you can switch to "NATIVE_APP" context to 'accept’ or 'deny' each pop-up on iOS and Android devices.
Code Snippet
driver.context("NATIVE_APP");
//For Android
driver.findElement(By.xpath(".//android.widget.Button[@text='Allow']")).click();
//For iOS
driver.findElement(By.id("Allow")).click();

Exception

Disabling 'Save your password' message doesn’t work in Edge browser.
There is a known issue in Edge browser which prevents you from interacting with OR disabling the 'Save Your Password’ pop-up. Refer to the GitHub issue link for more details.
Reference url - clickHere

MobileAutomation - Handle Pop-ups, Alerts and Prompts in Automate and App Automate Tests

This article shows you how to handle user permission pop-ups, alerts, and prompts in your automated tests on BrowserStack. Introductio...