| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3675,6 +3675,44 @@ Emitted when no more tests are queued for execution in watch mode. | |||
| 3675 | 3675 | ||
| 3676 | 3676 | Emitted when one or more tests are restarted due to a file change in watch mode. | |
| 3677 | 3677 | ||
| 3678 | + ## `getTestContext()` | ||
| 3679 | + | ||
| 3680 | + <!-- YAML | ||
| 3681 | + added: REPLACEME | ||
| 3682 | + --> | ||
| 3683 | + | ||
| 3684 | + * Returns: {TestContext|SuiteContext|undefined} | ||
| 3685 | + | ||
| 3686 | + Returns the [`TestContext`][] or [`SuiteContext`][] object associated with the | ||
| 3687 | + currently executing test or suite, or `undefined` if called outside of a test or | ||
| 3688 | + suite. This function can be used to access context information from within the | ||
| 3689 | + test or suite function or any async operations within them. | ||
| 3690 | + | ||
| 3691 | + ```mjs | ||
| 3692 | + import { getTestContext } from 'node:test'; | ||
| 3693 | + | ||
| 3694 | + test('example test', async () => { | ||
| 3695 | + const ctx = getTestContext(); | ||
| 3696 | + console.log(`Running test: ${ctx.name}`); | ||
| 3697 | + }); | ||
| 3698 | + | ||
| 3699 | + describe('example suite', () => { | ||
| 3700 | + const ctx = getTestContext(); | ||
| 3701 | + console.log(`Running suite: ${ctx.name}`); | ||
| 3702 | + }); | ||
| 3703 | + ``` | ||
| 3704 | + | ||
| 3705 | + When called from a test, returns a [`TestContext`][]. | ||
| 3706 | + When called from a suite, returns a [`SuiteContext`][]. | ||
| 3707 | + | ||
| 3708 | + If called from outside a test or suite (e.g., at the top level of a module or in | ||
| 3709 | + a setTimeout callback after execution has completed), this function returns | ||
| 3710 | + `undefined`. | ||
| 3711 | + | ||
| 3712 | + When called from within a hook (before, beforeEach, after, afterEach), this | ||
| 3713 | + function returns the context of the test or suite that the hook is associated | ||
| 3714 | + with. | ||
| 3715 | + | ||
| 3678 | 3716 | ## Test instrumentation and OpenTelemetry | |
| 3679 | 3717 | ||
| 3680 | 3718 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,7 +21,7 @@ const { | |||
| 21 | 21 | }, | |
| 22 | 22 | } = require('internal/errors'); | |
| 23 | 23 | const { exitCodes: { kGenericUserError } } = internalBinding('errors'); | |
| 24 | - const { kCancelledByParent, Test, Suite } = require('internal/test_runner/test'); | ||
| 24 | + const { kCancelledByParent, Test, Suite, TestContext, SuiteContext } = require('internal/test_runner/test'); | ||
| 25 | 25 | const { | |
| 26 | 26 | parseCommandLine, | |
| 27 | 27 | reporterScope, | |
@@ -431,8 +431,27 @@ function hook(hook) { | |||
| 431 | 431 | }; | |
| 432 | 432 | } | |
| 433 | 433 | ||
| 434 | + function getTestContext() { | ||
| 435 | + const test = testResources.get(executionAsyncId()); | ||
| 436 | + // Exclude the reporter sentinel | ||
| 437 | + if (test === undefined || test === reporterScope) { | ||
| 438 | + return undefined; | ||
| 439 | + } | ||
| 440 | + // For hooks (hookType is set), return the test/suite being hooked (the parent) | ||
| 441 | + const actualTest = test.hookType !== undefined ? test.parent : test; | ||
| 442 | + if (actualTest === undefined) { | ||
| 443 | + return undefined; | ||
| 444 | + } | ||
| 445 | + // Return SuiteContext for suites, TestContext for tests | ||
| 446 | + if (actualTest instanceof Suite) { | ||
| 447 | + return new SuiteContext(actualTest); | ||
| 448 | + } | ||
| 449 | + return new TestContext(actualTest); | ||
| 450 | + } | ||
| 451 | + | ||
| 434 | 452 | module.exports = { | |
| 435 | 453 | createTestTree, | |
| 454 | + getTestContext, | ||
| 436 | 455 | test: runInParentContext(Test), | |
| 437 | 456 | suite: runInParentContext(Suite), | |
| 438 | 457 | before: hook('before'), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1831,4 +1831,6 @@ module.exports = { | |||
| 1831 | 1831 | kUnwrapErrors, | |
| 1832 | 1832 | Suite, | |
| 1833 | 1833 | Test, | |
| 1834 | + TestContext, | ||
| 1835 | + SuiteContext, | ||
| 1834 | 1836 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,7 @@ const { | |||
| 5 | 5 | ObjectDefineProperty, | |
| 6 | 6 | } = primordials; | |
| 7 | 7 | ||
| 8 | - const { test, suite, before, after, beforeEach, afterEach } = require('internal/test_runner/harness'); | ||
| 8 | + const { test, suite, before, after, beforeEach, afterEach, getTestContext } = require('internal/test_runner/harness'); | ||
| 9 | 9 | const { run } = require('internal/test_runner/runner'); | |
| 10 | 10 | ||
| 11 | 11 | module.exports = test; | |
@@ -15,6 +15,7 @@ ObjectAssign(module.exports, { | |||
| 15 | 15 | before, | |
| 16 | 16 | beforeEach, | |
| 17 | 17 | describe: suite, | |
| 18 | + getTestContext, | ||
| 18 | 19 | it: test, | |
| 19 | 20 | run, | |
| 20 | 21 | suite, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,54 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + require('../common'); | ||
| 3 | + const assert = require('node:assert'); | ||
| 4 | + const { test, getTestContext, describe, it } = require('node:test'); | ||
| 5 | + | ||
| 6 | + // Outside a test — must return undefined | ||
| 7 | + assert.strictEqual(getTestContext(), undefined); | ||
| 8 | + | ||
| 9 | + test('getTestContext returns current context inside test', async () => { | ||
| 10 | + const ctx = getTestContext(); | ||
| 11 | + assert.ok(ctx !== undefined); | ||
| 12 | + assert.strictEqual(ctx.name, 'getTestContext returns current context inside test'); | ||
| 13 | + assert.strictEqual(typeof ctx.signal, 'object'); | ||
| 14 | + assert.strictEqual(typeof ctx.fullName, 'string'); | ||
| 15 | + }); | ||
| 16 | + | ||
| 17 | + test('getTestContext works in nested test', async (t) => { | ||
| 18 | + await t.test('child', async () => { | ||
| 19 | + const ctx = getTestContext(); | ||
| 20 | + assert.ok(ctx !== undefined); | ||
| 21 | + assert.strictEqual(ctx.name, 'child'); | ||
| 22 | + }); | ||
| 23 | + }); | ||
| 24 | + | ||
| 25 | + describe('getTestContext works in describe/it', () => { | ||
| 26 | + it('has correct name', () => { | ||
| 27 | + const ctx = getTestContext(); | ||
| 28 | + assert.ok(ctx !== undefined); | ||
| 29 | + assert.strictEqual(ctx.name, 'has correct name'); | ||
| 30 | + }); | ||
| 31 | + }); | ||
| 32 | + | ||
| 33 | + describe('getTestContext returns SuiteContext in suite', () => { | ||
| 34 | + it('suite context is available', () => { | ||
| 35 | + const ctx = getTestContext(); | ||
| 36 | + assert.ok(ctx !== undefined); | ||
| 37 | + // Suite name appears as parent in nested test context | ||
| 38 | + assert.strictEqual(typeof ctx.signal, 'object'); | ||
| 39 | + assert.strictEqual(typeof ctx.fullName, 'string'); | ||
| 40 | + }); | ||
| 41 | + }); | ||
| 42 | + | ||
| 43 | + test('getTestContext works in test body during async operations', async (t) => { | ||
| 44 | + const ctx = getTestContext(); | ||
| 45 | + assert.ok(ctx !== undefined); | ||
| 46 | + assert.strictEqual(ctx.name, 'getTestContext works in test body during async operations'); | ||
| 47 | + | ||
| 48 | + // Also works in nested async context | ||
| 49 | + const ctxInSetImmediate = await new Promise((resolve) => { | ||
| 50 | + setImmediate(() => resolve(getTestContext())); | ||
| 51 | + }); | ||
| 52 | + assert.ok(ctxInSetImmediate !== undefined); | ||
| 53 | + assert.strictEqual(ctxInSetImmediate.name, 'getTestContext works in test body during async operations'); | ||
| 54 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -252,6 +252,8 @@ const customTypesMap = { | |||
| 252 | 252 | 'Timer': 'timers.html#timers', | |
| 253 | 253 | ||
| 254 | 254 | 'TestsStream': 'test.html#class-testsstream', | |
| 255 | + 'TestContext': 'test.html#class-testcontext', | ||
| 256 | + 'SuiteContext': 'test.html#class-suitecontext', | ||
| 255 | 257 | ||
| 256 | 258 | 'tls.SecureContext': 'tls.html#tlscreatesecurecontextoptions', | |
| 257 | 259 | 'tls.Server': 'tls.html#class-tlsserver', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments