Is it possible in XCUITest to validate that a notification banner is sent to the screen?
I can add an accessibility identifier to the notification, but I am having a problem getting XCUITest to interact with it when the banner is ent to the screen. I know that XCUITest runs in a separate process from the app, but was wondeering if it was still possible to interact with the notification or is it beyond the scope of XCUITest?
Thanks,
With Xcode 9 this is now possible. You can get access to other apps. That includes the springboard which contains the Notification banner.
XCUIApplication
now has a new initializer that takes a bundle identifier as parameter. It gives you a reference to the app that uses that bundle identifier. You can then use the normal queries to access UI elements. Just like you did before with your own app.
This is a test that checks if a Local Notification is being displayed when the app is closed:
import XCTest
class UserNotificationUITests: XCTestCase {
override func setUp() {
super.setUp()
continueAfterFailure = false
}
func testIfLocalNotificationIsDisplayed() {
let app = XCUIApplication()
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
app.launch()
// close app to trigger local notification
XCUIDevice.shared.press(XCUIDevice.Button.home)
// wait for the notification
let localNotification = springboard.otherElements["USERNOTIFICATION, now, Buy milk!, Remember to buy milk from store!"]
XCTAssertEqual(waiterResultWithExpectation(localNotification), XCTWaiter.Result.completed)
}
}
extension UserNotificationUITests {
func waiterResultWithExpectation(_ element: XCUIElement) -> XCTWaiter.Result {
let myPredicate = NSPredicate(format: "exists == true")
let myExpectation = XCTNSPredicateExpectation(predicate: myPredicate,
object: element)
let result = XCTWaiter().wait(for: [myExpectation], timeout: 6)
return result
}
}
You can checkout the demo app including this test here
You can also test Remote Notifications with UITests. That's needs a bit more work, because you cannot directly schedule Remote Notifications from your code. You can use a service called NWPusher for that. I wrote a blogpost about how to test Remote Notifications with Xcode UITests and there also is a demo project on github.
Xcode 12 iOS 14*
Also accessing/asserting inside the notification is possible:
let notification = springBoard.otherElements["Notification"].descendants(matching: .any)["APPNAME, now, TITLE, BODY"]
if notification.waitForExistence(timeout: 10) {
notification.tap()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With