Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode UI Unit Tests and Permission Alerts

I'm working on a UI unit test for my app, and am trying to figure out how to automatically have the test framework click "OK" when the system presents an alert asking for permission to access contacts.

So far, I've looked at these four SO posts, and tried the various suggestions, but am still unable to get this to work:

XCTest app tests and permissions alerts

Xcode 7 UI Testing: how to dismiss a series of system alerts in code

Xcode UI Testing allow system alerts series

Xcode 7 UI Testing: Dismiss Push and Location alerts

Here's what I currently am trying - however, the permissions dialog is still not being automatically accepted; the test waits for me to click "OK" before moving forward: func testApp() {

    self.addUIInterruptionMonitor(withDescription: "MyDescription", handler: { (alert) -> Bool in
        let button = alert.buttons["OK"]
        if button.exists {
            button.tap()
            return true
        }
        return false
    })

    let app = XCUIApplication()
    app.launch()
    ...
    app.tap()
    ...
}

EDIT: Here's the change I've made based on @ad-johnson's suggestion:

var app: XCUIApplication!

override func setUp() {
    super.setUp()

    continueAfterFailure = false
    app = XCUIApplication()

    addUIInterruptionMonitor(withDescription: "Contact Auth")
    { (alert) -> Bool in if alert.buttons["OK"].exists {
        alert.buttons["OK"].tap()
        }
        return true }

    app.launch()
}


func testScreenshots() {
    app.tap()
    ...
}
like image 792
narner Avatar asked Sep 16 '25 15:09

narner


1 Answers

May not be too helpful, but this matches what I have (for allowing access to Location Services, so I wait for an "Allow" button.) The only difference is that the order I have is 1) let app= 2) add the monitor 3) launch app. All in setup(). The app.tap is in the func testApp(). XCUIApplication() creates a new instance of the app each time it is called: I think I'd try moving that before the monitor in the first instance. Here's my setup method (ignore the UITestHelper call):

override func setUp() {
    super.setUp()

    continueAfterFailure = false
    app = XCUIApplication()

    // ensure app is currently authorised.  If the first install is to
    // happen then the settings won't exist yet but that's ok, the test
    // will handle the Location Services prompt and allow.
    UITestHelper.resetAuthorisation(setToInUse: true)

    addUIInterruptionMonitor(withDescription: "Location Services")
    { (alert) -> Bool in if alert.buttons["Allow"].exists {
        alert.buttons["Allow"].tap()
        }
        return true }

    app.launch()
}

and my test:

func testDoesNotAlertReminderIfAuthorised() {

    // given

    // When
    app.tap()
 ....
like image 170
ad-johnson Avatar answered Sep 18 '25 08:09

ad-johnson