diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index f90c7dcad10346..742ba64e53550d 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -784,6 +784,19 @@ function run(options = kEmptyObject) { cwd, globalSetupPath, }; + + if (isolation === 'none') { + if (testNamePatterns != null) { + globalOptions.testNamePatterns = testNamePatterns; + } + if (testSkipPatterns != null) { + globalOptions.testSkipPatterns = testSkipPatterns; + } + if (only != null) { + globalOptions.only = only; + } + } + const root = createTestTree(rootTestOptions, globalOptions); let testFiles = files ?? createTestFileList(globPatterns, cwd); const { isTestRunner } = globalOptions; diff --git a/test/fixtures/test-runner/test-runner-isolation-none.mjs b/test/fixtures/test-runner/test-runner-isolation-none.mjs new file mode 100644 index 00000000000000..03a32fd6ad5701 --- /dev/null +++ b/test/fixtures/test-runner/test-runner-isolation-none.mjs @@ -0,0 +1,32 @@ +import { run } from 'node:test'; +import { tap } from 'node:test/reporters'; +import { parseArgs } from 'node:util'; + +const { + values, +} = parseArgs({ + args: process.argv.slice(2), + options: { + file: { type: 'string' }, + only: { type: 'boolean' }, + 'name-pattern': { type: 'string' }, + 'skip-pattern': { type: 'string' }, + }, +}); + +const opts = { + isolation: 'none', + files: [values.file], +}; + +if (values.only) { + opts.only = true; +} +if (values['name-pattern']) { + opts.testNamePatterns = [new RegExp(values['name-pattern'])]; +} +if (values['skip-pattern']) { + opts.testSkipPatterns = [new RegExp(values['skip-pattern'])]; +} + +run(opts).compose(tap).pipe(process.stdout); \ No newline at end of file diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index e9bb6c4a260160..17b75ad7806e28 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -689,6 +689,48 @@ describe('forceExit', () => { }); }); +describe('with isolation="none"', () => { + const isolationNoneFixture = fixtures.path('test-runner', 'test-runner-isolation-none.mjs'); + + it('should pass only to children', async () => { + const child = await common.spawnPromisified(process.execPath, [ + isolationNoneFixture, + '--file', join(testFixtures, 'test_only.js'), + '--only', + ]); + + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.code, 0); + assert.match(child.stdout, /ok 1 - this should be executed/); + assert.match(child.stdout, /# tests 1/); + }); + + it('should skip tests not matching testNamePatterns - RegExp', async () => { + const child = await common.spawnPromisified(process.execPath, [ + isolationNoneFixture, + '--file', join(testFixtures, 'default-behavior/test/skip_by_name.cjs'), + '--name-pattern', 'executed', + ]); + + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.code, 0); + assert.match(child.stdout, /ok 1 - this should be executed/); + assert.match(child.stdout, /# tests 1/); + }); + + it('should skip tests matching testSkipPatterns - RegExp', async () => { + const child = await common.spawnPromisified(process.execPath, [ + isolationNoneFixture, + '--file', join(testFixtures, 'default-behavior/test/skip_by_name.cjs'), + '--skip-pattern', 'skipped', + ]); + + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.code, 0); + assert.match(child.stdout, /ok 1 - this should be executed/); + assert.match(child.stdout, /# tests 1/); + }); +}); // exitHandler doesn't run until after the tests / after hooks finish. process.on('exit', () => {