DEV Community

Cover image for XCUITest Alerts: Handling Alerts, Sheets, Pop-Ups and System Dialogs
QAPulse by SK
QAPulse by SK

Posted on Originally published at skakarh.com

XCUITest Alerts: Handling Alerts, Sheets, Pop-Ups and System Dialogs

XCUITest Alerts are a critical part of reliable iOS UI automation because alerts, action sheets, pop-ups, permission prompts, and system dialogs can interrupt the normal interaction flow. A production-grade XCUITest framework must detect these transient UI states, identify the correct controls, synchronize with their appearance, and validate the resulting application behavior.

What are XCUITest Alerts?

XCUITest alerts are alert and dialog interfaces exposed through XCUITest’s UI automation hierarchy, allowing automated tests to detect, inspect, interact with, and validate alert-driven application behavior.

Typical examples include:

  • Confirmation alerts
  • Error alerts
  • Action sheets
  • Delete confirmations
  • Permission prompts
  • Login dialogs
  • System notifications
  • Camera and microphone permissions
  • Location permissions
  • System-level dialogs
  • Custom modal pop-ups

A typical automation flow is:

Application Action
       ↓
Alert / Sheet Appears
       ↓
Synchronize
       ↓
Locate Dialog
       ↓
Locate Button
       ↓
Perform Action
       ↓
Validate Result
Enter fullscreen mode Exit fullscreen mode

Definition

XCUITest alerts are alert and dialog interfaces that XCUITest can locate and interact with through the iOS UI automation hierarchy.

Key Points

  • Use app.alerts for alert-style interfaces.
  • Use app.sheets for action sheets where appropriate.
  • Use app.buttons to locate dialog actions.
  • Use waitForExistence(timeout:) for asynchronous dialogs.
  • Validate dialog titles and messages when they represent requirements.
  • Handle permission dialogs explicitly.
  • Do not assume dialogs appear instantly.
  • Avoid brittle coordinate-based interactions.
  • Separate application dialogs from system dialogs.
  • Validate the application state after dismissing a dialog.
  • Use launch configuration to control permissions when appropriate.
  • Centralize recurring dialog handling in reusable helpers.

Why Dialog Handling Matters in XCUITest

A test can fail even when the application’s primary workflow is correct if an unexpected dialog blocks interaction.

For example:

Launch App
   ↓
Login
   ↓
Dashboard
   ↓
Permission Dialog Appears
   ↓
Next UI Element Blocked
   ↓
Test Failure
Enter fullscreen mode Exit fullscreen mode

A production test should explicitly handle expected dialogs.

let alert =
    app.alerts["Delete Item"]

XCTAssertTrue(
    alert.waitForExistence(timeout: 10)
)

alert.buttons["Delete"].tap()
Enter fullscreen mode Exit fullscreen mode

The test now understands the intermediate application state.

1. Handling Basic Alerts

A standard alert can be accessed through app.alerts.

let app = XCUIApplication()

app.buttons["deleteButton"].tap()

let alert =
    app.alerts["Delete Item"]

XCTAssertTrue(
    alert.waitForExistence(timeout: 10)
)

alert.buttons["Delete"].tap()
Enter fullscreen mode Exit fullscreen mode

This pattern is straightforward:

Tap
 ↓
Wait
 ↓
Find Alert
 ↓
Find Button
 ↓
Tap
Enter fullscreen mode Exit fullscreen mode

2. Validating an Alert Message

When the alert message is part of the expected behavior, validate it.

let alert =
    app.alerts["Delete Item"]

XCTAssertTrue(
    alert.waitForExistence(timeout: 10)
)

let message =
    alert.staticTexts[
        "Are you sure you want to delete this item?"
    ]

XCTAssertTrue(
    message.exists
)
Enter fullscreen mode Exit fullscreen mode

For some alert structures, identifying the message by its visible text can be sufficient:

XCTAssertTrue(
    alert.staticTexts[
        "Are you sure you want to delete this item?"
    ].exists
)
Enter fullscreen mode Exit fullscreen mode

The assertion turns the dialog into a testable behavior.

3. Handling Cancel Actions

Negative paths are equally important.

let alert =
    app.alerts["Delete Item"]

XCTAssertTrue(
    alert.waitForExistence(timeout: 10)
)

alert.buttons["Cancel"].tap()

XCTAssertFalse(
    alert.exists
)
Enter fullscreen mode Exit fullscreen mode

This verifies both:

  1. The alert appeared.
  2. The cancel action dismissed it.

4. Handling Confirmation Alerts

A confirmation workflow can be tested as:

func testDeleteConfirmation() {

    let app = XCUIApplication()
    app.launch()

    app.buttons["deleteButton"].tap()

    let alert =
        app.alerts["Delete Item"]

    XCTAssertTrue(
        alert.waitForExistence(timeout: 10)
    )

    XCTAssertTrue(
        alert.buttons["Delete"].exists
    )

    alert.buttons["Delete"].tap()

    XCTAssertTrue(
        app.staticTexts["Deleted"]
            .waitForExistence(timeout: 10)
    )
}
Enter fullscreen mode Exit fullscreen mode

Notice that the final assertion validates the application outcome, not merely the button interaction.

5. Handling Action Sheets

Action sheets represent another common modal interaction.

let sheet =
    app.sheets["File Options"]

XCTAssertTrue(
    sheet.waitForExistence(timeout: 10)
)

sheet.buttons["Delete"].tap()
Enter fullscreen mode Exit fullscreen mode

Depending on the UI hierarchy, you may also locate buttons directly:

app.buttons["Delete"].tap()
Enter fullscreen mode Exit fullscreen mode

The important point is to use the hierarchy exposed by the application rather than relying on screen coordinates.

6. Handling Pop-Ups

Custom application pop-ups may not always appear as XCUIAlert-style structures.

For example:

let popup =
    app.otherElements["subscription.popup"]

XCTAssertTrue(
    popup.waitForExistence(timeout: 10)
)

popup.buttons["Close"].tap()
Enter fullscreen mode Exit fullscreen mode

This is why accessibility identifiers are valuable.

A custom popup can expose:

subscription.popup
subscription.popup.close
subscription.popup.upgrade
Enter fullscreen mode Exit fullscreen mode

👉 Continue reading the full article on skakarh.com →

Originally published at skakarh.com/xcuitest-alerts.
Subscribe to QA Pulse by SK
weekly signal for QA, Test Automation and AI in Software Engineering.

Top comments (0)