Skip to content

Commit ebd2b91

Browse files
trivikraduh95
authored andcommitted
test_runner: fix watch cwd with isolation none
When watch mode runs with isolation disabled, spawn the child test runner with the files or glob patterns from the current run instead of reusing the parent process argv. This keeps discovery scoped to the configured cwd and avoids rerunning the driver test when the parent argv points outside that cwd. Fixes: #63689 Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.5 PR-URL: #63690 Fixes: #63689 Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
1 parent e75d973 commit ebd2b91

2 files changed

Lines changed: 49 additions & 2 deletions

File tree

lib/internal/test_runner/runner.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const {
1212
ArrayPrototypePush,
1313
ArrayPrototypePushApply,
1414
ArrayPrototypeShift,
15-
ArrayPrototypeSlice,
1615
ArrayPrototypeSome,
1716
ArrayPrototypeSort,
1817
MathMax,
@@ -175,6 +174,9 @@ function getRunArgs(path, { forceExit,
175174
testNamePatterns,
176175
testSkipPatterns,
177176
only,
177+
hasFiles,
178+
testFiles,
179+
globPatterns,
178180
argv: suppliedArgs,
179181
execArgv,
180182
rerunFailuresFilePath,
@@ -232,7 +234,8 @@ function getRunArgs(path, { forceExit,
232234

233235
if (path === kIsolatedProcessName) {
234236
ArrayPrototypePush(runArgs, '--test');
235-
ArrayPrototypePushApply(runArgs, ArrayPrototypeSlice(process.argv, 1));
237+
ArrayPrototypePush(runArgs, '--test-isolation=none');
238+
ArrayPrototypePushApply(runArgs, hasFiles ? testFiles : globPatterns ?? []);
236239
} else {
237240
ArrayPrototypePush(runArgs, path);
238241
}
@@ -951,6 +954,7 @@ function run(options = kEmptyObject) {
951954
workerIdPool: isolation === 'process' ? workerIdPool : null,
952955
randomize,
953956
randomSeed,
957+
testFiles,
954958
};
955959

956960
if (isolation === 'process') {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Test run({ watch: true, cwd, isolation: 'none' }) does not reuse the
2+
// parent process argv when spawning the watch child.
3+
import * as common from '../common/index.mjs';
4+
import assert from 'node:assert';
5+
import { readFileSync, writeFileSync } from 'node:fs';
6+
import { join } from 'node:path';
7+
import { run } from 'node:test';
8+
import tmpdir from '../common/tmpdir.js';
9+
import { skipIfNoWatch } from '../common/watch.js';
10+
11+
skipIfNoWatch();
12+
tmpdir.refresh();
13+
14+
const marker = join(tmpdir.path, 'marker');
15+
writeFileSync(join(tmpdir.path, 'test.js'), `
16+
const test = require('node:test');
17+
const { writeFileSync } = require('node:fs');
18+
19+
test('test ran from cwd', () => {
20+
writeFileSync(${JSON.stringify(marker)}, 'ran');
21+
});
22+
`);
23+
24+
const controller = new AbortController();
25+
const stream = run({
26+
cwd: tmpdir.path,
27+
watch: true,
28+
signal: controller.signal,
29+
isolation: 'none',
30+
}).on('data', function({ type }) {
31+
if (type === 'test:watch:drained') {
32+
stream.removeAllListeners('test:fail');
33+
stream.removeAllListeners('test:pass');
34+
controller.abort();
35+
}
36+
});
37+
38+
stream.on('test:fail', common.mustNotCall());
39+
stream.on('test:pass', common.mustCall(1));
40+
// eslint-disable-next-line no-unused-vars
41+
for await (const _ of stream);
42+
43+
assert.strictEqual(readFileSync(marker, 'utf8'), 'ran');

0 commit comments

Comments
 (0)