1- import { spawnSync } from 'node:child_process' ;
1+ import { spawn } from 'node:child_process' ;
22import { join } from 'node:path' ;
33import { describe , expect , test } from 'vitest' ;
44
55const __dirname = import . meta. dirname || new URL ( '.' , import . meta. url ) . pathname ;
66
77const NODE_MAJOR_VERSION = parseInt ( process . versions . node . split ( '.' ) [ 0 ] , 10 ) ;
88
9- function runTest ( ...paths ) {
9+ // macOS emulated x64 in CI is very slow!
10+ const timeout = process . env . CI && process . platform === 'darwin' ? 60000 : 20000 ;
11+
12+ async function runTest ( ...paths ) {
13+ console . time ( 'Test Run' ) ;
1014 const file = join ( ...paths ) ;
11- const args = NODE_MAJOR_VERSION === 22 ? [ '--experimental-async-context-frame' , file ] : [ file ] ;
12- const result = spawnSync ( 'node' , args ) ;
13- return result ;
15+ const args = NODE_MAJOR_VERSION === 22 ? [ '--experimental-async-context-frame' , file ] : [ file ] ;
16+
17+ return new Promise ( ( resolve , reject ) => {
18+ const child = spawn ( 'node' , args , { stdio : [ 'ignore' , 'pipe' , 'pipe' ] } ) ;
19+
20+ let stdoutBuf = '' ;
21+ let stderrBuf = '' ;
22+
23+ child . stdout ?. on ( 'data' , chunk => {
24+ stdoutBuf += chunk . toString ( ) ;
25+ } ) ;
26+ child . stderr ?. on ( 'data' , chunk => {
27+ stderrBuf += chunk . toString ( ) ;
28+ } ) ;
29+
30+ child . on ( 'error' , err => reject ( err ) ) ;
31+
32+ child . on ( 'close' , code => {
33+ const stdout = stdoutBuf
34+ . split ( '\n' )
35+ . map ( line => line . trim ( ) )
36+ . filter ( line => line !== '' ) ;
37+ const stderr = stderrBuf
38+ . split ( '\n' )
39+ . map ( line => line . trim ( ) )
40+ . filter ( line => line !== '' ) ;
41+
42+ let trace ;
43+ for ( const line of stdout ) {
44+ try {
45+ trace = JSON . parse ( line ) ;
46+ break ;
47+ } catch ( _ ) {
48+ // ignore non-JSON lines
49+ }
50+ }
51+
52+ console . timeEnd ( 'Test Run' ) ;
53+ if ( stdout . length > 0 ) {
54+ console . log ( 'stdout:' , stdout ) ;
55+ }
56+ if ( stderr . length > 0 ) {
57+ console . log ( 'stderr:' , stderr ) ;
58+ }
59+
60+ resolve ( { status : code , stdout, trace } ) ;
61+ } ) ;
62+ } ) ;
1463}
1564
16- describe ( 'e2e Tests' , { timeout : 20000 } , ( ) => {
17- test ( 'Capture stack trace from multiple threads' , ( ) => {
18- const result = runTest ( __dirname , 'stack-traces.js' )
65+ describe ( 'e2e Tests' , { timeout } , ( ) => {
66+ test ( 'Capture stack trace from multiple threads' , async ( ) => {
67+ const result = await runTest ( __dirname , 'stack-traces.js' )
1968
2069 expect ( result . status ) . toEqual ( 0 ) ;
2170
22- const trace = JSON . parse ( result . stdout . toString ( ) ) ;
23-
24- expect ( trace ) . toEqual ( expect . objectContaining ( {
71+ expect ( result . trace ) . toEqual ( expect . objectContaining ( {
2572 '0' : {
2673 frames : expect . arrayContaining ( [
2774 {
@@ -69,14 +116,12 @@ describe('e2e Tests', { timeout: 20000 }, () => {
69116 } ) ) ;
70117 } ) ;
71118
72- test ( 'detect stalled thread' , { timeout : 20000 } , ( ) => {
73- const result = runTest ( __dirname , 'stalled.js' ) ;
119+ test ( 'detect stalled thread' , async ( ) => {
120+ const result = await runTest ( __dirname , 'stalled.js' ) ;
74121
75122 expect ( result . status ) . toEqual ( 0 ) ;
76123
77- const trace = JSON . parse ( result . stdout . toString ( ) ) ;
78-
79- expect ( trace ) . toEqual ( expect . objectContaining ( {
124+ expect ( result . trace ) . toEqual ( expect . objectContaining ( {
80125 '0' : {
81126 frames : expect . arrayContaining ( [
82127 {
@@ -106,19 +151,17 @@ describe('e2e Tests', { timeout: 20000 }, () => {
106151 } ) ) ;
107152 } ) ;
108153
109- test ( 'async storage state' , { timeout : 20000 } , ( ctx ) => {
154+ test ( 'async storage state' , async ( ctx ) => {
110155 if ( NODE_MAJOR_VERSION < 22 ) {
111156 ctx . skip ( ) ;
112157 return ;
113158 }
114159
115- const result = runTest ( __dirname , 'async-storage.mjs' ) ;
160+ const result = await runTest ( __dirname , 'async-storage.mjs' ) ;
116161
117162 expect ( result . status ) . toEqual ( 0 ) ;
118163
119- const trace = JSON . parse ( result . stdout . toString ( ) ) ;
120-
121- expect ( trace ) . toEqual ( expect . objectContaining ( {
164+ expect ( result . trace ) . toEqual ( expect . objectContaining ( {
122165 '0' : expect . objectContaining ( {
123166 frames : expect . arrayContaining ( [
124167 {
@@ -145,11 +188,10 @@ describe('e2e Tests', { timeout: 20000 }, () => {
145188 } ) ) ;
146189 } ) ;
147190
148- test ( 'can be disabled' , { timeout : 20000 } , ( ) => {
149- const result = runTest ( __dirname , 'stalled-disabled.js' ) ;
191+ test ( 'can be disabled' , async ( ) => {
192+ const result = await runTest ( __dirname , 'stalled-disabled.js' ) ;
150193
151194 expect ( result . status ) . toEqual ( 0 ) ;
152-
153- expect ( result . stdout . toString ( ) ) . toContain ( 'complete' ) ;
195+ expect ( result . stdout ) . toContain ( 'complete' ) ;
154196 } ) ;
155197} ) ;
0 commit comments