Automate Complex iOS Alerts With Appium

1_iMPfw0qHQdgGzVdtAdJooQ

     iOS alert handling has often been a testy subject. Luckily, with the current XCUITest driver used by Appium, we can connect directly to the Apple-approved method for accepting or dismissing an alert, or even getting its text. Appium provides access to this behavior via the standard suite of WebDriver alert commands, for example:

driver.switchTo().alert().alert()
          driver.switchTo().alert().dismiss()
            driver.switchTo().alert().getText()

     Unfortunately, the WebDriver spec is not quite as flexible as mobile apps when it comes to the design of alerts. The WebDriver spec was based around web browser alerts, which can contain at most two action buttons. Mobile apps can create native alerts that contain 3 or even more buttons! So what do you do when you need to automate the action associated with a button which is not “OK” or “Cancel”?

     Luckily, Appium has a special command for handling alerts on iOS that you can use for this purpose: mobile: alert. This command does allow you to accept and dismiss alerts as usual, but that’s not very interesting. We’re going to look at two new use cases: getting a list of the available button labels, and tapping an alert action via its label. These features together will help solve the problem under consideration. Let’s take a look at an example:

HashMap<String, String> args = new HashMap<>();
            args.put("action", "getButtons");
            List<String> buttons = (List<String>)driver.executeScript("mobile: alert", args);

      Following the pattern of the other mobile: methods, we use executeScript with a special command and parameters to get the list of button labels. Once we have this list, we can do whatever we want with it.

String buttonLabel = null;
            for (String button : buttons) {
              if (button.equals("OK") || button.equals("Cancel")) {
                continue;
                  }
                  buttonLabel = button;
                  }
                  if (buttonLabel == null) {
                    throw new Error("Did not get a third alert button as we were expecting");
                      }

     At this point, we have the value of the button we want to press in the buttonLabel variable. We can again use mobile: alert to target this specific button, using a different action parameter than before (with a value of “accept”), and adding the new parameter buttonLabel to let Appium know which button we want it to tap for us:

args.put("action", "accept");
                    args.put("buttonLabel", buttonLabel);
                      driver.executeScript("mobile: alert", args);

That’s all there is to it! Using mobile: alert we have access to the full set of alert actions that can be displayed in an iOS app. Try to use the above logic to deal with complex alert in iOS native applications.

Reference: Appium Pro

make it perfect!