Issue #48
Continue my post https://github.com/onmyway133/blog/issues/45. When you work with features, like map view, you mostly need permissions, and in UITests you need to test for system alerts.
Add interruption monitor
This is the code. Note that you need to call app.tap()
to interact with the app again, in order for interruption monitor to work
addUIInterruptionMonitor(withDescription: "Location permission", handler: { alert in
alert.buttons["Allow"].tap()
return true
})
app.tap()
Note that you don’t always need to handle the returned value of addUIInterruptionMonitor
Only tap when needed
One problem with this approach is that when there is no system alert (you already touched to allow before), then app.tap()
will tap on your main screen. In my app which uses map view, it will tap on some pins, which will present another screen, which is not correct.
Since app.alerts
does not work, my 2nd attempt is to check for app.windows.count
. Unfortunately, it always shows 5 windows whether alert is showing or not. I know 1 is for main window, 1 is for status bar, the other 3 windows I have no idea.
The 3rd attempt is to check that underlying elements (behind alert) can’t be touched, which is to use isHittable
. This property does not work, it always returns true
Check the content
This uses the assumption that we only tests for when user hits Allow
button. So only if alert is answered with Allow
, then we have permission to display our content. For my map view, I check that there are some pins on the map. See https://github.com/onmyway133/blog/issues/45 on how to mock location and identify the pins
if app.otherElements.matching(identifier: "myPin").count == 0 {
app.tap()
}
When there is no permission
So how can we test that user has denied your request? In my map view, if user does not allow location permission, I show a popup asking user to go to Settings and change it, otherwise, they can’t interact with the map.
I don’t know how to toggle location in Privacy
in Settings
, maybe XCUISiriService
can help. But 1 thing we can do is to mock the application
Before you launch the app in UITests
, add some arguments
app.launchArguments.append("--UITests-mockNoLocationPermission")
and in the app, we need to check for this arguments
func checkLocationPermission() {
if CommandLine.arguments.contains("--UITests-mockNoLocationPermission") {
showNoLocationPopupAndAskUserToEnableInSettings()
}
}
That’s it. In UITests
, we can test whether that no location permission popup
appears or not
Updated at 2020-06-02 02:12:36