From 3065b0f67416a7cc67fceb9e4310070c6648f400 Mon Sep 17 00:00:00 2001 From: Ian Hou <45278651+iankhou@users.noreply.github.com> Date: Thu, 12 Feb 2026 15:13:40 -0500 Subject: [PATCH 1/7] integ tests for cli and toolkit lib for cdk watch --- ...le-changes-with-glob-patterns.integtest.ts | 113 ++++++++++++++ .../toolkit-watch-glob.integtest.ts | 146 ++++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts create mode 100644 packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts new file mode 100644 index 000000000..79efbfe54 --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts @@ -0,0 +1,113 @@ +import * as child_process from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; +import { integTest, withDefaultFixture } from '../../../lib'; + +jest.setTimeout(10 * 60 * 1000); // 10 minutes for watch tests + +/** + * Integration test for cdk watch with glob pattern support. + * + * This test verifies that the chokidar v4 glob pattern fix works correctly + * by running `cdk watch` and verifying it detects file changes. + */ +integTest( + 'cdk watch detects file changes with glob patterns', + withDefaultFixture(async (fixture) => { + // Create a test file that will be watched + const testFile = path.join(fixture.integTestDir, 'watch-test-file.ts'); + fs.writeFileSync(testFile, 'export const initial = true;'); + + // Make CLI available + await fixture.cli.makeCliAvailable(); + + // Accumulate output from the watch process + let output = ''; + + // Start cdk watch in the background using child_process directly + const watchProcess = child_process.spawn('cdk', [ + 'watch', + '--hotswap', + '-v', + fixture.fullStackName('test-1'), + ], { + cwd: fixture.integTestDir, + shell: true, + env: { + ...process.env, + ...fixture.cdkShellEnv(), + }, + }); + + watchProcess.stdout?.on('data', (data) => { + output += data.toString(); + fixture.log(data.toString()); + }); + + watchProcess.stderr?.on('data', (data) => { + output += data.toString(); + fixture.log(data.toString()); + }); + + try { + // Wait for the initial deployment to start + await waitForOutput(() => output, "Triggering initial 'cdk deploy'", 120000); + fixture.log('✓ Watch started and triggered initial deploy'); + + // Wait for the initial deploy to complete (look for deployment success message) + await waitForOutput(() => output, 'deployment time', 300000); + fixture.log('✓ Initial deployment completed'); + + // Modify the test file to trigger a watch event + fs.writeFileSync(testFile, 'export const modified = true;'); + + // Wait for the watch to detect the change + await waitForOutput(() => output, 'Detected change to', 60000); + fixture.log('✓ Watch detected file change'); + + // Verify the deployment was triggered + await waitForOutput(() => output, "Triggering 'cdk deploy'", 60000); + fixture.log('✓ Watch triggered deployment after file change'); + } finally { + // Clean up: kill the watch process + watchProcess.kill('SIGTERM'); + + // Wait a bit for process to terminate + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Clean up test file + if (fs.existsSync(testFile)) { + fs.unlinkSync(testFile); + } + + // Destroy the stack + await fixture.cdkDestroy('test-1'); + } + }), +); + +/** + * Wait for a specific output string in the accumulated output + */ +async function waitForOutput(getOutput: () => string, searchString: string, timeoutMs: number): Promise { + const startTime = Date.now(); + + return new Promise((resolve, reject) => { + const checkOutput = () => { + const currentOutput = getOutput(); + if (currentOutput.includes(searchString)) { + resolve(); + return; + } + + if (Date.now() - startTime > timeoutMs) { + reject(new Error(`Timeout waiting for output: "${searchString}". Current output:\n${currentOutput.slice(-2000)}`)); + return; + } + + setTimeout(checkOutput, 1000); + }; + + checkOutput(); + }); +} diff --git a/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts new file mode 100644 index 000000000..9acd2e2b2 --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts @@ -0,0 +1,146 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import * as fs from 'fs'; +import * as path from 'path'; +import * as toolkit from '@aws-cdk/toolkit-lib'; +import { assemblyFromCdkAppDir, toolkitFromFixture } from './toolkit-helpers'; +import { integTest, withDefaultFixture } from '../../lib'; + +/** + * Integration tests for toolkit-lib watch with glob pattern matching. + * + * These tests verify that the chokidar v4 glob pattern fix works correctly + * by using the actual Toolkit.watch() method with real file system operations. + */ + +integTest( + 'toolkit watch detects file changes with glob patterns', + withDefaultFixture(async (fixture) => { + const tk = toolkitFromFixture(fixture); + const assembly = await assemblyFromCdkAppDir(tk, fixture); + + // Track events received from the watcher + const receivedEvents: Array<{ code: string | undefined; message: string }> = []; + + // Create a custom IoHost to capture watch events + const customTk = new toolkit.Toolkit({ + ioHost: { + notify: async (msg) => { + receivedEvents.push({ code: msg.code, message: msg.message }); + }, + requestResponse: async (): Promise => undefined as unknown as T, + }, + }); + + // Create a test file in the watch directory + const testFile = path.join(fixture.integTestDir, 'watch-test-file.ts'); + + // Start watching with specific include patterns + const watcher = await customTk.watch(assembly, { + include: ['**/*.ts'], + exclude: ['**/node_modules/**', '**/*.test.ts'], + watchDir: fixture.integTestDir, + // Use a deployment method that won't actually deploy (we just want to test file watching) + deploymentMethod: { method: 'hotswap' }, + }); + + try { + // Wait a bit for the watcher to initialize + await sleep(1000); + + // Create a new .ts file - this should be detected + fs.writeFileSync(testFile, 'export const watchTest = true;'); + + // Wait for the file change to be detected + await sleep(2000); + + // Verify that the watcher detected the file + const observingEvents = receivedEvents.filter(e => + e.code === 'CDK_TOOLKIT_I5311' || // observing file + e.code === 'CDK_TOOLKIT_I5312' || // detected change + e.code === 'CDK_TOOLKIT_I5314', // triggering deploy + ); + + fixture.log(`Received ${observingEvents.length} watch-related events`); + for (const event of observingEvents) { + fixture.log(` ${event.code}: ${event.message.substring(0, 100)}...`); + } + + // The watcher should have received the ready event and started observing + const hasReadyOrObserving = receivedEvents.some(e => + e.code === 'CDK_TOOLKIT_I5314' || // triggering initial deploy + e.code === 'CDK_TOOLKIT_I5311', // observing files + ); + + if (!hasReadyOrObserving) { + throw new Error('Watcher did not emit ready/observing events'); + } + + fixture.log('✓ Toolkit watch successfully initialized and detected files'); + } finally { + // Clean up + await watcher.dispose(); + if (fs.existsSync(testFile)) { + fs.unlinkSync(testFile); + } + } + }), +); + +integTest( + 'toolkit watch excludes node_modules and dotfiles by default', + withDefaultFixture(async (fixture) => { + const tk = toolkitFromFixture(fixture); + const assembly = await assemblyFromCdkAppDir(tk, fixture); + + // Track the exclude patterns that were configured + const configMessages: string[] = []; + + // Create a custom IoHost to capture configuration messages + const customTk = new toolkit.Toolkit({ + ioHost: { + notify: async (msg) => { + if (msg.code === 'CDK_TOOLKIT_I5310') { + configMessages.push(msg.message); + } + }, + requestResponse: async (): Promise => undefined as unknown as T, + }, + }); + + // Start watching with default exclude patterns + const watcher = await customTk.watch(assembly, { + include: ['**'], + watchDir: fixture.integTestDir, + deploymentMethod: { method: 'hotswap' }, + }); + + try { + // Wait for initialization + await sleep(500); + + // Verify that default excludes are applied + const configMsg = configMessages.find(m => m.includes("'exclude' patterns")); + + if (!configMsg) { + throw new Error('Did not receive exclude patterns configuration message'); + } + + // Check that default excludes are present + if (!configMsg.includes('node_modules')) { + throw new Error('Default excludes should include node_modules'); + } + if (!configMsg.includes('.*')) { + throw new Error('Default excludes should include dotfiles (.*)'); + } + + fixture.log('✓ Toolkit watch applies default exclude patterns correctly'); + fixture.log(` Config: ${configMsg.substring(0, 200)}...`); + } finally { + await watcher.dispose(); + } + }), +); + +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} From 2b1ee05273eaebe82c8bc184e8e8279c3de3adc4 Mon Sep 17 00:00:00 2001 From: Ian Hou <45278651+iankhou@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:56:39 -0500 Subject: [PATCH 2/7] watch test fix --- ...-detects-file-changes-with-glob-patterns.integtest.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts index 79efbfe54..24473695e 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts @@ -18,6 +18,15 @@ integTest( const testFile = path.join(fixture.integTestDir, 'watch-test-file.ts'); fs.writeFileSync(testFile, 'export const initial = true;'); + // Update cdk.json to include watch configuration + const cdkJsonPath = path.join(fixture.integTestDir, 'cdk.json'); + const cdkJson = JSON.parse(fs.readFileSync(cdkJsonPath, 'utf-8')); + cdkJson.watch = { + include: ['**/*.ts', '**/*.js'], + exclude: ['node_modules/**', 'cdk.out/**', '**/*.d.ts'], + }; + fs.writeFileSync(cdkJsonPath, JSON.stringify(cdkJson, null, 2)); + // Make CLI available await fixture.cli.makeCliAvailable(); From 36efe3059a15c721233c589f8dbfe1b413fd7a80 Mon Sep 17 00:00:00 2001 From: Ian Hou <45278651+iankhou@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:42:41 -0500 Subject: [PATCH 3/7] cleanup for watch tests --- ...le-changes-with-glob-patterns.integtest.ts | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts index 24473695e..2e5797c20 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts @@ -74,17 +74,38 @@ integTest( await waitForOutput(() => output, 'Detected change to', 60000); fixture.log('✓ Watch detected file change'); - // Verify the deployment was triggered - await waitForOutput(() => output, "Triggering 'cdk deploy'", 60000); + // Wait for the second deployment to complete + // Count occurrences of 'deployment time' - need to see it twice + await waitForCondition( + () => (output.match(/deployment time/g) || []).length >= 2, + 60000, + 'second deployment to complete', + ); fixture.log('✓ Watch triggered deployment after file change'); } finally { - // Clean up: kill the watch process + // Clean up: kill the watch process first and wait for it to fully terminate + // before doing anything else to avoid conflicts watchProcess.kill('SIGTERM'); - // Wait a bit for process to terminate - await new Promise(resolve => setTimeout(resolve, 1000)); + // Wait for the process to actually exit + await new Promise((resolve) => { + const timeout = setTimeout(() => { + watchProcess.kill('SIGKILL'); + resolve(); + }, 10000); - // Clean up test file + watchProcess.on('exit', () => { + clearTimeout(timeout); + resolve(); + }); + }); + + fixture.log('✓ Watch process terminated'); + + // Wait additional time to ensure no lingering file handles + await new Promise(resolve => setTimeout(resolve, 2000)); + + // Clean up test file (do this AFTER watch is fully stopped) if (fs.existsSync(testFile)) { fs.unlinkSync(testFile); } @@ -120,3 +141,32 @@ async function waitForOutput(getOutput: () => string, searchString: string, time checkOutput(); }); } + +/** + * Wait for a condition to become true + */ +async function waitForCondition( + condition: () => boolean, + timeoutMs: number, + description: string, +): Promise { + const startTime = Date.now(); + + return new Promise((resolve, reject) => { + const check = () => { + if (condition()) { + resolve(); + return; + } + + if (Date.now() - startTime > timeoutMs) { + reject(new Error(`Timeout waiting for ${description}`)); + return; + } + + setTimeout(check, 1000); + }; + + check(); + }); +} From 8a75e290ec42eba91edf1e9c916baa67cf6cd904 Mon Sep 17 00:00:00 2001 From: Ian Hou <45278651+iankhou@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:55:26 -0500 Subject: [PATCH 4/7] cleanup and remove unnecessary file removal logic] --- ...le-changes-with-glob-patterns.integtest.ts | 108 ++++-------------- 1 file changed, 21 insertions(+), 87 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts index 2e5797c20..411eeeab2 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts @@ -5,12 +5,6 @@ import { integTest, withDefaultFixture } from '../../../lib'; jest.setTimeout(10 * 60 * 1000); // 10 minutes for watch tests -/** - * Integration test for cdk watch with glob pattern support. - * - * This test verifies that the chokidar v4 glob pattern fix works correctly - * by running `cdk watch` and verifying it detects file changes. - */ integTest( 'cdk watch detects file changes with glob patterns', withDefaultFixture(async (fixture) => { @@ -27,146 +21,86 @@ integTest( }; fs.writeFileSync(cdkJsonPath, JSON.stringify(cdkJson, null, 2)); - // Make CLI available await fixture.cli.makeCliAvailable(); - // Accumulate output from the watch process let output = ''; - // Start cdk watch in the background using child_process directly + // Start cdk watch with detached process group for clean termination const watchProcess = child_process.spawn('cdk', [ - 'watch', - '--hotswap', - '-v', - fixture.fullStackName('test-1'), + 'watch', '--hotswap', '-v', fixture.fullStackName('test-1'), ], { cwd: fixture.integTestDir, shell: true, - env: { - ...process.env, - ...fixture.cdkShellEnv(), - }, + detached: true, + env: { ...process.env, ...fixture.cdkShellEnv() }, }); watchProcess.stdout?.on('data', (data) => { output += data.toString(); fixture.log(data.toString()); }); - watchProcess.stderr?.on('data', (data) => { output += data.toString(); fixture.log(data.toString()); }); try { - // Wait for the initial deployment to start await waitForOutput(() => output, "Triggering initial 'cdk deploy'", 120000); - fixture.log('✓ Watch started and triggered initial deploy'); + fixture.log('✓ Watch started'); - // Wait for the initial deploy to complete (look for deployment success message) await waitForOutput(() => output, 'deployment time', 300000); fixture.log('✓ Initial deployment completed'); // Modify the test file to trigger a watch event fs.writeFileSync(testFile, 'export const modified = true;'); - // Wait for the watch to detect the change await waitForOutput(() => output, 'Detected change to', 60000); fixture.log('✓ Watch detected file change'); - // Wait for the second deployment to complete - // Count occurrences of 'deployment time' - need to see it twice + // Wait for second deployment await waitForCondition( () => (output.match(/deployment time/g) || []).length >= 2, 60000, 'second deployment to complete', ); - fixture.log('✓ Watch triggered deployment after file change'); + fixture.log('✓ Deployment triggered after file change'); } finally { - // Clean up: kill the watch process first and wait for it to fully terminate - // before doing anything else to avoid conflicts - watchProcess.kill('SIGTERM'); - - // Wait for the process to actually exit - await new Promise((resolve) => { - const timeout = setTimeout(() => { - watchProcess.kill('SIGKILL'); - resolve(); - }, 10000); - - watchProcess.on('exit', () => { - clearTimeout(timeout); - resolve(); - }); - }); - - fixture.log('✓ Watch process terminated'); - - // Wait additional time to ensure no lingering file handles - await new Promise(resolve => setTimeout(resolve, 2000)); - - // Clean up test file (do this AFTER watch is fully stopped) - if (fs.existsSync(testFile)) { - fs.unlinkSync(testFile); + // Kill entire process group + if (watchProcess.pid) { + try { process.kill(-watchProcess.pid, 'SIGKILL'); } catch { /* ignore */ } } + await new Promise(resolve => setTimeout(resolve, 3000)); - // Destroy the stack - await fixture.cdkDestroy('test-1'); + // Use separate output dir to avoid conflicts with lingering watch process + await fixture.cdkDestroy('test-1', { options: ['--output', 'cdk-destroy.out'] }); } }), ); -/** - * Wait for a specific output string in the accumulated output - */ async function waitForOutput(getOutput: () => string, searchString: string, timeoutMs: number): Promise { const startTime = Date.now(); - return new Promise((resolve, reject) => { - const checkOutput = () => { - const currentOutput = getOutput(); - if (currentOutput.includes(searchString)) { - resolve(); - return; - } - + const check = () => { + if (getOutput().includes(searchString)) return resolve(); if (Date.now() - startTime > timeoutMs) { - reject(new Error(`Timeout waiting for output: "${searchString}". Current output:\n${currentOutput.slice(-2000)}`)); - return; + return reject(new Error(`Timeout waiting for: "${searchString}"`)); } - - setTimeout(checkOutput, 1000); + setTimeout(check, 1000); }; - - checkOutput(); + check(); }); } -/** - * Wait for a condition to become true - */ -async function waitForCondition( - condition: () => boolean, - timeoutMs: number, - description: string, -): Promise { +async function waitForCondition(condition: () => boolean, timeoutMs: number, description: string): Promise { const startTime = Date.now(); - return new Promise((resolve, reject) => { const check = () => { - if (condition()) { - resolve(); - return; - } - + if (condition()) return resolve(); if (Date.now() - startTime > timeoutMs) { - reject(new Error(`Timeout waiting for ${description}`)); - return; + return reject(new Error(`Timeout waiting for ${description}`)); } - setTimeout(check, 1000); }; - check(); }); } From d72ce2c881b2d816f72bf9f98d2c53209598442c Mon Sep 17 00:00:00 2001 From: Ian Hou <45278651+iankhou@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:14:30 -0500 Subject: [PATCH 5/7] format --- ...watch-detects-file-changes-with-glob-patterns.integtest.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts index 411eeeab2..d969970e8 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts @@ -67,7 +67,9 @@ integTest( } finally { // Kill entire process group if (watchProcess.pid) { - try { process.kill(-watchProcess.pid, 'SIGKILL'); } catch { /* ignore */ } + try { process.kill(-watchProcess.pid, 'SIGKILL'); } catch { + /* ignore */ + } } await new Promise(resolve => setTimeout(resolve, 3000)); From dd94cc5b65dab0ffcdfc73294261ca435f3629ea Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 21:23:46 +0000 Subject: [PATCH 6/7] chore: self mutation Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- ...watch-detects-file-changes-with-glob-patterns.integtest.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts index d969970e8..6dd0f9461 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/watch/cdk-watch-detects-file-changes-with-glob-patterns.integtest.ts @@ -67,7 +67,9 @@ integTest( } finally { // Kill entire process group if (watchProcess.pid) { - try { process.kill(-watchProcess.pid, 'SIGKILL'); } catch { + try { + process.kill(-watchProcess.pid, 'SIGKILL'); + } catch { /* ignore */ } } From 768aa69dc1be94262327c3fd9744f9970dc39d82 Mon Sep 17 00:00:00 2001 From: Ian Hou <45278651+iankhou@users.noreply.github.com> Date: Tue, 17 Feb 2026 10:41:53 -0500 Subject: [PATCH 7/7] fix async operations not completed before test teardown in toolkit watch integ test --- .../toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts index 9acd2e2b2..4f78a12b1 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/toolkit-lib-integ-tests/toolkit-watch-glob.integtest.ts @@ -77,8 +77,9 @@ integTest( fixture.log('✓ Toolkit watch successfully initialized and detected files'); } finally { - // Clean up + // Clean up - dispose and wait for async operations to settle await watcher.dispose(); + await sleep(1000); // Allow async operations to complete if (fs.existsSync(testFile)) { fs.unlinkSync(testFile); } @@ -137,6 +138,7 @@ integTest( fixture.log(` Config: ${configMsg.substring(0, 200)}...`); } finally { await watcher.dispose(); + await sleep(1000); // Allow async operations to complete } }), );