1- import { test , expect , type Page } from '@playwright/test'
1+ import { test , expect , type Page , type Route } from '@playwright/test'
22import * as fs from 'fs'
33import * as path from 'path'
44import { fileURLToPath } from 'url'
@@ -135,10 +135,13 @@ const EVALUATE_RETRY_DELAY_MS = 500
135135 */
136136const BATCH_NAV_TIMEOUT_MS = process . env . CI ? 90_000 : 45_000
137137/**
138- * Overall test timeout (ms). 300s base × 2 CI multiplier = 600s, matching
139- * the suite wall-clock cap in run-all-tests.sh (#9101).
138+ * Overall test timeout (ms). The cache suite now covers 347 cards across 15
139+ * batches, so the previous 600s CI cap was too tight: the report finished
140+ * writing, then run-all-tests.sh killed the suite at the wall-clock limit.
141+ * 450s base × 2 CI multiplier = 900s to leave headroom for nightly runner
142+ * jitter without relaxing the cache assertions themselves (#15933).
140143 */
141- const CACHE_TEST_TIMEOUT_MS = 300_000
144+ const CACHE_TEST_TIMEOUT_MS = 450_000
142145const CI_TIMEOUT_MULTIPLIER = 2
143146/**
144147 * Maximum acceptable median warm time-to-content (ms).
@@ -162,6 +165,7 @@ const STORAGE_CLEANUP_TIMEOUT_MS = 5_000
162165const STORAGE_CLEANUP_POLL_INTERVAL_MS = 100
163166const STORAGE_CLEANUP_POLL_ATTEMPTS = 20
164167const COLD_BATCH_RESET_WINDOW_NAME = '__kc-cache-test-cold-reset__'
168+ const EMPTY_SSE_BODY = ': keep-alive\n\n'
165169const COLD_BATCH_KEEP_LOCAL_STORAGE_KEYS = [
166170 'token' ,
167171 'kc-demo-mode' ,
@@ -696,13 +700,24 @@ function writeReport(report: CacheComplianceReport, outDir: string) {
696700// Main test
697701// ---------------------------------------------------------------------------
698702
703+ function fulfillSkippedRoute ( route : Route ) {
704+ const acceptHeader = route . request ( ) . headers ( ) . accept || ''
705+ const isStreamRequest = route . request ( ) . url ( ) . includes ( '/stream' ) || acceptHeader . includes ( 'text/event-stream' )
706+
707+ return route . fulfill ( {
708+ status : 200 ,
709+ contentType : isStreamRequest ? 'text/event-stream' : 'application/json' ,
710+ body : isStreamRequest ? EMPTY_SSE_BODY : '{}' ,
711+ } )
712+ }
713+
699714test . describe . configure ( { mode : 'serial' } )
700715
701716test ( 'card cache compliance — storage and retrieval' , async ( { page } , testInfo ) => {
702- // 300s base × 2 CI multiplier = 600s, matching the suite wall-clock cap in
703- // run-all-tests.sh. No testInfo.setTimeout was set before (#9101) , so the
704- // test ran against the global config timeout (1200s) which meant timeout
705- // errors only surfaced as wall-clock kills .
717+ // 450s base × 2 CI multiplier = 900s, aligned with run-all-tests.sh. The
718+ // suite now renders 347 cards across 15 batches , so the old 600s ceiling
719+ // could kill the run after report generation even when cache assertions
720+ // already passed (#15933) .
706721 testInfo . setTimeout ( process . env . CI ? CACHE_TEST_TIMEOUT_MS * CI_TIMEOUT_MULTIPLIER : CACHE_TEST_TIMEOUT_MS )
707722
708723 const allBatchResults : Array < { batchIndex : number ; cards : CardCacheResult [ ] } > = [ ]
@@ -730,7 +745,7 @@ test('card cache compliance — storage and retrieval', async ({ page }, testInf
730745 '**/api/self-upgrade/**' , '**/api/admin/**' , '**/api/acmm/**' ,
731746 ]
732747 for ( const pattern of skipRoutePatterns ) {
733- await page . route ( pattern , ( route ) => route . fulfill ( { status : 200 , contentType : 'application/json' , body : '{}' } ) )
748+ await page . route ( pattern , fulfillSkippedRoute )
734749 }
735750
736751 await setLiveColdMode ( page )
0 commit comments