I've spent several hours trying every possible solution I've seen without success, I hope I have more luck asking directly.
I'm using XCode 13.2.1 and I'm testing with an iPhone X (iOS 15.3.1).
I want to make a XCTest that send a push notification to my (killed) app, then the test opens the notification, make click on it, and the app opens showing a specific view.
So far, I managed to send the push notification, it's shown in the device just a second after the test send it, and then it dissapears. If I manually open the notification center, then the notification is there, ok.
But I haven't been able to click on the notification. This is what I tried:
Test 1: Notification dissapears and it's not clicked.
func testWhenPushNotificationOpenThenCorrectPageIsShown() {
sendPushNotification()
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
springboard.otherElements["MyApp, now, My notification text"].tap()
}
Test 2: Notification dissapears and it's not clicked.
func testWhenPushNotificationOpenThenCorrectPageIsShown() {
sendPushNotification()
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
springboard.otherElements["Notification"].descendants(matching: .any)["NotificationShortLookView"].tap()
}
Test 3: Notification dissapears and it's not clicked.
func testWhenPushNotificationOpenThenCorrectPageIsShown() {
sendPushNotification()
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
springboard.otherElements["Notification"].firstMatch.tap()
}
I tested these 3 cases adding springboard.activate() too.
I thought on opening the notification center making sweep from the status bar doing this:
Test 4: Notification dissapears, the notification center is shown, with the push notification in it, but I don't know how to make click on it (taking into account that when I manually click on this notification it shows an "Open" button that I must click to open the app).
func testWhenPushNotificationOpenThenCorrectPageIsShown() {
sendPushNotification()
let app = XCUIApplication()
app.launch()
let coord1 = app.coordinate(withNormalizedOffset: CGVector(dx: 0.1, dy: 0.01))
let coord2 = app.coordinate(withNormalizedOffset: CGVector(dx: 0.1, dy: 0.8))
coord1.press(forDuration: 0.1, thenDragTo: coord2)
}
Finally I tried to change my app notification settings to make them persistent. Now when the device received it, it doesn't dissappears but with every test detailed above I have no success, the notification is not clicked.
With the notification persistent I logged the springboard content and this is what I get regarding to the push notification:
springboard.debugDescription
Attributes: Application, 0x127f137a0, pid: 62, label: ' '
Element subtree:
→Application, 0x127f137a0, pid: 62, label: ' '
...
Window (Main), 0x129a20120, {{0.0, 0.0}, {375.0, 812.0}}
Other, 0x129a20230, {{0.0, 0.0}, {375.0, 812.0}}
Other, 0x129a0ff60, {{0.0, 0.0}, {375.0, 812.0}}
BannerNotification, 0x129a10070, {{8.0, 40.0}, {359.0, 75.3}}
Other, 0x129a12620, {{8.0, 40.0}, {359.0, 75.3}}, label: 'Notification'
Other, 0x129a12730, {{8.0, 40.0}, {359.0, 75.3}}
BannerNotification, 0x129a071f0, {{8.0, 40.0}, {359.0, 75.3}}, identifier: 'NotificationShortLookView', label: 'MyApp, now, My notification text'
I don't like this last option because I have to manually set the persistent mode for my notifications (I guess it's not possible to do it programmatically), but if it's the best option I would choose it.
What could I try?
EDIT: I've tried this:
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
let notif = springboard.otherElements["Notification"].descendants(matching: .any)["NotificationShortLookView"]
print(notif.debugDescription)
notif.tap()
The log of notif.debugDescription shows this:
Attributes: BannerNotification, 0x1037413e0, {{8.0, 40.0}, {359.0, 75.3}}, identifier: 'NotificationShortLookView', label: 'MyApp, now, My notification text'
Element subtree:
→BannerNotification, 0x1037413e0, {{8.0, 40.0}, {359.0, 75.3}}, identifier: 'NotificationShortLookView', label: 'MyApp, now, My notification text'
Path to element:
→Application, 0x10372c7e0, pid: 62, label: ' '
↳Window (Main), 0x103740d80, {{0.0, 0.0}, {375.0, 812.0}}
↳Other, 0x103740e90, {{0.0, 0.0}, {375.0, 812.0}}
↳Other, 0x103740fa0, {{0.0, 0.0}, {375.0, 812.0}}
↳BannerNotification, 0x1037410b0, {{8.0, 40.0}, {359.0, 75.3}}
↳Other, 0x1037411c0, {{8.0, 40.0}, {359.0, 75.3}}, label: 'Notification'
↳Other, 0x1037412d0, {{8.0, 40.0}, {359.0, 75.3}}
↳BannerNotification, 0x1037413e0, {{8.0, 40.0}, {359.0, 75.3}}, identifier: 'NotificationShortLookView', label: 'MyApp, now, My notification text'
There, it appears the notifation, but again the notif.tap() gives me a crash with notif cannot be nil error.
I think I'm close to the solution but I'm missing something.
You were almost there with your 3rd attempt. This is what consistently works for me in my project on iOS 14.5 and 15.5:
without using
firstMatch.