UI Testing: dismissing a series of system alerts

As of Xcode 7.1 it is possible to register an UI Interuption Handler to handle system alerts, so you call something like this

addUIInterruptionMonitorWithDescription("System Alert") { (alert) -> Bool in 
alert.buttons["OK"].tap() 
return true 
}


and then you interact with the interface ie

.,
tap it.
app.tap()



This is all well and good but what if you are presented with a series of notifications one after another ie., location and push notifications alert?

I've tried everything I could think of e.g..

  • registering multiple handlers (only the first one gets called, in my case that would be the location dialog)
  • returning false in addUIInterruptionMonitoWithDescription -- nothing happens
  • tapping the app multiple times to "fire handlers"
  • delaying the app taps
  • adding handler(s) in the setUp function
  • dissming alerts with app.alerts.element.collectionViews.buttons["OK"].tap()
  • delaying multiple app.alerts.element.collectionViews.buttons["OK"].tap() //as suggested in this thread https://forums.developer.apple.com/thread/20626

and none of it worked. I just cant get past the second alert.


Similar reports, no working solution yet:


How to deal with this problem? Is it a bug or we are not handling it right?

It would be really helpful if someone from Apple comments on this.


Thank you.

Regards

Replies

I've been struggling with this as well and would LOVE to hear a solution or workaround.

Hello,



Had the same issue. App i'm testing has two UI popovers in a row that triggers two system alerts: Notifications and Contacts permission.


This is the workflow: UIPopover -> UIButton -> Notification Alert -> OK -> UIPopover -> UIButton -> Contacts Alert - OK -> next window

This is how I managed to deal with it:


let app = XCUIApplication()


if app.buttons["accessNotificationsUnderstandButton"].exists {

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

app.tap()

}

if app.buttons["accessContanctUnderstandButton"].exists {

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

}

app.cells["someCell"].tap()


First alert is skipping by 'app.tap()' the second one is mysteriously closing when I'm taping on app.cells["someCell"]. I don't use addUIInterruptionMonitorWithDescription handler. It's obviously a weird solution however it's the only one that works for me.

I would also love some feedback from Apple on this.


I have been down the same rabbit hole as OP with no amount of success.

I don’t know enough about UI testing to offer any input on the technical side of this question, alas, but I’d like to respond to this:

I would also love some feedback from Apple on this.

The best way to get official answers from Apple about thorny problems like this one is to open a DTS tech support incident.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I have submitted an Technical Support Incident ticket for hopefully resolving this issue.


I'll update this thread with whatever I find out.

I've just been struggling with this too, so let me just briefly explain my situation:

I have three alerts in series, and wanted to test them for different scenarios e.g. allow the first one, disallow the second alert etc., and I've been able to do it by using UIInterruptionMonitor.

After a little debugging, I've realised that the single UIInterruptionMonitor catches all system alerts that you present at the time, so that the command inside its completion handler is being applied on every alert ("Don't allow" or "OK"). So basically what I did is I've checked inside the completion handler what is the currently presented (and catched) alert, and apply specific action on it, and other action for other alerts. Then I've separated the rest of requirements in different test functions and everything was covered.

Here's small snippet for disallowing only second alert (in array of three), and allowing others:


       addUIInterruptionMonitor(withDescription: "Access to sound recording") { (alert) -> Bool in
            if alert.staticTexts["MyApp would like to use your microphone for recording your sound."].exists {
                alert.buttons["Don’t Allow"].tap()
            } else {
                alert.buttons["OK"].tap()
            }
            return true
        }
        app.tap()


Now you see how can you control all alerts separately, just by checking the alert's text inside monitor completion handler. The main thing that was blocking me to do it this way is because I thought that I need three monitors for three alerts, but instead all of them are caught inside one.

P.S. I'm on XCode 9.3, iOS 11.3


I hope this will help you and everyone 🙂

Any answer on your TSI?

Thanks for this! I was racking my brain with an exception I was getting trying to add multiple UIInterruptionMonitors and this worked beautifully!