11import { spawn , type ChildProcess } from 'node:child_process' ;
2- import { setTimeout as delay } from 'node:timers/promises' ;
32import fs from 'node:fs' ;
43import path from 'node:path' ;
54
6- const HOST = '127.0.0.1' ;
7- const PORT = 4444 ;
85const READY_TIMEOUT_MS = 30_000 ;
9- const POLL_INTERVAL_MS = 250 ;
10- const STATUS_URL = `http://${ HOST } :${ PORT } /status` ;
6+ // The intermediary prints this marker to stdout once its listener is bound.
7+ // We can't HTTP-probe /status because the intermediary forwards /status to
8+ // the in-app server on :4445, which isn't spawned until a per-spec
9+ // `webdriverio.remote()` call delivers the binary-path capability — so any
10+ // pre-session HTTP probe fails by design.
11+ const READY_MARKER = / t a u r i - w e b d r i v e r r u n n i n g o n p o r t / i;
1112
1213const REPORTS_DIR = path . resolve ( './reports' ) ;
1314fs . mkdirSync ( REPORTS_DIR , { recursive : true } ) ;
@@ -23,53 +24,48 @@ export default async function globalSetup() {
2324 shell : process . platform === 'win32' ,
2425 } ) ;
2526
26- driver . stdout ?. on ( 'data' , ( chunk : Buffer ) => {
27- stdoutLog . write ( chunk ) ;
28- process . stdout . write ( chunk ) ;
29- } ) ;
30- driver . stderr ?. on ( 'data' , ( chunk : Buffer ) => {
31- stderrLog . write ( chunk ) ;
32- process . stderr . write ( chunk ) ;
33- } ) ;
34-
35- type ExitInfo = { code : number | null ; signal : NodeJS . Signals | null } ;
36- const exitState : { value : ExitInfo | null } = { value : null } ;
37- driver . once ( 'exit' , ( code , signal ) => {
38- exitState . value = { code, signal } ;
39- } ) ;
27+ const ready = new Promise < void > ( ( resolve , reject ) => {
28+ const timer = setTimeout ( ( ) => {
29+ reject (
30+ new Error (
31+ `tauri-webdriver did not print readiness marker within ${ READY_TIMEOUT_MS } ms. ` +
32+ `See ${ path . relative ( process . cwd ( ) , stderrPath ) } for driver output.` ,
33+ ) ,
34+ ) ;
35+ } , READY_TIMEOUT_MS ) ;
4036
41- const spawnFailed = new Promise < never > ( ( _ , reject ) => {
42- driver . once ( 'error' , ( err ) =>
43- reject ( new Error ( `tauri-webdriver failed to spawn: ${ ( err as Error ) . message } ` ) ) ,
44- ) ;
45- } ) ;
37+ let stdoutBuf = '' ;
38+ driver . stdout ?. on ( 'data' , ( chunk : Buffer ) => {
39+ stdoutLog . write ( chunk ) ;
40+ process . stdout . write ( chunk ) ;
41+ stdoutBuf += chunk . toString ( 'utf8' ) ;
42+ if ( READY_MARKER . test ( stdoutBuf ) ) {
43+ clearTimeout ( timer ) ;
44+ resolve ( ) ;
45+ }
46+ } ) ;
47+ driver . stderr ?. on ( 'data' , ( chunk : Buffer ) => {
48+ stderrLog . write ( chunk ) ;
49+ process . stderr . write ( chunk ) ;
50+ } ) ;
4651
47- const ready = ( async ( ) => {
48- const deadline = Date . now ( ) + READY_TIMEOUT_MS ;
49- while ( Date . now ( ) < deadline ) {
50- const exited = exitState . value ;
51- if ( exited ) {
52- throw new Error (
53- `tauri-webdriver exited during startup (code=${ exited . code } , signal=${ exited . signal } ). ` +
52+ driver . once ( 'error' , ( err ) => {
53+ clearTimeout ( timer ) ;
54+ reject ( new Error ( `tauri-webdriver failed to spawn: ${ ( err as Error ) . message } ` ) ) ;
55+ } ) ;
56+ driver . once ( 'exit' , ( code , signal ) => {
57+ clearTimeout ( timer ) ;
58+ reject (
59+ new Error (
60+ `tauri-webdriver exited during startup (code=${ code } , signal=${ signal } ). ` +
5461 `See ${ path . relative ( process . cwd ( ) , stderrPath ) } for driver output.` ,
55- ) ;
56- }
57- try {
58- const res = await fetch ( STATUS_URL , { signal : AbortSignal . timeout ( 1_000 ) } ) ;
59- if ( res . ok ) return ;
60- } catch {
61- // not yet — keep polling
62- }
63- await delay ( POLL_INTERVAL_MS ) ;
64- }
65- throw new Error (
66- `tauri-webdriver did not become ready on ${ STATUS_URL } within ${ READY_TIMEOUT_MS } ms. ` +
67- `See ${ path . relative ( process . cwd ( ) , stderrPath ) } for driver output.` ,
68- ) ;
69- } ) ( ) ;
62+ ) ,
63+ ) ;
64+ } ) ;
65+ } ) ;
7066
7167 try {
72- await Promise . race ( [ ready , spawnFailed ] ) ;
68+ await ready ;
7369 } catch ( err ) {
7470 if ( driver . exitCode === null && ! driver . killed ) driver . kill ( 'SIGTERM' ) ;
7571 stdoutLog . end ( ) ;
0 commit comments