PIXEL
DOCK

I like the smell of Swift in the morning…

How to dismiss the phone call prompt during a Xcode UITest

Posted: | Author: | Filed under: iOS, Swift, UITests | No Comments »

Sometimes you offer your users the ability to make a phone call directly from your app. For example there could be a “Call Help Center” button that a user can press to make the call. When the user taps on that button the system will prompt a dialog where the user can either cancel or make the call.

When you write a UITest for this button you want to test that tapping the button will initiate the call. But you don’t actually want to make the call. So you need a way to cancel the call when the dialog shows up.

Normally you would add a UIInterruptionMonitor at the beginning of the UITest. This works for a lot of system dialogs (e.g. the dialog that asks the user for permission to use his location). But in this case it does not work. The UIInterruptionMonitor’s closure is never executed.

The reason is quite simple. UIInterruptionMonitor only works with dialogs that are presented by your app. All the permission dialogs are presented within your app’s scope, so the UIInterruptionMonitor can handle them. The phone call dialog however is presented from outside your app’s scope. You need to access the dialog via the Springboard which is now possible with Xcode 9.

You can test the help center button and dismiss dialog like this:

func testCallHelpCenterButton() {
    let app = XCUIApplication()
    let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")

    app.launch()
    app.buttons["Call Help Center"].tap()

    // check that the dialog is presented and tap the 'Cancel' button 
    let cancelButton = storyboard.buttons["Cancel"]
    XCTAssert(cancelButton.exists)
    cancelButton.tap()
}

Leave a Reply