From 9c49eec09e2c00afa1da33213f40c1702f13e78d Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 24 Oct 2025 11:54:41 +0200 Subject: [PATCH 1/2] test: move test-runner-watch-mode helper into common --- test/common/watch.js | 159 +++++++++++++++- test/fixtures/test-runner-watch/dependency.js | 1 + .../fixtures/test-runner-watch/dependency.mjs | 1 + test/fixtures/test-runner-watch/test.js | 5 + test/parallel/test-runner-watch-mode.mjs | 171 ++---------------- 5 files changed, 176 insertions(+), 161 deletions(-) create mode 100644 test/fixtures/test-runner-watch/dependency.js create mode 100644 test/fixtures/test-runner-watch/dependency.mjs create mode 100644 test/fixtures/test-runner-watch/test.js diff --git a/test/common/watch.js b/test/common/watch.js index 068790780e1470..47a906e7754495 100644 --- a/test/common/watch.js +++ b/test/common/watch.js @@ -1,7 +1,24 @@ 'use strict'; const common = require('./index.js'); +const tmpdir = require('./tmpdir.js'); +const fixtures = require('./fixtures.js'); +const { writeFileSync, readdirSync, readFileSync, renameSync, unlinkSync } = require('node:fs'); +const { spawn } = require('node:child_process'); +const { once } = require('node:events'); +const assert = require('node:assert'); +const { setTimeout } = require('node:timers/promises'); -exports.skipIfNoWatchModeSignals = function() { +function skipIfNoWatch() { + if (common.isIBMi) { + common.skip('IBMi does not support `fs.watch()`'); + } + + if (common.isAIX) { + common.skip('folder watch capability is limited in AIX.'); + } +} + +function skipIfNoWatchModeSignals() { if (common.isWindows) { common.skip('no signals on Windows'); } @@ -13,4 +30,144 @@ exports.skipIfNoWatchModeSignals = function() { if (common.isAIX) { common.skip('folder watch capability is limited in AIX.'); } +} + +const fixturePaths = {}; +const fixtureContent = {}; + +function refreshForTestRunnerWatch() { + tmpdir.refresh(); + const files = readdirSync(fixtures.path('test-runner-watch')); + for (const file of files) { + const src = fixtures.path('test-runner-watch', file); + const dest = tmpdir.resolve(file); + fixturePaths[file] = dest; + fixtureContent[file] = readFileSync(src, 'utf8'); + writeFileSync(dest, fixtureContent[file]); + } +} + +async function testRunnerWatch({ + fileToUpdate, + file, + action = 'update', + fileToCreate, + isolation, +}) { + const ran1 = Promise.withResolvers(); + const ran2 = Promise.withResolvers(); + const child = spawn(process.execPath, + ['--watch', '--test', '--test-reporter=spec', + isolation ? `--test-isolation=${isolation}` : '', + file ? fixturePaths[file] : undefined].filter(Boolean), + { encoding: 'utf8', stdio: ['inherit', 'pipe', 'inherit'], cwd: tmpdir.path }); + let stdout = ''; + let currentRun = ''; + const runs = []; + + child.stdout.on('data', (data) => { + stdout += data.toString(); + currentRun += data.toString(); + const testRuns = stdout.match(/duration_ms\s\d+/g); + if (testRuns?.length >= 1) ran1.resolve(); + if (testRuns?.length >= 2) ran2.resolve(); + }); + + const testUpdate = async () => { + await ran1.promise; + runs.push(currentRun); + currentRun = ''; + const content = fixtureContent[fileToUpdate]; + const path = fixturePaths[fileToUpdate]; + writeFileSync(path, content); + await setTimeout(common.platformTimeout(1000)); + await ran2.promise; + runs.push(currentRun); + child.kill(); + await once(child, 'exit'); + + assert.strictEqual(runs.length, 2); + + for (const run of runs) { + assert.match(run, /tests 1/); + assert.match(run, /pass 1/); + assert.match(run, /fail 0/); + assert.match(run, /cancelled 0/); + } + }; + + const testRename = async () => { + await ran1.promise; + runs.push(currentRun); + currentRun = ''; + const fileToRenamePath = tmpdir.resolve(fileToUpdate); + const newFileNamePath = tmpdir.resolve(`test-renamed-${fileToUpdate}`); + renameSync(fileToRenamePath, newFileNamePath); + await setTimeout(common.platformTimeout(1000)); + await ran2.promise; + runs.push(currentRun); + child.kill(); + await once(child, 'exit'); + + assert.strictEqual(runs.length, 2); + + for (const run of runs) { + assert.match(run, /tests 1/); + assert.match(run, /pass 1/); + assert.match(run, /fail 0/); + assert.match(run, /cancelled 0/); + } + }; + + const testDelete = async () => { + await ran1.promise; + runs.push(currentRun); + currentRun = ''; + const fileToDeletePath = tmpdir.resolve(fileToUpdate); + unlinkSync(fileToDeletePath); + await setTimeout(common.platformTimeout(2000)); + ran2.resolve(); + runs.push(currentRun); + child.kill(); + await once(child, 'exit'); + + assert.strictEqual(runs.length, 2); + + for (const run of runs) { + assert.doesNotMatch(run, /MODULE_NOT_FOUND/); + } + }; + + const testCreate = async () => { + await ran1.promise; + runs.push(currentRun); + currentRun = ''; + const newFilePath = tmpdir.resolve(fileToCreate); + writeFileSync(newFilePath, 'module.exports = {};'); + await setTimeout(common.platformTimeout(1000)); + await ran2.promise; + runs.push(currentRun); + child.kill(); + await once(child, 'exit'); + + for (const run of runs) { + assert.match(run, /tests 1/); + assert.match(run, /pass 1/); + assert.match(run, /fail 0/); + assert.match(run, /cancelled 0/); + } + }; + + action === 'update' && await testUpdate(); + action === 'rename' && await testRename(); + action === 'delete' && await testDelete(); + action === 'create' && await testCreate(); +} + + +module.exports = { + skipIfNoWatch, + skipIfNoWatchModeSignals, + testRunnerWatch, + refreshForTestRunnerWatch, }; diff --git a/test/fixtures/test-runner-watch/dependency.js b/test/fixtures/test-runner-watch/dependency.js new file mode 100644 index 00000000000000..a0995453769c8a --- /dev/null +++ b/test/fixtures/test-runner-watch/dependency.js @@ -0,0 +1 @@ +module.exports = {}; \ No newline at end of file diff --git a/test/fixtures/test-runner-watch/dependency.mjs b/test/fixtures/test-runner-watch/dependency.mjs new file mode 100644 index 00000000000000..d852a426b2bf36 --- /dev/null +++ b/test/fixtures/test-runner-watch/dependency.mjs @@ -0,0 +1 @@ +export const a = 1; \ No newline at end of file diff --git a/test/fixtures/test-runner-watch/test.js b/test/fixtures/test-runner-watch/test.js new file mode 100644 index 00000000000000..85606b1535b286 --- /dev/null +++ b/test/fixtures/test-runner-watch/test.js @@ -0,0 +1,5 @@ +const test = require('node:test'); +require('./dependency.js'); +import('./dependency.mjs'); +import('data:text/javascript,'); +test('test has ran'); \ No newline at end of file diff --git a/test/parallel/test-runner-watch-mode.mjs b/test/parallel/test-runner-watch-mode.mjs index d23830cbae1704..d6931ef9a79cab 100644 --- a/test/parallel/test-runner-watch-mode.mjs +++ b/test/parallel/test-runner-watch-mode.mjs @@ -1,184 +1,35 @@ -import * as common from '../common/index.mjs'; +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; import { describe, it, beforeEach } from 'node:test'; -import { once } from 'node:events'; -import assert from 'node:assert'; -import { spawn } from 'node:child_process'; -import { writeFileSync, renameSync, unlinkSync } from 'node:fs'; -import { setTimeout } from 'node:timers/promises'; -import tmpdir from '../common/tmpdir.js'; -if (common.isIBMi) - common.skip('IBMi does not support `fs.watch()`'); - -if (common.isAIX) - common.skip('folder watch capability is limited in AIX.'); - -let fixturePaths; - -// This test updates these files repeatedly, -// Reading them from disk is unreliable due to race conditions. -const fixtureContent = { - 'dependency.js': 'module.exports = {};', - 'dependency.mjs': 'export const a = 1;', - 'test.js': ` -const test = require('node:test'); -require('./dependency.js'); -import('./dependency.mjs'); -import('data:text/javascript,'); -test('test has ran');`, -}; - -function refresh() { - tmpdir.refresh(); - fixturePaths = Object.keys(fixtureContent) - .reduce((acc, file) => ({ ...acc, [file]: tmpdir.resolve(file) }), {}); - Object.entries(fixtureContent) - .forEach(([file, content]) => writeFileSync(fixturePaths[file], content)); -} - -async function testWatch({ - fileToUpdate, - file, - action = 'update', - fileToCreate, - isolation, -}) { - const ran1 = Promise.withResolvers(); - const ran2 = Promise.withResolvers(); - const child = spawn(process.execPath, - ['--watch', '--test', '--test-reporter=spec', - isolation ? `--test-isolation=${isolation}` : '', - file ? fixturePaths[file] : undefined].filter(Boolean), - { encoding: 'utf8', stdio: 'pipe', cwd: tmpdir.path }); - let stdout = ''; - let currentRun = ''; - const runs = []; - - child.stdout.on('data', (data) => { - stdout += data.toString(); - currentRun += data.toString(); - const testRuns = stdout.match(/duration_ms\s\d+/g); - if (testRuns?.length >= 1) ran1.resolve(); - if (testRuns?.length >= 2) ran2.resolve(); - }); - - const testUpdate = async () => { - await ran1.promise; - runs.push(currentRun); - currentRun = ''; - const content = fixtureContent[fileToUpdate]; - const path = fixturePaths[fileToUpdate]; - writeFileSync(path, content); - await setTimeout(common.platformTimeout(1000)); - await ran2.promise; - runs.push(currentRun); - child.kill(); - await once(child, 'exit'); - - assert.strictEqual(runs.length, 2); - - for (const run of runs) { - assert.match(run, /tests 1/); - assert.match(run, /pass 1/); - assert.match(run, /fail 0/); - assert.match(run, /cancelled 0/); - } - }; - - const testRename = async () => { - await ran1.promise; - runs.push(currentRun); - currentRun = ''; - const fileToRenamePath = tmpdir.resolve(fileToUpdate); - const newFileNamePath = tmpdir.resolve(`test-renamed-${fileToUpdate}`); - renameSync(fileToRenamePath, newFileNamePath); - await setTimeout(common.platformTimeout(1000)); - await ran2.promise; - runs.push(currentRun); - child.kill(); - await once(child, 'exit'); - - assert.strictEqual(runs.length, 2); - - for (const run of runs) { - assert.match(run, /tests 1/); - assert.match(run, /pass 1/); - assert.match(run, /fail 0/); - assert.match(run, /cancelled 0/); - } - }; - - const testDelete = async () => { - await ran1.promise; - runs.push(currentRun); - currentRun = ''; - const fileToDeletePath = tmpdir.resolve(fileToUpdate); - unlinkSync(fileToDeletePath); - await setTimeout(common.platformTimeout(2000)); - ran2.resolve(); - runs.push(currentRun); - child.kill(); - await once(child, 'exit'); - - assert.strictEqual(runs.length, 2); - - for (const run of runs) { - assert.doesNotMatch(run, /MODULE_NOT_FOUND/); - } - }; - - const testCreate = async () => { - await ran1.promise; - runs.push(currentRun); - currentRun = ''; - const newFilePath = tmpdir.resolve(fileToCreate); - writeFileSync(newFilePath, 'module.exports = {};'); - await setTimeout(common.platformTimeout(1000)); - await ran2.promise; - runs.push(currentRun); - child.kill(); - await once(child, 'exit'); - - for (const run of runs) { - assert.match(run, /tests 1/); - assert.match(run, /pass 1/); - assert.match(run, /fail 0/); - assert.match(run, /cancelled 0/); - } - }; - - action === 'update' && await testUpdate(); - action === 'rename' && await testRename(); - action === 'delete' && await testDelete(); - action === 'create' && await testCreate(); -} +skipIfNoWatch(); describe('test runner watch mode', () => { - beforeEach(refresh); + beforeEach(refreshForTestRunnerWatch); for (const isolation of ['none', 'process']) { describe(`isolation: ${isolation}`, () => { it('should run tests repeatedly', async () => { - await testWatch({ file: 'test.js', fileToUpdate: 'test.js', isolation }); + await testRunnerWatch({ file: 'test.js', fileToUpdate: 'test.js', isolation }); }); it('should run tests with dependency repeatedly', async () => { - await testWatch({ file: 'test.js', fileToUpdate: 'dependency.js', isolation }); + await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.js', isolation }); }); it('should run tests with ESM dependency', async () => { - await testWatch({ file: 'test.js', fileToUpdate: 'dependency.mjs', isolation }); + await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.mjs', isolation }); }); it('should support running tests without a file', async () => { - await testWatch({ fileToUpdate: 'test.js', isolation }); + await testRunnerWatch({ fileToUpdate: 'test.js', isolation }); }); it('should support a watched test file rename', async () => { - await testWatch({ fileToUpdate: 'test.js', action: 'rename', isolation }); + await testRunnerWatch({ fileToUpdate: 'test.js', action: 'rename', isolation }); }); it('should not throw when delete a watched test file', async () => { - await testWatch({ fileToUpdate: 'test.js', action: 'delete', isolation }); + await testRunnerWatch({ fileToUpdate: 'test.js', action: 'delete', isolation }); }); it('should run new tests when a new file is created in the watched directory', { @@ -186,7 +37,7 @@ describe('test runner watch mode', () => { 'This test is failing when isolation is set to none and must be fixed' : undefined, }, async () => { - await testWatch({ action: 'create', fileToCreate: 'new-test-file.test.js', isolation }); + await testRunnerWatch({ action: 'create', fileToCreate: 'new-test-file.test.js', isolation }); }); }); } From 711affc5926d0478c0bdd33ee58d721ab62fd136 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 24 Oct 2025 12:59:47 +0200 Subject: [PATCH 2/2] test: split test-runner-watch-mode The test has been flaky for years and new platforms keep popping up. As it squeezes too many independent test cases into one file, split them into individual files to avoid masking regressions and help only mark the real flaky ones as flaky. This might also help with the flakiness itself by avoiding updating a shared tmpdir being watched by differet tests and avoiding running all these time-consuming tests in one file, which can cause a timeout on slow machines. --- test/common/watch.js | 2 +- test/parallel/parallel.status | 4 -- test/parallel/test-runner-watch-mode.mjs | 44 ------------------- test/test-runner/test-runner.status | 4 ++ .../test-watch-create-isolation-none.mjs | 8 ++++ .../test-watch-create-isolation-process.mjs | 8 ++++ .../test-watch-delete-isolation-none.mjs | 8 ++++ .../test-watch-delete-isolation-process.mjs | 8 ++++ .../test-watch-dependency-isolation-none.mjs | 8 ++++ ...est-watch-dependency-isolation-process.mjs | 8 ++++ ...st-watch-esm-dependency-isolation-none.mjs | 8 ++++ ...watch-esm-dependency-isolation-process.mjs | 8 ++++ .../test-watch-no-file-isolation-none.mjs | 8 ++++ .../test-watch-no-file-isolation-process.mjs | 8 ++++ .../test-watch-rename-isolation-none.mjs | 8 ++++ .../test-watch-rename-isolation-process.mjs | 8 ++++ ...st-watch-run-repeatedly-isolation-none.mjs | 8 ++++ ...watch-run-repeatedly-isolation-process.mjs | 8 ++++ 18 files changed, 117 insertions(+), 49 deletions(-) delete mode 100644 test/parallel/test-runner-watch-mode.mjs create mode 100644 test/test-runner/test-watch-create-isolation-none.mjs create mode 100644 test/test-runner/test-watch-create-isolation-process.mjs create mode 100644 test/test-runner/test-watch-delete-isolation-none.mjs create mode 100644 test/test-runner/test-watch-delete-isolation-process.mjs create mode 100644 test/test-runner/test-watch-dependency-isolation-none.mjs create mode 100644 test/test-runner/test-watch-dependency-isolation-process.mjs create mode 100644 test/test-runner/test-watch-esm-dependency-isolation-none.mjs create mode 100644 test/test-runner/test-watch-esm-dependency-isolation-process.mjs create mode 100644 test/test-runner/test-watch-no-file-isolation-none.mjs create mode 100644 test/test-runner/test-watch-no-file-isolation-process.mjs create mode 100644 test/test-runner/test-watch-rename-isolation-none.mjs create mode 100644 test/test-runner/test-watch-rename-isolation-process.mjs create mode 100644 test/test-runner/test-watch-run-repeatedly-isolation-none.mjs create mode 100644 test/test-runner/test-watch-run-repeatedly-isolation-process.mjs diff --git a/test/common/watch.js b/test/common/watch.js index 47a906e7754495..1831939b5a99e5 100644 --- a/test/common/watch.js +++ b/test/common/watch.js @@ -60,7 +60,7 @@ async function testRunnerWatch({ ['--watch', '--test', '--test-reporter=spec', isolation ? `--test-isolation=${isolation}` : '', file ? fixturePaths[file] : undefined].filter(Boolean), - { encoding: 'utf8', stdio: ['inherit', 'pipe', 'inherit'], cwd: tmpdir.path }); + { encoding: 'utf8', stdio: 'pipe', cwd: tmpdir.path }); let stdout = ''; let currentRun = ''; const runs = []; diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index 5cb15393e42d4f..bd4ad779d69382 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -50,10 +50,6 @@ test-runner-run-watch: PASS, FLAKY # https://github.com/nodejs/node/issues/58353 test-http2-debug: PASS, FLAKY -[$system==linux || $system==win32] -# https://github.com/nodejs/node/issues/49605 -test-runner-watch-mode: PASS,FLAKY - [$system==macos] # https://github.com/nodejs/node/issues/42741 test-http-server-headers-timeout-keepalive: PASS,FLAKY diff --git a/test/parallel/test-runner-watch-mode.mjs b/test/parallel/test-runner-watch-mode.mjs deleted file mode 100644 index d6931ef9a79cab..00000000000000 --- a/test/parallel/test-runner-watch-mode.mjs +++ /dev/null @@ -1,44 +0,0 @@ -import '../common/index.mjs'; -import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; -import { describe, it, beforeEach } from 'node:test'; - -skipIfNoWatch(); - -describe('test runner watch mode', () => { - beforeEach(refreshForTestRunnerWatch); - for (const isolation of ['none', 'process']) { - describe(`isolation: ${isolation}`, () => { - it('should run tests repeatedly', async () => { - await testRunnerWatch({ file: 'test.js', fileToUpdate: 'test.js', isolation }); - }); - - it('should run tests with dependency repeatedly', async () => { - await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.js', isolation }); - }); - - it('should run tests with ESM dependency', async () => { - await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.mjs', isolation }); - }); - - it('should support running tests without a file', async () => { - await testRunnerWatch({ fileToUpdate: 'test.js', isolation }); - }); - - it('should support a watched test file rename', async () => { - await testRunnerWatch({ fileToUpdate: 'test.js', action: 'rename', isolation }); - }); - - it('should not throw when delete a watched test file', async () => { - await testRunnerWatch({ fileToUpdate: 'test.js', action: 'delete', isolation }); - }); - - it('should run new tests when a new file is created in the watched directory', { - todo: isolation === 'none' ? - 'This test is failing when isolation is set to none and must be fixed' : - undefined, - }, async () => { - await testRunnerWatch({ action: 'create', fileToCreate: 'new-test-file.test.js', isolation }); - }); - }); - } -}); diff --git a/test/test-runner/test-runner.status b/test/test-runner/test-runner.status index 65ae96eb9e3726..e8b4ff2d32248c 100644 --- a/test/test-runner/test-runner.status +++ b/test/test-runner/test-runner.status @@ -5,3 +5,7 @@ prefix test-runner # sample-test : PASS,FLAKY [true] # This section applies to all platforms + +# https://github.com/nodejs/node/pull/54888#issuecomment-2351128116 +# TODO(pmarchini): This test is failing when isolation is set to none and must be fixed. +test-watch-create-isolation-none: SKIP diff --git a/test/test-runner/test-watch-create-isolation-none.mjs b/test/test-runner/test-watch-create-isolation-none.mjs new file mode 100644 index 00000000000000..c7035ea63afd2c --- /dev/null +++ b/test/test-runner/test-watch-create-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none runs tests when a new file is created in the watched directory +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ action: 'create', fileToCreate: 'new-test-file.test.js', isolation: 'none' }); diff --git a/test/test-runner/test-watch-create-isolation-process.mjs b/test/test-runner/test-watch-create-isolation-process.mjs new file mode 100644 index 00000000000000..d1eaa9667d2e32 --- /dev/null +++ b/test/test-runner/test-watch-create-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process runs tests when a new file is created in the watched directory +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ action: 'create', fileToCreate: 'new-test-file.test.js', isolation: 'process' }); diff --git a/test/test-runner/test-watch-delete-isolation-none.mjs b/test/test-runner/test-watch-delete-isolation-none.mjs new file mode 100644 index 00000000000000..210d2a87f82666 --- /dev/null +++ b/test/test-runner/test-watch-delete-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none does not throw when deleting a watched test file +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ fileToUpdate: 'test.js', action: 'delete', isolation: 'none' }); diff --git a/test/test-runner/test-watch-delete-isolation-process.mjs b/test/test-runner/test-watch-delete-isolation-process.mjs new file mode 100644 index 00000000000000..d09b84caf53ea7 --- /dev/null +++ b/test/test-runner/test-watch-delete-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process does not throw when deleting a watched test file +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ fileToUpdate: 'test.js', action: 'delete', isolation: 'process' }); diff --git a/test/test-runner/test-watch-dependency-isolation-none.mjs b/test/test-runner/test-watch-dependency-isolation-none.mjs new file mode 100644 index 00000000000000..7171a334ce03bd --- /dev/null +++ b/test/test-runner/test-watch-dependency-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none runs tests with dependency repeatedly +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.js', isolation: 'none' }); diff --git a/test/test-runner/test-watch-dependency-isolation-process.mjs b/test/test-runner/test-watch-dependency-isolation-process.mjs new file mode 100644 index 00000000000000..25b8d00f3b0283 --- /dev/null +++ b/test/test-runner/test-watch-dependency-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process runs tests with dependency repeatedly +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.js', isolation: 'process' }); diff --git a/test/test-runner/test-watch-esm-dependency-isolation-none.mjs b/test/test-runner/test-watch-esm-dependency-isolation-none.mjs new file mode 100644 index 00000000000000..d066bd90d74ce5 --- /dev/null +++ b/test/test-runner/test-watch-esm-dependency-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none runs tests with ESM dependency +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.mjs', isolation: 'none' }); diff --git a/test/test-runner/test-watch-esm-dependency-isolation-process.mjs b/test/test-runner/test-watch-esm-dependency-isolation-process.mjs new file mode 100644 index 00000000000000..7e0ad48ece03d7 --- /dev/null +++ b/test/test-runner/test-watch-esm-dependency-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process runs tests with ESM dependency +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ file: 'test.js', fileToUpdate: 'dependency.mjs', isolation: 'process' }); diff --git a/test/test-runner/test-watch-no-file-isolation-none.mjs b/test/test-runner/test-watch-no-file-isolation-none.mjs new file mode 100644 index 00000000000000..ebf14d828a32c5 --- /dev/null +++ b/test/test-runner/test-watch-no-file-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none runs tests without a file argument +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ fileToUpdate: 'test.js', isolation: 'none' }); diff --git a/test/test-runner/test-watch-no-file-isolation-process.mjs b/test/test-runner/test-watch-no-file-isolation-process.mjs new file mode 100644 index 00000000000000..76991b37189894 --- /dev/null +++ b/test/test-runner/test-watch-no-file-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process runs tests without a file argument +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ fileToUpdate: 'test.js', isolation: 'process' }); diff --git a/test/test-runner/test-watch-rename-isolation-none.mjs b/test/test-runner/test-watch-rename-isolation-none.mjs new file mode 100644 index 00000000000000..d125b33ce83d84 --- /dev/null +++ b/test/test-runner/test-watch-rename-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none handles a watched test file rename +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ fileToUpdate: 'test.js', action: 'rename', isolation: 'none' }); diff --git a/test/test-runner/test-watch-rename-isolation-process.mjs b/test/test-runner/test-watch-rename-isolation-process.mjs new file mode 100644 index 00000000000000..e784831a33bfa0 --- /dev/null +++ b/test/test-runner/test-watch-rename-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process handles a watched test file rename +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ fileToUpdate: 'test.js', action: 'rename', isolation: 'process' }); diff --git a/test/test-runner/test-watch-run-repeatedly-isolation-none.mjs b/test/test-runner/test-watch-run-repeatedly-isolation-none.mjs new file mode 100644 index 00000000000000..763f5a3be05f14 --- /dev/null +++ b/test/test-runner/test-watch-run-repeatedly-isolation-none.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=none runs tests repeatedly +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ file: 'test.js', fileToUpdate: 'test.js', isolation: 'none' }); diff --git a/test/test-runner/test-watch-run-repeatedly-isolation-process.mjs b/test/test-runner/test-watch-run-repeatedly-isolation-process.mjs new file mode 100644 index 00000000000000..07719cfd77710f --- /dev/null +++ b/test/test-runner/test-watch-run-repeatedly-isolation-process.mjs @@ -0,0 +1,8 @@ +// Test --test --watch --test-isolation=process runs tests repeatedly +import '../common/index.mjs'; +import { skipIfNoWatch, refreshForTestRunnerWatch, testRunnerWatch } from '../common/watch.js'; + +skipIfNoWatch(); +refreshForTestRunnerWatch(); + +await testRunnerWatch({ file: 'test.js', fileToUpdate: 'test.js', isolation: 'process' });