@@ -5,8 +5,8 @@ import { constants as fsConstants } from 'node:fs';
55import { chromium } from '@playwright/test' ;
66
77const HOST = process . env . REPRO_HOST || '127.0.0.1' ;
8- const PORT = Number ( process . env . REPRO_PORT || '4173 ' ) ;
9- const BASE_URL = `http:// ${ HOST } : ${ PORT } ` ;
8+ const DEFAULT_PORT = Number ( process . env . REPRO_PORT || '43173 ' ) ;
9+ const BASE_URL_OVERRIDE = ( process . env . REPRO_BASE_URL || '' ) . trim ( ) ;
1010const SERVER_READY_TIMEOUT_MS = 45_000 ;
1111const COMPILE_TIMEOUT_MS = 180_000 ;
1212
@@ -65,12 +65,15 @@ async function requireArtifacts() {
6565 }
6666}
6767
68- function startViteDevServer ( ) {
68+ function startViteDevServer ( baseUrl , port ) {
69+ // Start Vite directly to avoid npm wrapper processes that are harder to
70+ // terminate from this script.
6971 const child = spawn (
70- 'npm' ,
71- [ 'run ' , 'dev' , '--' , '-- host', HOST , '--port' , String ( PORT ) , '--strictPort' ] ,
72+ process . execPath ,
73+ [ './node_modules/vite/bin/vite.js ' , '-- host' , HOST , '--port' , String ( port ) , '--strictPort' ] ,
7274 {
73- stdio : [ 'ignore' , 'pipe' , 'pipe' ]
75+ stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
76+ detached : true
7477 }
7578 ) ;
7679
@@ -85,7 +88,7 @@ function startViteDevServer() {
8588 const onData = ( buf ) => {
8689 const text = String ( buf ) ;
8790 output += text ;
88- if ( ! ready && text . includes ( 'Local:' ) && text . includes ( BASE_URL ) ) {
91+ if ( ! ready && text . includes ( 'Local:' ) && text . includes ( baseUrl ) ) {
8992 ready = true ;
9093 clearTimeout ( timer ) ;
9194 resolve ( ) ;
@@ -107,16 +110,21 @@ function startViteDevServer() {
107110}
108111
109112async function stopProcess ( child ) {
110- if ( ! child || child . killed ) return ;
111- child . kill ( 'SIGTERM' ) ;
113+ if ( ! child || child . exitCode !== null ) return ;
114+ try {
115+ // Kill the whole process group (Vite + any children).
116+ process . kill ( - child . pid , 'SIGTERM' ) ;
117+ } catch { }
112118 for ( let i = 0 ; i < 30 ; i += 1 ) {
113119 if ( child . exitCode !== null ) return ;
114120 await sleep ( 100 ) ;
115121 }
116- child . kill ( 'SIGKILL' ) ;
122+ try {
123+ process . kill ( - child . pid , 'SIGKILL' ) ;
124+ } catch { }
117125}
118126
119- async function runBrowserWorkerCompile ( ) {
127+ async function runBrowserWorkerCompile ( baseUrl ) {
120128 const browser = await chromium . launch ( {
121129 headless : true ,
122130 channel : 'chromium' ,
@@ -129,7 +137,7 @@ async function runBrowserWorkerCompile() {
129137 } ) ;
130138
131139 try {
132- const page = await browser . newPage ( { baseURL : BASE_URL } ) ;
140+ const page = await browser . newPage ( { baseURL : baseUrl } ) ;
133141 await page . goto ( '/' ) ;
134142
135143 const evaluatePromise = page . evaluate ( async ( { files } ) => {
@@ -152,11 +160,19 @@ async function runBrowserWorkerCompile() {
152160 } ;
153161 } , { files : UVM_FILES } ) ;
154162
163+ let timer = null ;
155164 const timeoutPromise = new Promise ( ( _ , reject ) => {
156- setTimeout ( ( ) => reject ( new Error ( `compile timed out after ${ COMPILE_TIMEOUT_MS } ms` ) ) , COMPILE_TIMEOUT_MS ) ;
165+ timer = setTimeout (
166+ ( ) => reject ( new Error ( `compile timed out after ${ COMPILE_TIMEOUT_MS } ms` ) ) ,
167+ COMPILE_TIMEOUT_MS
168+ ) ;
157169 } ) ;
158170
159- return await Promise . race ( [ evaluatePromise , timeoutPromise ] ) ;
171+ try {
172+ return await Promise . race ( [ evaluatePromise , timeoutPromise ] ) ;
173+ } finally {
174+ if ( timer ) clearTimeout ( timer ) ;
175+ }
160176 } finally {
161177 await browser . close ( ) ;
162178 }
@@ -182,12 +198,17 @@ function analyzeLogs(payload) {
182198 try {
183199 await requireArtifacts ( ) ;
184200
185- console . log ( `# Starting Vite dev server at ${ BASE_URL } ` ) ;
186- server = startViteDevServer ( ) ;
187- await server . readyPromise ;
201+ const baseUrl = BASE_URL_OVERRIDE || `http://${ HOST } :${ DEFAULT_PORT } ` ;
202+ if ( ! BASE_URL_OVERRIDE ) {
203+ console . log ( `# Starting Vite dev server at ${ baseUrl } ` ) ;
204+ server = startViteDevServer ( baseUrl , DEFAULT_PORT ) ;
205+ await server . readyPromise ;
206+ } else {
207+ console . log ( `# Using existing dev server at ${ baseUrl } ` ) ;
208+ }
188209
189210 console . log ( '# Running minimal browser-worker UVM compile via createCirctWasmAdapter' ) ;
190- const payload = await runBrowserWorkerCompile ( ) ;
211+ const payload = await runBrowserWorkerCompile ( baseUrl ) ;
191212 const analysis = analyzeLogs ( payload ) ;
192213
193214 console . log ( '--- Repro Summary ---' ) ;
0 commit comments