Skip to main content
iOS puts its own screens over your app: a location alert, Allow Paste, the Sign in with Apple sheet, a Face ID prompt, the purchase sheet. They move with every iOS release and they aren’t yours. A check names each answer once in dialogs, and every run answers them without a model.

Answer iOS dialogs

Add dialogs to an existing check file:
Model steps, a replay and a launch-only check all use these answers. To test that the app handles a refusal, answer the other way:
ask keeps the rule a task uses, and a check has nobody to ask, so the run stops and says which dialog iOS showed.

Know which dialogs are never answered

iOS asking for your Apple Account password, a dialog with a password field, a Save Password prompt, Trust This Computer and an Apple Account sign-in, including one that offers Face ID or Touch ID, are never answered for you, whatever dialogs says. Mobster knows them by Apple’s wording, so an app’s own alert such as “Incorrect password” or “You’re all set” stays the app’s. An app’s own alert that uses the same wording as one of these, such as “Enter your password to continue”, or on your iPhone “Do you want to buy 100 coins?”, stops the check instead of being answered. Only iOS’s own dialogs are answered, on a simulator and on your iPhone:
  • An alert is answered only while WebDriverAgent reports SpringBoard in front, or the Apple process for its own kind: StoreKit for a purchase alert, AuthKit for a Sign in with Apple alert, CoreAuthUI for a Face ID alert. None of its lines may be on the app’s own screen, so the app’s alert stays the app’s even when it says “location” or has Allow and Don’t Allow buttons.
  • A sheet is answered only while the one Apple process that shows it is in front and the screen Mobster reads is that process’s own. The app’s screen behind a real sheet is never taken for the sheet.
  • A web page in an in-app browser or a web sign-in runs in Safari’s process, so its confirm() and its look-alike Continue, Subscribe or “Log in with Face ID” are never answered.
  • When WebDriverAgent can’t say what is in front, nothing is pressed.
Each dialog Mobster answers is its own system_dialog event in events.jsonl: the kind, the button, and that the check chose it. A replay answers one between steps, so it doesn’t count as a step or a heal, and a replay that meets a dialog it hasn’t seen before answers it from dialogs instead of failing. A replay that meets one dialogs has no answer for ends couldnt_run, class system_dialog, and keeps its recorded steps. Within one run Mobster never answers the same dialog twice in a row: when the dialog it answered last is still there, or back, the run ends couldnt_run, class system_dialog. Mobster reads a dialog from WebDriverAgent’s alert, or from the screen for a sheet an app presents. It never asks a model to read one.

Handle a dialog at launch

A launch-only check has no steps. It watches for 2 seconds from the moment the app is in front. In that time it answers each iOS dialog, such as a notifications alert, with the answer dialogs names, or on a simulator with the default above. Then it reads the screen for its verdict. On your iPhone, a permission alert stays up when dialogs doesn’t name permissions. A dialog that comes up after the 2 seconds stays up too. The failure names a dialog that stays up:
A dialog that dialogs stops at in those 2 seconds, such as a camera alert under permissions: ask, ends the check couldnt_run, class system_dialog.

What a simulator may do that an iPhone may not

On a simulator there is no money to spend and nobody to message, so the checks that matter most (the paywall buys, the composer sends) run. The app’s own backend still receives what the app sends, so point a check at staging.

Test in other languages

Every check runs once in each language. --locale takes language codes, with a region if you like (pt_BR), separated by commas or repeated, at most 12. The run for de is the check “Home [de]”: it launches your app with -AppleLanguages (de) -AppleLocale de, the same as conditions: {locale: de} in a check file, and it keeps any other conditions the check sets. Mobster changes the app’s language and region only, not the simulator’s system settings. The same flag works with --sim and --device: a real iPhone gets the launch arguments and nothing else. --locale replaces a locale list in a check. Each language is its own check in results.json (locale on the check), in junit.xml (the classname checks.home.de) and in the history, so a layout that breaks only in German has its own pass rate. Each language also has its own stable case ID, so saved-suite comparisons keep German and Japanese results apart. The audit reads the screens each run already reads, with no model, and reports warnings that never fail the check: Right-to-left layout comes from iOS: with ar, the app mirrors itself when it uses leading and trailing edges, and rtl-not-mirrored tells you where it didn’t. The accessibility tree has labels and frames, not the rendered glyphs, so text cut off inside a frame of the right size isn’t flagged. A brand name in Latin letters is flagged as untranslated in Japanese, which is why each finding is a warning. Languages written in Latin script (German, French, Spanish) get the truncation rule only.