@@ -27,6 +27,7 @@ import {config} from 'dotenv'
2727import * as path from 'path'
2828import { fileURLToPath } from 'url'
2929import { chromium } from '@playwright/test'
30+ import { BROWSER_TIMEOUT } from '../setup/constants.js'
3031import { navigateToDashboard } from '../setup/browser.js'
3132import { completeLogin } from '../helpers/browser-login.js'
3233import type { Page } from '@playwright/test'
@@ -96,8 +97,8 @@ export async function cleanupAllApps(opts: CleanupOptions = {}): Promise<void> {
9697 'X-Shopify-Loadtest-Bf8d22e7-120e-4b5b-906c-39ca9d5499a9' : 'true' ,
9798 } ,
9899 } )
99- context . setDefaultTimeout ( 30_000 )
100- context . setDefaultNavigationTimeout ( 30_000 )
100+ context . setDefaultTimeout ( BROWSER_TIMEOUT . max )
101+ context . setDefaultNavigationTimeout ( BROWSER_TIMEOUT . max )
101102 const page = await context . newPage ( )
102103
103104 try {
@@ -182,7 +183,7 @@ export async function cleanupAllApps(opts: CleanupOptions = {}): Promise<void> {
182183 const msg = err instanceof Error ? err . message : String ( err )
183184 if ( attempt <= maxRetries ) {
184185 console . warn ( ` Attempt ${ attempt } failed: ${ msg } ` )
185- await page . waitForTimeout ( 3000 )
186+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
186187 } else {
187188 console . warn ( ` Failed: ${ msg } ` )
188189 }
@@ -238,12 +239,12 @@ async function findAppsOnDashboard(
238239
239240 // Check for next page — navigate via href since the button click may not work
240241 const nextLink = page . locator ( 'a[href*="next_cursor"]' ) . first ( )
241- if ( ! ( await nextLink . isVisible ( { timeout : 2000 } ) . catch ( ( ) => false ) ) ) break
242+ if ( ! ( await nextLink . isVisible ( { timeout : BROWSER_TIMEOUT . medium } ) . catch ( ( ) => false ) ) ) break
242243 const nextHref = await nextLink . getAttribute ( 'href' )
243244 if ( ! nextHref ) break
244245 const nextUrl = nextHref . startsWith ( 'http' ) ? nextHref : `https://dev.shopify.com${ nextHref } `
245246 await page . goto ( nextUrl , { waitUntil : 'domcontentloaded' } )
246- await page . waitForTimeout ( 3000 )
247+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
247248 }
248249
249250 return apps
@@ -257,7 +258,7 @@ async function uninstallApp(
257258 orgId : string ,
258259) : Promise < boolean > {
259260 await page . goto ( `${ appUrl } /installs` , { waitUntil : 'domcontentloaded' } )
260- await page . waitForTimeout ( 3000 )
261+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
261262
262263 const rows = await page . locator ( 'table tbody tr' ) . all ( )
263264 const storeNames : string [ ] = [ ]
@@ -276,14 +277,14 @@ async function uninstallApp(
276277 let navigated = false
277278 for ( let attempt = 1 ; attempt <= 3 ; attempt ++ ) {
278279 const orgButton = page . locator ( 'button[popovertarget="store-switcher-popover"]' ) . first ( )
279- if ( ! ( await orgButton . isVisible ( { timeout : 5000 } ) . catch ( ( ) => false ) ) ) continue
280+ if ( ! ( await orgButton . isVisible ( { timeout : BROWSER_TIMEOUT . long } ) . catch ( ( ) => false ) ) ) continue
280281 await orgButton . click ( )
281- await page . waitForTimeout ( 1000 )
282+ await page . waitForTimeout ( BROWSER_TIMEOUT . short )
282283
283284 const storeLink = page . locator ( 'a, button' ) . filter ( { hasText : storeName } ) . first ( )
284- if ( ! ( await storeLink . isVisible ( { timeout : 5000 } ) . catch ( ( ) => false ) ) ) continue
285+ if ( ! ( await storeLink . isVisible ( { timeout : BROWSER_TIMEOUT . long } ) . catch ( ( ) => false ) ) ) continue
285286 await storeLink . click ( )
286- await page . waitForTimeout ( 3000 )
287+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
287288 navigated = true
288289 break
289290 }
@@ -296,41 +297,41 @@ async function uninstallApp(
296297 // Navigate to store's apps settings page
297298 const storeAdminUrl = page . url ( )
298299 await page . goto ( `${ storeAdminUrl . replace ( / \/ $ / , '' ) } /settings/apps` , { waitUntil : 'domcontentloaded' } )
299- await page . waitForTimeout ( 5000 )
300+ await page . waitForTimeout ( BROWSER_TIMEOUT . long )
300301
301302 // Dismiss any Dev Console dialog
302303 const cancelButton = page . locator ( 'button:has-text("Cancel")' )
303- if ( await cancelButton . isVisible ( { timeout : 2000 } ) . catch ( ( ) => false ) ) {
304+ if ( await cancelButton . isVisible ( { timeout : BROWSER_TIMEOUT . medium } ) . catch ( ( ) => false ) ) {
304305 await cancelButton . click ( )
305- await page . waitForTimeout ( 1000 )
306+ await page . waitForTimeout ( BROWSER_TIMEOUT . short )
306307 }
307308
308309 // Find the app in the installed list
309310 const appSpan = page . locator ( `span:has-text("${ appName } "):not([class*="Polaris"])` ) . first ( )
310- if ( ! ( await appSpan . isVisible ( { timeout : 5000 } ) . catch ( ( ) => false ) ) ) {
311+ if ( ! ( await appSpan . isVisible ( { timeout : BROWSER_TIMEOUT . max } ) . catch ( ( ) => false ) ) ) {
311312 allUninstalled = false
312313 continue
313314 }
314315
315316 // Click the ⋯ menu button next to the app name
316317 const menuButton = appSpan . locator ( 'xpath=./following::button[1]' )
317318 await menuButton . click ( )
318- await page . waitForTimeout ( 1000 )
319+ await page . waitForTimeout ( BROWSER_TIMEOUT . short )
319320
320321 // Click "Uninstall" in the dropdown menu
321322 const uninstallOption = page . locator ( 'text=Uninstall' ) . last ( )
322- if ( ! ( await uninstallOption . isVisible ( { timeout : 3000 } ) . catch ( ( ) => false ) ) ) {
323+ if ( ! ( await uninstallOption . isVisible ( { timeout : BROWSER_TIMEOUT . medium } ) . catch ( ( ) => false ) ) ) {
323324 allUninstalled = false
324325 continue
325326 }
326327 await uninstallOption . click ( )
327- await page . waitForTimeout ( 2000 )
328+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
328329
329330 // Handle confirmation dialog
330331 const confirmButton = page . locator ( 'button:has-text("Uninstall"), button:has-text("Confirm")' ) . last ( )
331- if ( await confirmButton . isVisible ( { timeout : 3000 } ) . catch ( ( ) => false ) ) {
332+ if ( await confirmButton . isVisible ( { timeout : BROWSER_TIMEOUT . medium } ) . catch ( ( ) => false ) ) {
332333 await confirmButton . click ( )
333- await page . waitForTimeout ( 3000 )
334+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
334335 }
335336 } catch ( _err ) {
336337 allUninstalled = false
@@ -343,32 +344,32 @@ async function uninstallApp(
343344/** Delete an app from the dev dashboard settings page. */
344345async function deleteApp ( page : Page , appUrl : string ) : Promise < void > {
345346 await page . goto ( `${ appUrl } /settings` , { waitUntil : 'domcontentloaded' } )
346- await page . waitForTimeout ( 3000 )
347+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
347348
348349 // Retry if delete button is disabled (uninstall propagation delay)
349350 const deleteButton = page . locator ( 'button:has-text("Delete app")' ) . first ( )
350351 for ( let attempt = 1 ; attempt <= 5 ; attempt ++ ) {
351352 await deleteButton . scrollIntoViewIfNeeded ( )
352353 const isDisabled = await deleteButton . getAttribute ( 'disabled' )
353354 if ( ! isDisabled ) break
354- await page . waitForTimeout ( 5000 )
355+ await page . waitForTimeout ( BROWSER_TIMEOUT . long )
355356 await page . reload ( { waitUntil : 'domcontentloaded' } )
356- await page . waitForTimeout ( 3000 )
357+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
357358 }
358359
359- await deleteButton . click ( { timeout : 10_000 } )
360- await page . waitForTimeout ( 2000 )
360+ await deleteButton . click ( { timeout : BROWSER_TIMEOUT . max } )
361+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
361362
362363 // Handle confirmation dialog — may need to type "DELETE"
363364 const confirmInput = page . locator ( 'input[type="text"]' ) . last ( )
364- if ( await confirmInput . isVisible ( { timeout : 3000 } ) . catch ( ( ) => false ) ) {
365+ if ( await confirmInput . isVisible ( { timeout : BROWSER_TIMEOUT . medium } ) . catch ( ( ) => false ) ) {
365366 await confirmInput . fill ( 'DELETE' )
366- await page . waitForTimeout ( 500 )
367+ await page . waitForTimeout ( BROWSER_TIMEOUT . short )
367368 }
368369
369370 const confirmButton = page . locator ( 'button:has-text("Delete app")' ) . last ( )
370371 await confirmButton . click ( )
371- await page . waitForTimeout ( 3000 )
372+ await page . waitForTimeout ( BROWSER_TIMEOUT . medium )
372373}
373374
374375// ---------------------------------------------------------------------------
0 commit comments