@@ -134,7 +134,6 @@ export async function waitForAppReady(opts: { skipLogin?: boolean } = {}) {
134134
135135 const alertHandled = await browser . sharedStore . get ( 'alertHandled' ) ;
136136 if ( ! alertHandled ) {
137- await driver . pause ( 5_000 ) ; // TOOD: remove
138137 const alert = await waitForAlert ( ) ;
139138 if ( alert ) await driver . acceptAlert ( ) ;
140139 await browser . sharedStore . set ( 'alertHandled' , true ) ;
@@ -221,6 +220,29 @@ export async function expectPairInSection(sectionId: string, key: string, value:
221220 expect ( valueText ) . toContain ( value ) ;
222221}
223222
223+ /**
224+ * Lock the iOS screen and wake it to reveal the lock screen (with notifications).
225+ */
226+ export async function lockScreen ( ) {
227+ await driver . updateSettings ( { defaultActiveApplication : 'com.apple.springboard' } ) ;
228+ await driver . lock ( ) ;
229+ await driver . pause ( 500 ) ;
230+
231+ await driver . execute ( 'mobile: pressButton' , { name : 'home' } ) ;
232+ await driver . pause ( 500 ) ;
233+ }
234+
235+ /**
236+ * Return to the app from SpringBoard / lock screen.
237+ */
238+ export async function returnToApp ( ) {
239+ const caps = driver . capabilities as Record < string , unknown > ;
240+ const bundleId = ( caps [ 'bundleId' ] ?? caps [ 'appium:bundleId' ] ) as string ;
241+ await driver . updateSettings ( { defaultActiveApplication : bundleId } ) ;
242+ await driver . execute ( 'mobile: activateApp' , { bundleId } ) ;
243+ await driver . pause ( 1_000 ) ;
244+ }
245+
224246/**
225247 * Clear all notifications.
226248 * Android: uses the native clearAllNotifications command.
@@ -241,9 +263,8 @@ export async function clearAllNotifications() {
241263 * Android: opens the notification shade, verifies the title (and optionally
242264 * body) are visible, then closes the shade.
243265 *
244- * iOS: goes to the home screen, switches to the SpringBoard context, then
245- * uses W3C touch actions (viewport origin) to swipe down and open the
246- * notification center. After verifying the notification, it returns to the app.
266+ * iOS: swipes down from the top-left to open the notification center,
267+ * verifies the notification, then returns to the app.
247268 */
248269export async function waitForNotification ( opts : {
249270 title : string ;
@@ -303,19 +324,13 @@ export async function waitForNotification(opts: {
303324 return ;
304325 }
305326
306- // iOS: swipe down from the top-left of the screen to open notification center
327+ // iOS: swipe down from the top-left to open notification center
307328 // (top-right opens Control Center on iOS 16+)
308- const caps = driver . capabilities as Record < string , unknown > ;
309- const bundleId = ( caps [ 'bundleId' ] ?? caps [ 'appium:bundleId' ] ) as string ;
329+ await driver . updateSettings ( { defaultActiveApplication : 'com.apple.springboard' } ) ;
310330
311331 await driver . execute ( 'mobile: pressButton' , { name : 'home' } ) ;
312332 await driver . pause ( 1_000 ) ;
313333
314- await driver . updateSettings ( {
315- defaultActiveApplication : 'com.apple.springboard' ,
316- } ) ;
317- await driver . pause ( 500 ) ;
318-
319334 const { width, height } = await driver . getWindowSize ( ) ;
320335 await driver . performActions ( [
321336 {
@@ -378,11 +393,7 @@ export async function waitForNotification(opts: {
378393 await image . waitForDisplayed ( { timeout : 5_000 } ) ;
379394 }
380395
381- await driver . execute ( 'mobile: pressButton' , { name : 'home' } ) ;
382- await driver . pause ( 500 ) ;
383-
384- await driver . updateSettings ( { defaultActiveApplication : bundleId } ) ;
385- await driver . execute ( 'mobile: activateApp' , { bundleId } ) ;
396+ await returnToApp ( ) ;
386397}
387398
388399export async function checkNotification ( opts : {
0 commit comments