diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index 4dce0ed2332b1a..a30700a9cf74af 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -170,8 +170,13 @@ function setup(root) { kCancelledByParent)); hook.disable(); - process.removeListener('unhandledRejection', rejectionHandler); process.removeListener('uncaughtException', exceptionHandler); + process.removeListener('unhandledRejection', rejectionHandler); + process.removeListener('beforeExit', exitHandler); + if (globalOptions.isTestRunner) { + process.removeListener('SIGINT', terminationHandler); + process.removeListener('SIGTERM', terminationHandler); + } }; const terminationHandler = () => { diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index 6fd1cb72f3b508..2baea71bc3af14 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -566,6 +566,7 @@ function run(options = kEmptyObject) { } let postRun = () => root.postRun(); + let teardown = () => root.harness.teardown(); let filesWatcher; const opts = { __proto__: null, @@ -580,6 +581,7 @@ function run(options = kEmptyObject) { if (watch) { filesWatcher = watchFiles(testFiles, opts); postRun = undefined; + teardown = undefined; } const runFiles = () => { root.harness.bootstrapComplete = true; @@ -591,7 +593,8 @@ function run(options = kEmptyObject) { }); }; - PromisePrototypeThen(PromisePrototypeThen(PromiseResolve(setup?.(root.reporter)), runFiles), postRun); + const setupPromise = PromiseResolve(setup?.(root.reporter)); + PromisePrototypeThen(PromisePrototypeThen(PromisePrototypeThen(setupPromise, runFiles), postRun), teardown); return root.reporter; } diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index 54e882c4ecabe3..0b3c0908601004 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -551,3 +551,13 @@ describe('forceExit', () => { }); }); }); + + +// exitHandler doesn't run until after the tests / after hooks finish. +process.on('exit', () => { + assert.strictEqual(process.listeners('uncaughtException').length, 0); + assert.strictEqual(process.listeners('unhandledRejection').length, 0); + assert.strictEqual(process.listeners('beforeExit').length, 0); + assert.strictEqual(process.listeners('SIGINT').length, 0); + assert.strictEqual(process.listeners('SIGTERM').length, 0); +});