Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode 7 UI Testing: Dismiss Push and Location alerts

I encountered a problem with Xcode 7 UI Testing.

The app displays two alerts after my user logs in, the Request Location Alert and the Push Notifications Alert. Those notifications are shown one right after the other. The Location one appears first.

I try to dismiss them automatically to start my tests.

In order to do that, I add two UIInterruptionMonitor, the first one for the Location Alert and the second one for the Notification Push Alert.

    addUIInterruptionMonitorWithDescription("Location Dialog") { (alert) -> Bool in         /* Dismiss Location Dialog */         if alert.collectionViews.buttons["Allow"].exists {             alert.collectionViews.buttons["Allow"].tap()             return true         }         return false     }     addUIInterruptionMonitorWithDescription("Push Dialog") { (alert) -> Bool in         /* Dismiss Push Dialog */         if alert.collectionViews.buttons["OK"].exists {             alert.collectionViews.buttons["OK"].tap()             return true         }         return false     } 

But only the Location one is triggered, the handler of Push Notifications UIInterruptionMonitor is never called.

If I return true in the Request Location UIInterruptionMonitor as this other post accepted answer specifies. Both handler are called but the alert parameter in both UIInterruptionMonitor links to the Request Location Alert View so the "OK" button is never found.

How can I dismiss those two successive alerts views?

like image 815
Thomas LEVY Avatar asked Nov 23 '15 16:11

Thomas LEVY


1 Answers

While not ideal, I found that if you simply wait until one authorization dialog has finished before presenting another one in the app, UI tests can pick up multiple requests in a row.

    if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse || CLLocationManager.authorizationStatus() == .AuthorizedAlways {         self.locationManager.requestLocation()     } else {         self.contactStore.requestAccessForEntityType(.Contacts) { _ in             self.locationManager.requestWhenInUseAuthorization()         }     } 

I'm actually requesting access to contacts in a different place in my code, but it can handle multiple simultaneous requests just fine.

Then in my test:

    addUIInterruptionMonitorWithDescription("Location Dialog") { (alert) -> Bool in         let button = alert.buttons["Allow"]         if button.exists {             button.tap()             return true         }         return false     }     addUIInterruptionMonitorWithDescription("Contacts Dialog") { (alert) -> Bool in         let button = alert.buttons["OK"]         if button.exists {             button.tap()             return true         }         return false     }      app.buttons["Location"].tap()      app.tap() // need to interact with the app for the handler to fire     app.tap() // need to interact with the app for the handler to fire 
like image 54
David Beck Avatar answered Oct 14 '22 21:10

David Beck