remove the watch mode concept, combine both watchers
This commit is contained in:
parent
c7b8a7b766
commit
52b0811c55
|
|
@ -61,7 +61,7 @@ export async function runDevServer(config: FullConfigInternal): Promise<() => Pr
|
||||||
projectOutputs.add(p.project.outputDir);
|
projectOutputs.add(p.project.outputDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
const globalWatcher = new Watcher('deep', async () => {
|
const globalWatcher = new Watcher(async () => {
|
||||||
const registry: ComponentRegistry = new Map();
|
const registry: ComponentRegistry = new Map();
|
||||||
await populateComponentsFromTests(registry);
|
await populateComponentsFromTests(registry);
|
||||||
// compare componentRegistry to registry key sets.
|
// compare componentRegistry to registry key sets.
|
||||||
|
|
|
||||||
|
|
@ -21,26 +21,24 @@ export type FSEvent = { event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkD
|
||||||
|
|
||||||
export class Watcher {
|
export class Watcher {
|
||||||
private _onChange: (events: FSEvent[]) => void;
|
private _onChange: (events: FSEvent[]) => void;
|
||||||
private _watchedFiles: string[] = [];
|
private _watchedPaths: string[] = [];
|
||||||
private _ignoredFolders: string[] = [];
|
private _ignoredFolders: string[] = [];
|
||||||
private _collector: FSEvent[] = [];
|
private _collector: FSEvent[] = [];
|
||||||
private _fsWatcher: FSWatcher | undefined;
|
private _fsWatcher: FSWatcher | undefined;
|
||||||
private _throttleTimer: NodeJS.Timeout | undefined;
|
private _throttleTimer: NodeJS.Timeout | undefined;
|
||||||
private _mode: 'flat' | 'deep';
|
|
||||||
|
|
||||||
constructor(mode: 'flat' | 'deep', onChange: (events: FSEvent[]) => void) {
|
constructor(onChange: (events: FSEvent[]) => void) {
|
||||||
this._mode = mode;
|
|
||||||
this._onChange = onChange;
|
this._onChange = onChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
update(watchedFiles: string[], ignoredFolders: string[], reportPending: boolean) {
|
update(watchedPaths: string[], ignoredFolders: string[], reportPending: boolean) {
|
||||||
if (JSON.stringify([this._watchedFiles, this._ignoredFolders]) === JSON.stringify(watchedFiles, ignoredFolders))
|
if (JSON.stringify([this._watchedPaths, this._ignoredFolders]) === JSON.stringify(watchedPaths, ignoredFolders))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (reportPending)
|
if (reportPending)
|
||||||
this._reportEventsIfAny();
|
this._reportEventsIfAny();
|
||||||
|
|
||||||
this._watchedFiles = watchedFiles;
|
this._watchedPaths = watchedPaths;
|
||||||
this._ignoredFolders = ignoredFolders;
|
this._ignoredFolders = ignoredFolders;
|
||||||
void this._fsWatcher?.close();
|
void this._fsWatcher?.close();
|
||||||
this._fsWatcher = undefined;
|
this._fsWatcher = undefined;
|
||||||
|
|
@ -48,17 +46,13 @@ export class Watcher {
|
||||||
clearTimeout(this._throttleTimer);
|
clearTimeout(this._throttleTimer);
|
||||||
this._throttleTimer = undefined;
|
this._throttleTimer = undefined;
|
||||||
|
|
||||||
if (!this._watchedFiles.length)
|
if (!this._watchedPaths.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ignored = [...this._ignoredFolders, '**/node_modules/**'];
|
const ignored = [...this._ignoredFolders, '**/node_modules/**'];
|
||||||
this._fsWatcher = chokidar.watch(watchedFiles, { ignoreInitial: true, ignored }).on('all', async (event, file) => {
|
this._fsWatcher = chokidar.watch(watchedPaths, { ignoreInitial: true, ignored }).on('all', async (event, file) => {
|
||||||
if (this._throttleTimer)
|
if (this._throttleTimer)
|
||||||
clearTimeout(this._throttleTimer);
|
clearTimeout(this._throttleTimer);
|
||||||
if (this._mode === 'flat' && event !== 'add' && event !== 'change')
|
|
||||||
return;
|
|
||||||
if (this._mode === 'deep' && event !== 'add' && event !== 'change' && event !== 'unlink' && event !== 'addDir' && event !== 'unlinkDir')
|
|
||||||
return;
|
|
||||||
this._collector.push({ event, file });
|
this._collector.push({ event, file });
|
||||||
this._throttleTimer = setTimeout(() => this._reportEventsIfAny(), 250);
|
this._throttleTimer = setTimeout(() => this._reportEventsIfAny(), 250);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import { TestRun, createTaskRunnerForList, createTaskRunnerForTestServer, create
|
||||||
import { open } from 'playwright-core/lib/utilsBundle';
|
import { open } from 'playwright-core/lib/utilsBundle';
|
||||||
import ListReporter from '../reporters/list';
|
import ListReporter from '../reporters/list';
|
||||||
import { SigIntWatcher } from './sigIntWatcher';
|
import { SigIntWatcher } from './sigIntWatcher';
|
||||||
import { type FSEvent, Watcher } from '../fsWatcher';
|
import { Watcher } from '../fsWatcher';
|
||||||
import type { ReportEntry, TestServerInterface, TestServerInterfaceEventEmitters } from '../isomorphic/testServerInterface';
|
import type { ReportEntry, TestServerInterface, TestServerInterfaceEventEmitters } from '../isomorphic/testServerInterface';
|
||||||
import { Runner } from './runner';
|
import { Runner } from './runner';
|
||||||
import type { ConfigCLIOverrides } from '../common/ipc';
|
import type { ConfigCLIOverrides } from '../common/ipc';
|
||||||
|
|
@ -64,8 +64,12 @@ class TestServer {
|
||||||
|
|
||||||
class TestServerDispatcher implements TestServerInterface {
|
class TestServerDispatcher implements TestServerInterface {
|
||||||
private _configLocation: ConfigLocation;
|
private _configLocation: ConfigLocation;
|
||||||
private _globalWatcher: Watcher;
|
|
||||||
private _testWatcher: Watcher;
|
private _watcher: Watcher;
|
||||||
|
private _watchedProjectDirs = new Set<string>();
|
||||||
|
private _ignoredProjectOutputs = new Set<string>();
|
||||||
|
private _watchedTestDependencies = new Set<string>();
|
||||||
|
|
||||||
private _testRun: { run: Promise<reporterTypes.FullResult['status']>, stop: ManualPromise<void> } | undefined;
|
private _testRun: { run: Promise<reporterTypes.FullResult['status']>, stop: ManualPromise<void> } | undefined;
|
||||||
readonly transport: Transport;
|
readonly transport: Transport;
|
||||||
private _queue = Promise.resolve();
|
private _queue = Promise.resolve();
|
||||||
|
|
@ -86,17 +90,14 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
gracefullyProcessExitDoNotHang(0);
|
gracefullyProcessExitDoNotHang(0);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
this._globalWatcher = new Watcher('deep', events => this._checkForChangedTestFiles(events));
|
this._watcher = new Watcher(events => {
|
||||||
this._testWatcher = new Watcher('flat', events => this._checkForChangedTestFiles(events));
|
const collector = new Set<string>();
|
||||||
|
events.forEach(f => collectAffectedTestFiles(f.file, collector));
|
||||||
|
this._dispatchEvent('testFilesChanged', { testFiles: [...collector] });
|
||||||
|
});
|
||||||
this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params);
|
this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _checkForChangedTestFiles(events: FSEvent[]) {
|
|
||||||
const collector = new Set<string>();
|
|
||||||
events.forEach(f => collectAffectedTestFiles(f.file, collector));
|
|
||||||
this._dispatchEvent('testFilesChanged', { testFiles: [...collector] });
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _wireReporter(messageSink: (message: any) => void) {
|
private async _wireReporter(messageSink: (message: any) => void) {
|
||||||
return await createReporterForTestServer(this._serializer, messageSink);
|
return await createReporterForTestServer(this._serializer, messageSink);
|
||||||
}
|
}
|
||||||
|
|
@ -281,24 +282,28 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
await taskRunner.reporter.onEnd({ status });
|
await taskRunner.reporter.onEnd({ status });
|
||||||
await taskRunner.reporter.onExit();
|
await taskRunner.reporter.onExit();
|
||||||
|
|
||||||
const projectDirs = new Set<string>();
|
this._watchedProjectDirs = new Set();
|
||||||
const projectOutputs = new Set<string>();
|
this._ignoredProjectOutputs = new Set();
|
||||||
for (const p of config.projects) {
|
for (const p of config.projects) {
|
||||||
projectDirs.add(p.project.testDir);
|
this._watchedProjectDirs.add(p.project.testDir);
|
||||||
projectOutputs.add(p.project.outputDir);
|
this._ignoredProjectOutputs.add(p.project.outputDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await resolveCtDirs(config);
|
const result = await resolveCtDirs(config);
|
||||||
if (result) {
|
if (result) {
|
||||||
projectDirs.add(result.templateDir);
|
this._watchedProjectDirs.add(result.templateDir);
|
||||||
projectOutputs.add(result.outDir);
|
this._ignoredProjectOutputs.add(result.outDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._watchTestDirs)
|
if (this._watchTestDirs)
|
||||||
this._globalWatcher.update([...projectDirs], [...projectOutputs], false);
|
this.updateWatcher(false);
|
||||||
return { report, status };
|
return { report, status };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateWatcher(reportPending: boolean) {
|
||||||
|
this._watcher.update([...this._watchedProjectDirs, ...this._watchedTestDependencies], [...this._ignoredProjectOutputs], reportPending);
|
||||||
|
}
|
||||||
|
|
||||||
async runTests(params: Parameters<TestServerInterface['runTests']>[0]): ReturnType<TestServerInterface['runTests']> {
|
async runTests(params: Parameters<TestServerInterface['runTests']>[0]): ReturnType<TestServerInterface['runTests']> {
|
||||||
let result: Awaited<ReturnType<TestServerInterface['runTests']>> = { status: 'passed' };
|
let result: Awaited<ReturnType<TestServerInterface['runTests']>> = { status: 'passed' };
|
||||||
this._queue = this._queue.then(async () => {
|
this._queue = this._queue.then(async () => {
|
||||||
|
|
@ -366,12 +371,12 @@ class TestServerDispatcher implements TestServerInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
async watch(params: { fileNames: string[]; }) {
|
async watch(params: { fileNames: string[]; }) {
|
||||||
const files = new Set<string>();
|
this._watchedTestDependencies = new Set();
|
||||||
for (const fileName of params.fileNames) {
|
for (const fileName of params.fileNames) {
|
||||||
files.add(fileName);
|
this._watchedTestDependencies.add(fileName);
|
||||||
dependenciesForTestFile(fileName).forEach(file => files.add(file));
|
dependenciesForTestFile(fileName).forEach(file => this._watchedTestDependencies.add(file));
|
||||||
}
|
}
|
||||||
this._testWatcher.update([...files], [], true);
|
this.updateWatcher(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findRelatedTestFiles(params: Parameters<TestServerInterface['findRelatedTestFiles']>[0]): ReturnType<TestServerInterface['findRelatedTestFiles']> {
|
async findRelatedTestFiles(params: Parameters<TestServerInterface['findRelatedTestFiles']>[0]): ReturnType<TestServerInterface['findRelatedTestFiles']> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue