@@ -501,9 +501,18 @@ ${ENDGROUP}`)
501501 `jest${ process . platform === 'win32' ? '.CMD' : '' } `
502502 )
503503 let firstError = true
504- let killed = false
504+ const testController = new AbortController ( )
505+ const testSignal = testController . signal
505506 let hadFailures = false
506507
508+ async function yourTurn ( ) {
509+ await sema . acquire ( )
510+ if ( testSignal . aborted ) {
511+ sema . release ( )
512+ throw testSignal . reason
513+ }
514+ }
515+
507516 const runTest = ( /** @type {TestFile } */ test , isFinalRun , isRetry ) =>
508517 new Promise ( ( resolve , reject ) => {
509518 const start = new Date ( ) . getTime ( )
@@ -618,11 +627,11 @@ ${ENDGROUP}`)
618627 if ( hideOutput ) {
619628 await outputSema . acquire ( )
620629 const isExpanded =
621- firstError && ! killed && ! shouldContinueTestsOnError
630+ firstError && ! testSignal . aborted && ! shouldContinueTestsOnError
622631 if ( isExpanded ) {
623632 firstError = false
624633 process . stdout . write ( `❌ ${ test . file } output:\n` )
625- } else if ( killed ) {
634+ } else if ( testSignal . aborted ) {
626635 process . stdout . write ( `${ GROUP } ${ test . file } output (killed)\n` )
627636 } else {
628637 process . stdout . write ( `${ GROUP } ❌ ${ test . file } output\n` )
@@ -636,7 +645,7 @@ ${ENDGROUP}`)
636645 output += chunk . toString ( )
637646 }
638647
639- if ( process . env . CI && ! killed ) {
648+ if ( process . env . CI && ! testSignal . aborted ) {
640649 errorsPerTests . set ( test . file , output )
641650 }
642651
@@ -685,7 +694,7 @@ ${ENDGROUP}`)
685694 const directorySemas = new Map ( )
686695
687696 const originalRetries = numRetries
688- await Promise . all (
697+ const results = await Promise . allSettled (
689698 tests . map ( async ( test ) => {
690699 const dirName = path . dirname ( test . file )
691700 let dirSema = directorySemas . get ( dirName )
@@ -697,7 +706,12 @@ ${ENDGROUP}`)
697706 }
698707 if ( dirSema ) await dirSema . acquire ( )
699708
700- await sema . acquire ( )
709+ try {
710+ await yourTurn ( )
711+ } catch ( err ) {
712+ throw new Error ( `Skipping ${ test . file } due to abort.` , { cause : err } )
713+ }
714+
701715 let passed = false
702716
703717 const shouldSkipRetries = skipRetryTestManifest . find ( ( t ) =>
@@ -750,16 +764,15 @@ ${ENDGROUP}`)
750764 }
751765
752766 if ( ! passed ) {
753- console . error (
754- `${ test . file } failed to pass within ${ numRetries } retries`
767+ hadFailures = true
768+ const error = new Error (
769+ `Test ${ test . file } failed to pass within ${ numRetries } retries`
755770 )
756771
757772 if ( ! shouldContinueTestsOnError ) {
758- killed = true
759- children . forEach ( ( child ) => child . kill ( ) )
760- cleanUpAndExit ( 1 )
773+ testController . abort ( error )
761774 } else {
762- hadFailures = true
775+ console . error ( error )
763776 console . log (
764777 `CONTINUE_ON_ERROR enabled, continuing tests after ${ test . file } failed`
765778 )
@@ -798,6 +811,21 @@ ${ENDGROUP}`)
798811 } )
799812 )
800813
814+ for ( const result of results ) {
815+ if ( result . status === 'rejected' ) {
816+ hadFailures = true
817+ // This can seem a bit noisy since it mostly repeats test failures in abort
818+ // causes. But if we remove this log, bugs in the test runner may be hard
819+ // to debug.
820+ console . error ( result . reason )
821+ }
822+ }
823+
824+ if ( hadFailures ) {
825+ // TODO: Does it make sense to update timings if there were failures?
826+ return hadFailures
827+ }
828+
801829 if ( options . timings ) {
802830 const curTimings = { }
803831 // let junitData = `<testsuites name="jest tests">`
@@ -857,20 +885,20 @@ ${ENDGROUP}`)
857885 }
858886 }
859887
860- // Return whether there were any failures
861888 return hadFailures
862889}
863890
864891main ( )
865892 . then ( ( hadFailures ) => {
866893 if ( hadFailures ) {
867894 console . error ( 'Some tests failed' )
868- cleanUpAndExit ( 1 )
895+ return cleanUpAndExit ( 1 )
869896 } else {
870- cleanUpAndExit ( 0 )
897+ return cleanUpAndExit ( 0 )
871898 }
872899 } )
873900 . catch ( ( err ) => {
874901 console . error ( err )
875- cleanUpAndExit ( 1 )
902+ // Retry cleanup one more time.
903+ return cleanUpAndExit ( 1 )
876904 } )
0 commit comments