@@ -20,6 +20,9 @@ const chromePath =
2020 process . env . CHROME_PATH ??
2121 "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ;
2222const debugPort = Number ( process . env . SIMDECK_E2E_CHROME_PORT ?? 9339 ) ;
23+ const chromeStartupTimeoutMs = Number (
24+ process . env . SIMDECK_E2E_CHROME_STARTUP_MS ?? 60_000 ,
25+ ) ;
2326const maxFrameGapMs = Number ( process . env . SIMDECK_E2E_MAX_FRAME_GAP_MS ?? 250 ) ;
2427const maxInteractionLatencyMs = Number (
2528 process . env . SIMDECK_E2E_MAX_INTERACTION_LATENCY_MS ?? 750 ,
@@ -112,17 +115,42 @@ async function fetchReferenceScreenshotDataUrl(udid) {
112115 return `data:${ contentType } ;base64,${ base64 } ` ;
113116}
114117
115- async function waitForDevTools ( ) {
118+ async function waitForDevTools ( chromeProcess , getChromeOutput , getSpawnError ) {
116119 const versionUrl = `http://127.0.0.1:${ debugPort } /json/version` ;
117120 const startedAt = Date . now ( ) ;
118- while ( Date . now ( ) - startedAt < 10_000 ) {
121+ while ( Date . now ( ) - startedAt < chromeStartupTimeoutMs ) {
122+ const spawnError = getSpawnError ( ) ;
123+ if ( spawnError ) {
124+ throw new Error (
125+ [ `Chrome failed to start: ${ spawnError . message } ` , getChromeOutput ( ) ]
126+ . filter ( Boolean )
127+ . join ( "\n" ) ,
128+ ) ;
129+ }
130+ if ( chromeProcess . exitCode !== null || chromeProcess . signalCode !== null ) {
131+ throw new Error (
132+ [
133+ `Chrome exited before DevTools became available (exit=${ chromeProcess . exitCode } , signal=${ chromeProcess . signalCode } ).` ,
134+ getChromeOutput ( ) ,
135+ ]
136+ . filter ( Boolean )
137+ . join ( "\n" ) ,
138+ ) ;
139+ }
119140 try {
120141 return await fetchJson ( versionUrl ) ;
121142 } catch {
122143 await sleep ( 100 ) ;
123144 }
124145 }
125- throw new Error ( "Timed out waiting for Chrome DevTools endpoint." ) ;
146+ throw new Error (
147+ [
148+ `Timed out waiting ${ chromeStartupTimeoutMs } ms for Chrome DevTools endpoint at ${ versionUrl } .` ,
149+ getChromeOutput ( ) ,
150+ ]
151+ . filter ( Boolean )
152+ . join ( "\n" ) ,
153+ ) ;
126154}
127155
128156function sleep ( ms ) {
@@ -435,6 +463,7 @@ function latestByKind(streams, kind) {
435463const profileDir = await mkdtemp ( join ( tmpdir ( ) , "simdeck-webrtc-e2e-" ) ) ;
436464const chromeArgs = [
437465 `--remote-debugging-port=${ debugPort } ` ,
466+ "--remote-debugging-address=127.0.0.1" ,
438467 `--user-data-dir=${ profileDir } ` ,
439468 "--no-first-run" ,
440469 "--no-default-browser-check" ,
@@ -450,16 +479,27 @@ if (process.env.SIMDECK_E2E_HEADFUL !== "1") {
450479}
451480
452481const chrome = spawn ( chromePath , chromeArgs , {
453- stdio : [ "ignore" , "ignore " , "pipe" ] ,
482+ stdio : [ "ignore" , "pipe " , "pipe" ] ,
454483} ) ;
455- let chromeStderr = "" ;
484+ let chromeOutput = "" ;
485+ let chromeSpawnError = null ;
456486let cdp ;
487+ chrome . stdout . on ( "data" , ( chunk ) => {
488+ chromeOutput += chunk . toString ( ) ;
489+ } ) ;
457490chrome . stderr . on ( "data" , ( chunk ) => {
458- chromeStderr += chunk . toString ( ) ;
491+ chromeOutput += chunk . toString ( ) ;
492+ } ) ;
493+ chrome . on ( "error" , ( error ) => {
494+ chromeSpawnError = error ;
459495} ) ;
460496
461497try {
462- await waitForDevTools ( ) ;
498+ await waitForDevTools (
499+ chrome ,
500+ ( ) => chromeOutput . trim ( ) ,
501+ ( ) => chromeSpawnError ,
502+ ) ;
463503 const target = await createPageTarget ( "about:blank" ) ;
464504 cdp = await connectCdp ( target . webSocketDebuggerUrl ) ;
465505 await cdp . send ( "Page.enable" ) ;
@@ -853,7 +893,7 @@ async function waitForValue(cdp, expression, predicate, timeoutMs) {
853893 await sleep ( 250 ) ;
854894 }
855895 throw new Error (
856- `Timed out waiting for expression: ${ expression } \n${ chromeStderr } ` ,
896+ `Timed out waiting for expression: ${ expression } \n${ chromeOutput } ` ,
857897 ) ;
858898}
859899
0 commit comments