diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index 0755c42750ac87..d2be83364a0f6d 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -414,7 +414,11 @@ class Test extends AsyncResource { this.pass(); } catch (err) { if (err?.code === 'ERR_TEST_FAILURE' && kIsNodeError in err) { - this.fail(err); + if (err.failureType === kTestTimeoutFailure) { + this.cancel(err); + } else { + this.fail(err); + } } else { this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); } diff --git a/test/message/test_runner_output.out b/test/message/test_runner_output.out index 22d97940a36f9c..4e987f8e9f4b94 100644 --- a/test/message/test_runner_output.out +++ b/test/message/test_runner_output.out @@ -129,9 +129,9 @@ not ok 13 - async assertion fail failureType: 'testCodeFailure' error: |- Expected values to be strictly equal: - + true !== false - + code: 'ERR_ASSERTION' stack: |- * @@ -607,8 +607,8 @@ not ok 61 - invalid subtest fail # Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. # tests 61 # pass 26 -# fail 20 -# cancelled 0 +# fail 18 +# cancelled 2 # skipped 10 # todo 5 # duration_ms * diff --git a/test/parallel/test-runner-misc.js b/test/parallel/test-runner-misc.js new file mode 100644 index 00000000000000..34abaf5c120be3 --- /dev/null +++ b/test/parallel/test-runner-misc.js @@ -0,0 +1,33 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const { setTimeout } = require('timers/promises'); + +if (process.argv[2] === 'child') { + const test = require('node:test'); + + if (process.argv[3] === 'abortSignal') { + assert.throws(() => test({ signal: {} }), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + + let testSignal; + test({ timeout: 10 }, common.mustCall(async ({ signal }) => { + assert.strictEqual(signal.aborted, false); + testSignal = signal; + await setTimeout(50); + })).finally(common.mustCall(() => { + test(() => assert.strictEqual(testSignal.aborted, true)); + })); + } else assert.fail('unreachable'); +} else { + const child = spawnSync(process.execPath, [__filename, 'child', 'abortSignal']); + const stdout = child.stdout.toString(); + assert.match(stdout, /^# pass 1$/m); + assert.match(stdout, /^# fail 0$/m); + assert.match(stdout, /^# cancelled 1$/m); + assert.strictEqual(child.status, 1); + assert.strictEqual(child.signal, null); +}