Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITesting of Alerts in xCode 7.1

I'm writing UITests in xCode 7.1 and have a problem in testing alerts (Allow notifications in my case). While creating a test xCode writes this code:

app.alerts["\U201cAppName\U201d Would Like to Send You Notifications"].collectionViews.buttons["OK"].tap()

Which immediately causes error:

Invalid escape sequence in literal

So I replaced xCode's code with:

app.alerts["\u{201c}AppName\u{201d} Would Like to Send You Notifications"].collectionViews.buttons["OK"].tap()

But when I run UITest it fails with message:

UI Testing Failure - No matches found for Alert

The same for code

app.alerts["“AppName” Would Like to Send You Notifications"].collectionViews.buttons["OK"].tap()

I also tried

app.alerts.collectionViews.buttons["OK"].tap()

as people advised here, but same story...

I believe many people faced with such an issue during UITesting in xCode 7.1

Please, share your experience or any suggestions for solving. Thanks in advance!

like image 343
Yurii Koval Avatar asked Nov 03 '15 16:11

Yurii Koval


2 Answers

See example below

import XCTest

let systemAlertHandlerDescription = "systemAlertHandlerDescription"

class LoginPerformingTestCase: XCTestCase {

var systemAlertMonitorToken: NSObjectProtocol? = nil

override func setUp() {
    continueAfterFailure = false

    let app = XCUIApplication()
    app.launchArguments = [TestingEnvironment.resetLaunchArgument, TestingEnvironment.testingEnvironmentArgument]
    app.launch()

    systemAlertMonitorToken = addUIInterruptionMonitorWithDescription(systemAlertHandlerDescription) { (alert) -> Bool in
        if alert.buttons.matchingIdentifier("OK").count > 0 {
            alert.buttons["OK"].tap()
            return true
        } else {
            return false
        }
    }
}

override func tearDown() {
    if let systemAlertMonitorToken = self.systemAlertMonitorToken {
        removeUIInterruptionMonitor(systemAlertMonitorToken)
    }

    super.tearDown()
}

func loginWithApp(app: XCUIApplication) {
    let signInButton = app.buttons["SIGN IN"]
    signInButton.tap()
    let emailAdressTextField = app.textFields.matchingIdentifier("EmailAddress").elementBoundByIndex(0)
    emailAdressTextField.tap()
    emailAdressTextField.typeText("[email protected]")

    let passwordSecureTextField = app.secureTextFields["Password"]
    passwordSecureTextField.tap()
    passwordSecureTextField.typeText("1111")
    signInButton.tap()

    let exists = NSPredicate(format: "exists == 1")
    let iconAlarmButton = app.buttons["icon alarm"]

    let expectation = expectationForPredicate(exists, evaluatedWithObject: iconAlarmButton, handler: nil)
    waitForExpectationsWithTimeout(60) { (error) -> Void in
        if let _ = error {
            expectation.fulfill()
        }
    }

    app.tap()//workaround to hide system alert
    let darkNavigaitonBar = app.otherElements.matchingIdentifier("darkNavigationView").elementBoundByIndex(0)
    if darkNavigaitonBar.hittable == true {
        app.tap()
    }

}

}
like image 163
Misha Vyrko Avatar answered Sep 28 '22 21:09

Misha Vyrko


Here is an example how to do it with an app requesting local notification permission access:

addUIInterruptionMonitorWithDescription("Local Dialog") { (alert) -> Bool in
     if alert.collectionViews.buttons["OK"].exists {
          alert.collectionViews.buttons["OK"].tap()
          return true
     }
     return false
}
like image 29
Samy Avatar answered Sep 28 '22 22:09

Samy