From 289399f8ec12fa9fbed4182844c6c462ea29288a Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Fri, 21 Nov 2025 08:29:35 +0100 Subject: [PATCH 1/3] src: rename config file testRunner to test PR-URL: https://github.com/nodejs/node/pull/60798 Reviewed-By: Jacob Smith Reviewed-By: Rafael Gonzaga Signed-off-by: Marco Ippolito --- doc/api/cli.md | 4 +-- doc/node-config-schema.json | 2 +- src/node_config_file.cc | 14 +++++++++- src/node_options.h | 2 +- .../options-as-flags/test-config.json | 2 +- .../rc/deprecated-testrunner-namespace.json | 5 ++++ .../node.config.json | 2 +- test/fixtures/rc/empty-valid-namespace.json | 2 +- test/fixtures/rc/namespace-with-array.json | 2 +- .../rc/namespace-with-disallowed-envvar.json | 2 +- test/fixtures/rc/namespaced/node.config.json | 2 +- test/fixtures/rc/override-namespace.json | 2 +- .../override-node-option-with-namespace.json | 2 +- test/fixtures/rc/unknown-flag-namespace.json | 2 +- .../options-propagation/node.config.json | 2 +- test/parallel/test-config-file.js | 14 +++++++++- test/parallel/test-runner-flag-propagation.js | 26 +++++++++---------- 17 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 test/fixtures/rc/deprecated-testrunner-namespace.json diff --git a/doc/api/cli.md b/doc/api/cli.md index 1a6844b1f9dad9..4ca461f263b319 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -986,7 +986,7 @@ in the `$schema` must be replaced with the version of Node.js you are using. "watch-path": "src", "watch-preserve-output": true }, - "testRunner": { + "test": { "test-isolation": "process" }, "watch": { @@ -999,7 +999,7 @@ The configuration file supports namespace-specific options: * The `nodeOptions` field contains CLI flags that are allowed in [`NODE_OPTIONS`][]. -* Namespace fields like `testRunner` contain configuration specific to that subsystem. +* Namespace fields like `test` contain configuration specific to that subsystem. No-op flags are not supported. Not all V8 flags are currently supported. diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 2b4f228eaa57d5..71df22b020cf46 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -816,7 +816,7 @@ } } }, - "testRunner": { + "test": { "type": "object", "additionalProperties": false, "required": [], diff --git a/src/node_config_file.cc b/src/node_config_file.cc index b3f5feb53d73c0..d1503bb45b3aff 100644 --- a/src/node_config_file.cc +++ b/src/node_config_file.cc @@ -260,8 +260,20 @@ ParseResult ConfigReader::ParseConfig(const std::string_view& config_path) { return ParseResult::InvalidContent; } - // Check if this field is a valid namespace std::string namespace_name(field_name); + + // TODO(@marco-ippolito): Remove warning for testRunner namespace + if (namespace_name == "testRunner") { + FPrintF(stderr, + "the \"testRunner\" namespace has been removed. " + "Use \"test\" instead.\n"); + // Better to throw an error than to ignore it + // Otherwise users might think their test suite is green + // when it's not running + return ParseResult::InvalidContent; + } + + // Check if this field is a valid namespace if (!valid_namespaces.contains(namespace_name)) { // If not, skip it continue; diff --git a/src/node_options.h b/src/node_options.h index 6ffa6bf5531d84..77423b8bcd441b 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -423,7 +423,7 @@ std::vector MapAvailableNamespaces(); // Define all namespace entries #define OPTION_NAMESPACE_LIST(V) \ V(kNoNamespace, "") \ - V(kTestRunnerNamespace, "testRunner") \ + V(kTestRunnerNamespace, "test") \ V(kWatchNamespace, "watch") \ V(kPermissionNamespace, "permission") diff --git a/test/fixtures/options-as-flags/test-config.json b/test/fixtures/options-as-flags/test-config.json index c80ffa4069fbf5..aa6355c37a1681 100644 --- a/test/fixtures/options-as-flags/test-config.json +++ b/test/fixtures/options-as-flags/test-config.json @@ -3,7 +3,7 @@ "experimental-transform-types": true, "max-http-header-size": 8192 }, - "testRunner": { + "test": { "test-isolation": "none" } } diff --git a/test/fixtures/rc/deprecated-testrunner-namespace.json b/test/fixtures/rc/deprecated-testrunner-namespace.json new file mode 100644 index 00000000000000..d8a01949418cf7 --- /dev/null +++ b/test/fixtures/rc/deprecated-testrunner-namespace.json @@ -0,0 +1,5 @@ +{ + "testRunner": { + "test-isolation": "none" + } +} diff --git a/test/fixtures/rc/duplicate-namespace-option/node.config.json b/test/fixtures/rc/duplicate-namespace-option/node.config.json index 4d948fbd33961d..948dc4e6c5570b 100644 --- a/test/fixtures/rc/duplicate-namespace-option/node.config.json +++ b/test/fixtures/rc/duplicate-namespace-option/node.config.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "test-name-pattern": "first-pattern", "test-name-pattern": "second-pattern" } diff --git a/test/fixtures/rc/empty-valid-namespace.json b/test/fixtures/rc/empty-valid-namespace.json index dbeb33d7aa8b59..c267aa9bde2918 100644 --- a/test/fixtures/rc/empty-valid-namespace.json +++ b/test/fixtures/rc/empty-valid-namespace.json @@ -1,3 +1,3 @@ { - "testRunner": {} + "test": {} } diff --git a/test/fixtures/rc/namespace-with-array.json b/test/fixtures/rc/namespace-with-array.json index 056a4291e9b666..1cddcdfd6c4ccd 100644 --- a/test/fixtures/rc/namespace-with-array.json +++ b/test/fixtures/rc/namespace-with-array.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "test-coverage-exclude": ["config-pattern1", "config-pattern2"] } } diff --git a/test/fixtures/rc/namespace-with-disallowed-envvar.json b/test/fixtures/rc/namespace-with-disallowed-envvar.json index 6152684e0583f4..f545f0ff62781f 100644 --- a/test/fixtures/rc/namespace-with-disallowed-envvar.json +++ b/test/fixtures/rc/namespace-with-disallowed-envvar.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "test-concurrency": 1, "experimental-test-coverage": true } diff --git a/test/fixtures/rc/namespaced/node.config.json b/test/fixtures/rc/namespaced/node.config.json index df929d25c10b52..0870c4c86033b2 100644 --- a/test/fixtures/rc/namespaced/node.config.json +++ b/test/fixtures/rc/namespaced/node.config.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "test-isolation": "none" } } diff --git a/test/fixtures/rc/override-namespace.json b/test/fixtures/rc/override-namespace.json index acb37b2eec485c..be79cf5d4415b5 100644 --- a/test/fixtures/rc/override-namespace.json +++ b/test/fixtures/rc/override-namespace.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "test-isolation": "process" }, "nodeOptions": { diff --git a/test/fixtures/rc/override-node-option-with-namespace.json b/test/fixtures/rc/override-node-option-with-namespace.json index 2db9e1a47f07ea..e5912da99590b4 100644 --- a/test/fixtures/rc/override-node-option-with-namespace.json +++ b/test/fixtures/rc/override-node-option-with-namespace.json @@ -2,7 +2,7 @@ "nodeOptions": { "test-isolation": "none" }, - "testRunner": { + "test": { "test-isolation": "process" } } diff --git a/test/fixtures/rc/unknown-flag-namespace.json b/test/fixtures/rc/unknown-flag-namespace.json index b5d87ad8dd3acd..01dd62824cf2b9 100644 --- a/test/fixtures/rc/unknown-flag-namespace.json +++ b/test/fixtures/rc/unknown-flag-namespace.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "unknown-flag": true } } diff --git a/test/fixtures/test-runner/options-propagation/node.config.json b/test/fixtures/test-runner/options-propagation/node.config.json index 98a35b7d3eebd2..7bb3d5c80fe0e5 100644 --- a/test/fixtures/test-runner/options-propagation/node.config.json +++ b/test/fixtures/test-runner/options-propagation/node.config.json @@ -1,5 +1,5 @@ { - "testRunner": { + "test": { "experimental-test-coverage": true } } diff --git a/test/parallel/test-config-file.js b/test/parallel/test-config-file.js index 79d2ef7cdc4b64..94593a9b8f6efa 100644 --- a/test/parallel/test-config-file.js +++ b/test/parallel/test-config-file.js @@ -429,7 +429,7 @@ describe('namespace-scoped options', () => { fixtures.path('rc/unknown-flag-namespace.json'), '-p', '"Hello, World!"', ]); - assert.match(result.stderr, /Unknown or not allowed option unknown-flag for namespace testRunner/); + assert.match(result.stderr, /Unknown or not allowed option unknown-flag for namespace test/); assert.strictEqual(result.stdout, ''); assert.strictEqual(result.code, 9); }); @@ -550,4 +550,16 @@ describe('namespace-scoped options', () => { assert.strictEqual(result.stdout, '2\n'); assert.strictEqual(result.code, 0); }); + + it('should throw an error for removed "testRunner" namespace', async () => { + const result = await spawnPromisified(process.execPath, [ + '--no-warnings', + '--experimental-config-file', + fixtures.path('rc/deprecated-testrunner-namespace.json'), + '-p', '"Hello, World!"', + ]); + assert.match(result.stderr, /the "testRunner" namespace has been removed\. Use "test" instead\./); + assert.strictEqual(result.stdout, ''); + assert.strictEqual(result.code, 9); + }); }); diff --git a/test/parallel/test-runner-flag-propagation.js b/test/parallel/test-runner-flag-propagation.js index 3f742850a9fae7..f4e9849cce77d0 100644 --- a/test/parallel/test-runner-flag-propagation.js +++ b/test/parallel/test-runner-flag-propagation.js @@ -68,19 +68,19 @@ describe('test runner flag propagation', () => { describe('via config file', () => { const configFilePropagationTests = [ - ['--test-concurrency', 2, 2, 'testRunner'], - ['--test-timeout', 5000, 5000, 'testRunner'], - ['--test-coverage-branches', 100, 100, 'testRunner'], - ['--test-coverage-functions', 100, 100, 'testRunner'], - ['--test-coverage-lines', 100, 100, 'testRunner'], - ['--experimental-test-coverage', true, false, 'testRunner'], - ['--test-coverage-exclude', 'test/**', 'test/**', 'testRunner'], - ['--test-coverage-include', 'src/**', 'src/**', 'testRunner'], - ['--test-update-snapshots', true, true, 'testRunner'], - ['--test-concurrency', 3, 3, 'testRunner'], - ['--test-timeout', 2500, 2500, 'testRunner'], - ['--test-coverage-branches', 90, 90, 'testRunner'], - ['--test-coverage-functions', 85, 85, 'testRunner'], + ['--test-concurrency', 2, 2, 'test'], + ['--test-timeout', 5000, 5000, 'test'], + ['--test-coverage-branches', 100, 100, 'test'], + ['--test-coverage-functions', 100, 100, 'test'], + ['--test-coverage-lines', 100, 100, 'test'], + ['--experimental-test-coverage', true, false, 'test'], + ['--test-coverage-exclude', 'test/**', 'test/**', 'test'], + ['--test-coverage-include', 'src/**', 'src/**', 'test'], + ['--test-update-snapshots', true, true, 'test'], + ['--test-concurrency', 3, 3, 'test'], + ['--test-timeout', 2500, 2500, 'test'], + ['--test-coverage-branches', 90, 90, 'test'], + ['--test-coverage-functions', 85, 85, 'test'], ]; for (const [flagName, configValue, expectedValue, namespace] of configFilePropagationTests) { From 4869f1f8d23906610eb86810c64a86197e66639f Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Fri, 21 Nov 2025 08:49:24 +0100 Subject: [PATCH 2/3] src: add test flag to config file PR-URL: https://github.com/nodejs/node/pull/60798 Reviewed-By: Jacob Smith Reviewed-By: Rafael Gonzaga Signed-off-by: Marco Ippolito --- doc/node-config-schema.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 71df22b020cf46..d2d8e3a2f11bc4 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -833,6 +833,9 @@ "type": "boolean", "description": "launch test runner on startup" }, + "test": { + "type": "boolean" + }, "test-concurrency": { "type": "number", "description": "specify test runner concurrency" From c28ce0d6f3276b6a1904224d3f8a55f5e94f57f3 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Thu, 16 Apr 2026 07:31:35 +0100 Subject: [PATCH 3/3] src: allow empty --experimental-config-file PR-URL: https://github.com/nodejs/node/pull/61610 Reviewed-By: Pietro Marchini Reviewed-By: Moshe Atlow Signed-off-by: Marco Ippolito --- doc/api/cli.md | 13 +- doc/api/test.md | 2 +- doc/node.1 | 70 ++++- lib/internal/main/watch_mode.js | 8 +- lib/internal/process/pre_execution.js | 3 +- lib/internal/test_runner/runner.js | 6 +- src/node.cc | 14 +- src/node_config_file.cc | 64 +++-- src/node_config_file.h | 4 +- src/node_options.cc | 9 +- src/node_options.h | 1 - test/parallel/test-cli-node-options-docs.js | 1 + test/parallel/test-cli-options-as-flags.js | 6 +- test/parallel/test-config-file.js | 241 +++++++++++------- test/parallel/test-permission-config-file.mjs | 27 +- test/parallel/test-runner-cli.js | 43 ++-- test/parallel/test-runner-flag-propagation.js | 15 +- test/sequential/test-watch-mode.mjs | 4 +- 18 files changed, 343 insertions(+), 188 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 4ca461f263b319..c39ab130d9ad7a 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -963,7 +963,7 @@ added: v23.6.0 Enable experimental import support for `.node` addons. -### `--experimental-config-file=config` +### `--experimental-config-file=path`, `--experimental-config-file`