diff --git a/packages/playwright/src/runner/uiMode.ts b/packages/playwright/src/runner/uiMode.ts index aff2baaddb..b9c7c5847f 100644 --- a/packages/playwright/src/runner/uiMode.ts +++ b/packages/playwright/src/runner/uiMode.ts @@ -179,9 +179,12 @@ class UIMode { await reporter.onExit(); const projectDirs = new Set(); - for (const p of this._config.projects) + const projectOutputs = new Set(); + for (const p of this._config.projects) { projectDirs.add(p.project.testDir); - this._globalWatcher.update([...projectDirs], false); + projectOutputs.add(p.project.outputDir); + } + this._globalWatcher.update([...projectDirs], [...projectOutputs], false); } private async _runTests(testIds: string[], projects: string[]) { @@ -217,7 +220,7 @@ class UIMode { files.add(fileName); dependenciesForTestFile(fileName).forEach(file => files.add(file)); } - this._testWatcher.update([...files], true); + this._testWatcher.update([...files], [], true); } private async _stopTests() { @@ -259,6 +262,7 @@ type FSEvent = { event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', fi class Watcher { private _onChange: (events: FSEvent[]) => void; private _watchedFiles: string[] = []; + private _ignoredFolders: string[] = []; private _collector: FSEvent[] = []; private _fsWatcher: FSWatcher | undefined; private _throttleTimer: NodeJS.Timeout | undefined; @@ -269,14 +273,15 @@ class Watcher { this._onChange = onChange; } - update(watchedFiles: string[], reportPending: boolean) { - if (JSON.stringify(this._watchedFiles) === JSON.stringify(watchedFiles)) + update(watchedFiles: string[], ignoredFolders: string[], reportPending: boolean) { + if (JSON.stringify([this._watchedFiles, this._ignoredFolders]) === JSON.stringify(watchedFiles, ignoredFolders)) return; if (reportPending) this._reportEventsIfAny(); this._watchedFiles = watchedFiles; + this._ignoredFolders = ignoredFolders; void this._fsWatcher?.close(); this._fsWatcher = undefined; this._collector.length = 0; @@ -286,7 +291,7 @@ class Watcher { if (!this._watchedFiles.length) return; - this._fsWatcher = chokidar.watch(watchedFiles, { ignoreInitial: true }).on('all', async (event, file) => { + this._fsWatcher = chokidar.watch(watchedFiles, { ignoreInitial: true, ignored: this._ignoredFolders }).on('all', async (event, file) => { if (this._throttleTimer) clearTimeout(this._throttleTimer); if (this._mode === 'flat' && event !== 'add' && event !== 'change') diff --git a/packages/trace-viewer/src/ui/uiModeView.tsx b/packages/trace-viewer/src/ui/uiModeView.tsx index 9c04722b83..49d4e03feb 100644 --- a/packages/trace-viewer/src/ui/uiModeView.tsx +++ b/packages/trace-viewer/src/ui/uiModeView.tsx @@ -103,7 +103,11 @@ export const UIModeView: React.FC<{}> = ({ inputRef.current?.focus(); setIsLoading(true); connect({ onEvent: dispatchEvent, onClose: () => setIsDisconnected(true) }).then(send => { - sendMessage = send; + sendMessage = async (method, params) => { + const logForTest = (window as any).__logForTest; + logForTest?.({ method, params }); + await send(method, params); + }; reloadTests(); }); }, [reloadTests]); diff --git a/tests/playwright-test/ui-mode-test-watch.spec.ts b/tests/playwright-test/ui-mode-test-watch.spec.ts index 4dae1f3355..dd92a7bc9e 100644 --- a/tests/playwright-test/ui-mode-test-watch.spec.ts +++ b/tests/playwright-test/ui-mode-test-watch.spec.ts @@ -262,3 +262,30 @@ test('should queue watches', async ({ runUITest, writeFiles, createLatch }) => { await expect(page.getByTestId('status-line')).toHaveText('3/3 passed (100%)'); }); + +test('should not watch output', async ({ runUITest }) => { + const { page } = await runUITest({ + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('passes', ({}, testInfo) => { + require('fs').writeFileSync(testInfo.outputPath('output.txt'), 'DATA'); + }); + `, + }); + + await expect.poll(dumpTestTree(page)).toBe(` + ▼ ◯ a.test.ts + ◯ passes + `); + + const commands: string[] = []; + await page.exposeBinding('__logForTest', (source, arg) => { + commands.push(arg.method); + }); + + await page.getByTitle('Run all').click(); + + await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + expect(commands).toContain('run'); + expect(commands).not.toContain('list'); +});