iOS alert handling has often been a testy subject (pun! pun!). Luckily, with the current XCUITest driver used by Appium, we can connect directly to 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:
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 which 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"?
For example, I've added a feature to The App's list view which enables you to tap a third alert button when you select a cloud type:
When you tap this third button, another alert appears with some extra information about the cloud type:
But back to the first alert. We want to click the "Learn more about Cirrostratus" alert option. In this case, we could probably use the fact that we know the name of the button to find it in the UI hierarchy. But what if we didn't know the text of the button, only that we wanted to tap the third button, whatever it contains? Luckily, Appium has a special command for handling alerts on iOS that you can use for this purpose: mobile: alert.
Also check: Working with the iOS Home Screen (Springboard)
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 considerations. Let's take a look at an example:
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. Today, we'll just try to extract the first label which isn't one of the defaults (taking care to throw an exception if there is no such label):
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:
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. See the full example below to see it working in the context of my test app or check out the code on GitHub!