@@ -115,16 +115,31 @@ export class TestShell {
115115 await Promise . all ( exitPromises ) ;
116116 }
117117
118+ debugInformation ( ) {
119+ return {
120+ pid : this . process . pid ,
121+ output : this . output ,
122+ rawOutput : this . rawOutput ,
123+ exitCode : this . process . exitCode ,
124+ signal : this . process . signalCode ,
125+ } ;
126+ }
127+
128+ static async cleanupAfterAll ( ) : Promise < void > {
129+ let foundOpenShells = false ;
130+ for ( const shell of TestShell . _openShells ) {
131+ foundOpenShells = true ;
132+ console . error ( shell . debugInformation ( ) ) ;
133+ }
134+ await TestShell . killall ( ) ;
135+ if ( foundOpenShells )
136+ throw new Error ( 'Open shells at end of test discovered!' ) ;
137+ }
138+
118139 static async cleanup ( this : Mocha . Context ) : Promise < void > {
119140 if ( this . currentTest ?. state === 'failed' ) {
120141 for ( const shell of TestShell . _openShells ) {
121- console . error ( {
122- pid : shell . process . pid ,
123- output : shell . output ,
124- rawOutput : shell . rawOutput ,
125- exitCode : shell . process . exitCode ,
126- signal : shell . process . signalCode ,
127- } ) ;
142+ console . error ( shell . debugInformation ( ) ) ;
128143 }
129144 }
130145 await TestShell . killall ( ) ;
@@ -321,3 +336,6 @@ export class TestShell {
321336 return match . groups ! . logId ;
322337 }
323338}
339+
340+ // If any shells remain at the end of the script, print their full output
341+ globalThis ?. after ( 'ensure no hanging shells' , TestShell . cleanupAfterAll ) ;
0 commit comments