diff --git a/lib/internal/test_runner/reporter/tap.js b/lib/internal/test_runner/reporter/tap.js index 915362b411b4e5..9e6a819181d3c1 100644 --- a/lib/internal/test_runner/reporter/tap.js +++ b/lib/internal/test_runner/reporter/tap.js @@ -63,6 +63,9 @@ async function * tapReporter(source) { case 'test:coverage': yield getCoverageReport(indent(data.nesting), data.summary, '# ', ''); break; + case 'test:bail': + yield `Bail out! ${tapEscape(data.reason)}\n`; + break; } } } diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index 43b7de41a54407..77f5b7677aa887 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -503,7 +503,7 @@ class Test extends AsyncResource { this.endTime = hrtime(); this.passed = false; this.error = err; - if (bail) { + if (bail && !this.root.bailedOut) { this.root.bailedOut = true; this.root.postRun(); } @@ -754,6 +754,10 @@ class Test extends AsyncResource { reporter.diagnostic(nesting, loc, diagnostics[i]); } + if(this.bailedOut){ + reporter.bail(); + } + reporter.diagnostic(nesting, loc, `tests ${harness.counters.all}`); reporter.diagnostic(nesting, loc, `suites ${harness.counters.suites}`); reporter.diagnostic(nesting, loc, `pass ${harness.counters.passed}`); diff --git a/lib/internal/test_runner/tests_stream.js b/lib/internal/test_runner/tests_stream.js index f7730caac00fa7..69630963886123 100644 --- a/lib/internal/test_runner/tests_stream.js +++ b/lib/internal/test_runner/tests_stream.js @@ -62,6 +62,13 @@ class TestsStream extends Readable { }); } + bail(reason = ''){ + this[kEmitMessage]('test:bail', { + __proto__: null, + reason, + }); + } + getSkip(reason = undefined) { return { __proto__: null, skip: reason ?? true }; } diff --git a/test/parallel/test-runner-bail.js b/test/parallel/test-runner-bail.js index 1fd6ebf48e9a39..109cb5dbcbac64 100644 --- a/test/parallel/test-runner-bail.js +++ b/test/parallel/test-runner-bail.js @@ -32,6 +32,7 @@ describe('node:test bail tap', () => { assert.match(child.stdout.toString(), /not ok 2 - second/); assert.doesNotMatch(child.stdout.toString(), /ok 3 - third/); assert.match(child.stdout.toString(), /not ok 1 - nested/); + assert.match(child.stdout.toString(), /Bail out!/); assert.doesNotMatch(child.stdout.toString(), /# Subtest: top level/); assert.doesNotMatch(child.stdout.toString(), /ok 1 - ok forth/); assert.doesNotMatch(child.stdout.toString(), /not ok 2 - fifth/);