Skip to content

Commit 9b60785

Browse files
committed
test_runner: run global after() hook earlier
This commit moves the global after() hook execution from the 'beforeExit' event to the point where all tests have finished running. This gives the global after() a chance to clean up handles that would otherwise prevent the 'beforeExit' event from being emitted. Fixes: #49056
1 parent d150316 commit 9b60785

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

lib/internal/test_runner/harness.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ function setup(root) {
142142
createProcessEventHandler('unhandledRejection', root);
143143
const coverage = configureCoverage(root, globalOptions);
144144
const exitHandler = async () => {
145-
await root.run(new ERR_TEST_FAILURE(
145+
root.postRun(new ERR_TEST_FAILURE(
146146
'Promise resolution is still pending but the event loop has already resolved',
147147
kCancelledByParent));
148148

lib/internal/test_runner/test.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -643,9 +643,16 @@ class Test extends AsyncResource {
643643
}
644644
}
645645

646-
// Clean up the test. Then, try to report the results and execute any
647-
// tests that were pending due to available concurrency.
648-
this.postRun(pendingSubtestsError);
646+
if (this.parent !== null) {
647+
// Clean up the test. Then, try to report the results and execute any
648+
// tests that were pending due to available concurrency.
649+
//
650+
// The root test is skipped here because it is a special case. Its
651+
// postRun() method is called when the process is getting ready to exit.
652+
// This helps catch any asynchronous activity that occurs after the tests
653+
// have finished executing.
654+
this.postRun(pendingSubtestsError);
655+
}
649656
}
650657

651658
postRun(pendingSubtestsError) {
@@ -687,6 +694,18 @@ class Test extends AsyncResource {
687694
this.parent.addReadySubtest(this);
688695
this.parent.processReadySubtestRange(false);
689696
this.parent.processPendingSubtests();
697+
698+
if (this.parent === this.root &&
699+
this.root.activeSubtests === 0 &&
700+
this.root.pendingSubtests.length === 0 &&
701+
this.root.readySubtests.size === 0 &&
702+
this.root.hooks.after.length > 0) {
703+
// This is done so that any global after() hooks are run. At this point
704+
// all of the tests have finished running. However, there might be
705+
// ref'ed handles keeping the event loop alive. This gives the global
706+
// after() hook a chance to clean them up.
707+
this.root.run();
708+
}
690709
} else if (!this.reported) {
691710
if (!this.passed && failed === 0 && this.error) {
692711
this.reporter.fail(0, kFilename, this.subtests.length + 1, kFilename, {

test/fixtures/test-runner/output/global_after_should_fail_the_test.snapshot

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ not ok 2 - /test/fixtures/test-runner/output/global_after_should_fail_the_test.j
2121
*
2222
*
2323
*
24-
*
2524
...
2625
1..1
2726
# tests 1

0 commit comments

Comments
 (0)