Xcode 7 UI Testing: how to dismiss a series of system alerts in code
Xcode 7.1
Xcode 7.1 has finally fixed the issue with system alerts. There are, however, two small gotchas.
First, you need to set up a "UI Interuption Handler" before presenting the alert. This is our way of telling the framework how to handle an alert when it appears.
Second, after presenting the alert you must interact with the interface. Simply tapping the app works just fine, but is required.
addUIInterruptionMonitorWithDescription("Location Dialog") { (alert) -> Bool in
alert.buttons["Allow"].tap()
return true
}
app.buttons["Request Location"].tap()
app.tap() // need to interact with the app for the handler to fire
The "Location Dialog" is just a string to help the developer identify which handler was accessed, it is not specific to the type of alert.
I believe that returning true
from the handler marks it as "complete", which means it won't be called again. For your situation I would try returning false
so the second alert will trigger the handler again.
Xcode 7.0
The following will dismiss a single "system alert" in Xcode 7 Beta 6:
let app = XCUIApplication()
app.launch()
// trigger location permission dialog
app.alerts.element.collectionViews.buttons["Allow"].tap()
Beta 6 introduced a slew of fixes for UI Testing and I believe this was one of them.
Also note that I am calling -element
directly on -alerts
. Calling -element
on an XCUIElementQuery
forces the framework to choose the "one and only" matching element on the screen. This works great for alerts where you can only have one visible at a time. However, if you try this for a label and have two labels the framework will raise an exception.
Is it possible to dismiss System Alerts using EarlGrey (iOS UI Testing)?
As the docs for grey_systemAlertViewShown indicate, grey_systemAlertViewShown merely checks to see if system alert views are shown. A better usage of the API would be to assert that system alert is not shown (maybe because the test app has mocked out the code that causes system alerts).
Code that taps a button that requests causes system alert to be shown (for ex: requests user's geo location) comes here...
// Assert that in the test app system alert view is not shown because we have mocked out the part of code that requests user location.
[[EarlGrey selectElementWithMatcher:grey_anything()] assertWithMatcher:grey_not(grey_systemAlertViewShown())];
As of this writing system alert views cannot be dismissed by EarlGrey. Alertviews that are launched by the app can be dismissed. The FAQ has a question that indicates that EarlGrey tests will fail if modal dialogs are present.
How to dismiss a system dialog during a Xcode UITest
So your real problem is to get rid of the system dialog when running UITests. Running UITests before UnitTests won't change a thing, because then the system dialog would pop up during the UITest.
You can dismiss the dialog like this (in your UITest):
addUIInterruptionMonitor(withDescription: "“RemoteNotification” Would Like to Send You Notifications") { (alerts) -> Bool in
if(alerts.buttons["Allow"].exists){
alerts.buttons["Allow"].tap();
}
return true;
}
XCUIApplication().tap()
You have to change the description because the above code dismisses a system alert that asks for permission to send push notifications.
It is important that this code comes BEFORE your test triggers the system dialog. You can put it inside your test function right after you launch the app and before the test does anything else.
Related Topics
Uitableview - Scroll to the Top
How to Update a Localized Storyboard's Strings
Duplicate Symbol Error in Nsmanagedobject Subclass
How to Style Uitextview to Like Rounded Rect Text Field
iPhone "Slide to Unlock" Animation
Saving Email/Password to Keychain in iOS
What Does "@Private" Mean in Objective-C
Building for iOS Simulator, But the Linked Framework '****.Framework' Was Built for iOS
Ibeacon Notification When the App Is Not Running
How to Store an Image in Core Data
Pod Install -Bash: Pod: Command Not Found
iOS Enterprise Distribution Through Ota
How to Fetch All Contacts Record in iOS 9 Using Contacts Framework
How to Prevent Duplicate Entry on Parse
iOS 10 Error [Access] <Private> When Using Uiimagepickercontroller
Example for Login Screen Modally Based on Storyboard
Conversion from Nstimeinterval to Hour,Minutes,Seconds,Milliseconds in Swift