chore(runner): remove watch mode (#17682)
This commit is contained in:
parent
a49ea7357a
commit
43ccd7bc96
|
|
@ -168,7 +168,6 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
|
||||||
testFileFilters,
|
testFileFilters,
|
||||||
projectFilter: opts.project || undefined,
|
projectFilter: opts.project || undefined,
|
||||||
projectGroup: opts.group,
|
projectGroup: opts.group,
|
||||||
watchMode: !!process.env.PW_TEST_WATCH,
|
|
||||||
passWithNoTests: opts.passWithNoTests,
|
passWithNoTests: opts.passWithNoTests,
|
||||||
});
|
});
|
||||||
await stopProfiling(undefined);
|
await stopProfiling(undefined);
|
||||||
|
|
|
||||||
|
|
@ -748,7 +748,6 @@ export const baseFullConfig: FullConfigInternal = {
|
||||||
version: require('../package.json').version,
|
version: require('../package.json').version,
|
||||||
workers: 0,
|
workers: 0,
|
||||||
webServer: null,
|
webServer: null,
|
||||||
_watchMode: false,
|
|
||||||
_webServers: [],
|
_webServers: [],
|
||||||
_globalOutputDir: path.resolve(process.cwd()),
|
_globalOutputDir: path.resolve(process.cwd()),
|
||||||
_configDir: '',
|
_configDir: '',
|
||||||
|
|
|
||||||
|
|
@ -123,10 +123,7 @@ export class BaseReporter implements ReporterInternal {
|
||||||
protected generateStartingMessage() {
|
protected generateStartingMessage() {
|
||||||
const jobs = Math.min(this.config.workers, this.config._maxConcurrentTestGroups);
|
const jobs = Math.min(this.config.workers, this.config._maxConcurrentTestGroups);
|
||||||
const shardDetails = this.config.shard ? `, shard ${this.config.shard.current} of ${this.config.shard.total}` : '';
|
const shardDetails = this.config.shard ? `, shard ${this.config.shard.current} of ${this.config.shard.total}` : '';
|
||||||
if (this.config._watchMode)
|
return `\nRunning ${this.totalTestCount} test${this.totalTestCount !== 1 ? 's' : ''} using ${jobs} worker${jobs !== 1 ? 's' : ''}${shardDetails}`;
|
||||||
return `\nRunning tests in the --watch mode`;
|
|
||||||
else
|
|
||||||
return `\nRunning ${this.totalTestCount} test${this.totalTestCount !== 1 ? 's' : ''} using ${jobs} worker${jobs !== 1 ? 's' : ''}${shardDetails}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getSlowTests(): [string, number][] {
|
protected getSlowTests(): [string, number][] {
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@ type RunOptions = {
|
||||||
testFileFilters?: TestFileFilter[];
|
testFileFilters?: TestFileFilter[];
|
||||||
projectFilter?: string[];
|
projectFilter?: string[];
|
||||||
projectGroup?: string;
|
projectGroup?: string;
|
||||||
watchMode?: boolean;
|
|
||||||
passWithNoTests?: boolean;
|
passWithNoTests?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -91,17 +90,10 @@ export type ConfigCLIOverrides = {
|
||||||
use?: any;
|
use?: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type WatchProgress = {
|
|
||||||
canceled: boolean;
|
|
||||||
dispatcher: Dispatcher | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class Runner {
|
export class Runner {
|
||||||
private _loader: Loader;
|
private _loader: Loader;
|
||||||
private _reporter!: ReporterInternal;
|
private _reporter!: ReporterInternal;
|
||||||
private _plugins: TestRunnerPlugin[] = [];
|
private _plugins: TestRunnerPlugin[] = [];
|
||||||
private _watchRepeatEachIndex = 0;
|
|
||||||
private _watchJobsQueue = Promise.resolve();
|
|
||||||
|
|
||||||
constructor(configCLIOverrides?: ConfigCLIOverrides) {
|
constructor(configCLIOverrides?: ConfigCLIOverrides) {
|
||||||
this._loader = new Loader(configCLIOverrides);
|
this._loader = new Loader(configCLIOverrides);
|
||||||
|
|
@ -194,12 +186,6 @@ export class Runner {
|
||||||
async runAllTests(options: RunOptions = {}): Promise<FullResult> {
|
async runAllTests(options: RunOptions = {}): Promise<FullResult> {
|
||||||
this._reporter = await this._createReporter(!!options.listOnly);
|
this._reporter = await this._createReporter(!!options.listOnly);
|
||||||
const config = this._loader.fullConfig();
|
const config = this._loader.fullConfig();
|
||||||
if (options.watchMode) {
|
|
||||||
config._watchMode = true;
|
|
||||||
config._workerIsolation = 'isolate-projects';
|
|
||||||
return await this._watch(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await raceAgainstTimeout(() => this._run(options), config.globalTimeout);
|
const result = await raceAgainstTimeout(() => this._run(options), config.globalTimeout);
|
||||||
let fullResult: FullResult;
|
let fullResult: FullResult;
|
||||||
if (result.timedOut) {
|
if (result.timedOut) {
|
||||||
|
|
@ -550,124 +536,6 @@ export class Runner {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _watch(options: RunOptions): Promise<FullResult> {
|
|
||||||
const config = this._loader.fullConfig();
|
|
||||||
|
|
||||||
// 1. Create empty suite.
|
|
||||||
const rootSuite = new Suite('', 'root');
|
|
||||||
|
|
||||||
// 2. Report begin.
|
|
||||||
this._reporter.onBegin?.(config, rootSuite);
|
|
||||||
|
|
||||||
// 3. Remove output directores.
|
|
||||||
if (!this._removeOutputDirs(options))
|
|
||||||
return { status: 'failed' };
|
|
||||||
|
|
||||||
// 4. Run Global setup.
|
|
||||||
const result: FullResult = { status: 'passed' };
|
|
||||||
const globalTearDown = await this._performGlobalSetup(config, rootSuite, result);
|
|
||||||
if (result.status !== 'passed')
|
|
||||||
return result;
|
|
||||||
|
|
||||||
const progress: WatchProgress = { canceled: false, dispatcher: undefined };
|
|
||||||
|
|
||||||
const runAndWatch = async () => {
|
|
||||||
// 5. Collect all files.
|
|
||||||
const filesByProject = await this._collectFiles(this._runPhaseFromOptions(options));
|
|
||||||
|
|
||||||
const allTestFiles = new Set<string>();
|
|
||||||
for (const files of filesByProject.values())
|
|
||||||
files.forEach(file => allTestFiles.add(file));
|
|
||||||
|
|
||||||
// 6. Trigger 'all files changed'.
|
|
||||||
await this._runAndReportError(async () => {
|
|
||||||
await this._runModifiedTestFilesForWatch(progress, options, allTestFiles);
|
|
||||||
}, result);
|
|
||||||
|
|
||||||
// 7. Start watching the filesystem for modifications.
|
|
||||||
await this._watchTestFiles(progress, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const sigintWatcher = new SigIntWatcher();
|
|
||||||
await Promise.race([runAndWatch(), sigintWatcher.promise()]);
|
|
||||||
if (!sigintWatcher.hadSignal())
|
|
||||||
sigintWatcher.disarm();
|
|
||||||
progress.canceled = true;
|
|
||||||
await progress.dispatcher?.stop();
|
|
||||||
} finally {
|
|
||||||
await globalTearDown?.();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _runModifiedTestFilesForWatch(progress: WatchProgress, options: RunOptions, testFiles: Set<string>): Promise<void> {
|
|
||||||
if (progress.canceled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const fileMatcher = createFileMatcher([...testFiles]);
|
|
||||||
const phase = this._runPhaseFromOptions(options);
|
|
||||||
phase.forEach(p => p.testFileMatcher = fileMatcher);
|
|
||||||
const filesByProject = await this._collectFiles(phase);
|
|
||||||
|
|
||||||
if (progress.canceled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const testGroups: TestGroup[] = [];
|
|
||||||
const repeatEachIndex = ++this._watchRepeatEachIndex;
|
|
||||||
for (const [project, files] of filesByProject) {
|
|
||||||
for (const file of files) {
|
|
||||||
const group: TestGroup = {
|
|
||||||
workerHash: `run${project.id}-repeat${repeatEachIndex}`,
|
|
||||||
requireFile: file,
|
|
||||||
repeatEachIndex,
|
|
||||||
projectId: project.id,
|
|
||||||
tests: [],
|
|
||||||
watchMode: true,
|
|
||||||
};
|
|
||||||
testGroups.push(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const dispatcher = new Dispatcher(this._loader, testGroups, this._reporter);
|
|
||||||
progress.dispatcher = dispatcher;
|
|
||||||
await dispatcher.run();
|
|
||||||
await dispatcher.stop();
|
|
||||||
progress.dispatcher = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _watchTestFiles(progress: WatchProgress, options: RunOptions): Promise<void> {
|
|
||||||
const folders = new Set<string>();
|
|
||||||
const config = this._loader.fullConfig();
|
|
||||||
for (const project of config.projects) {
|
|
||||||
if (options.projectFilter && !options.projectFilter.includes(project.name))
|
|
||||||
continue;
|
|
||||||
folders.add(project.testDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const folder of folders) {
|
|
||||||
const changedFiles = new Set<string>();
|
|
||||||
let throttleTimer: NodeJS.Timeout | undefined;
|
|
||||||
fs.watch(folder, (event, filename) => {
|
|
||||||
if (event !== 'change')
|
|
||||||
return;
|
|
||||||
|
|
||||||
const fullName = path.join(folder, filename);
|
|
||||||
changedFiles.add(fullName);
|
|
||||||
if (throttleTimer)
|
|
||||||
clearTimeout(throttleTimer);
|
|
||||||
|
|
||||||
throttleTimer = setTimeout(() => {
|
|
||||||
const copy = new Set(changedFiles);
|
|
||||||
changedFiles.clear();
|
|
||||||
this._watchJobsQueue = this._watchJobsQueue.then(() => this._runModifiedTestFilesForWatch(progress, options, copy));
|
|
||||||
}, 250);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await new Promise(() => {});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _removeOutputDirs(options: RunOptions): Promise<boolean> {
|
private async _removeOutputDirs(options: RunOptions): Promise<boolean> {
|
||||||
const config = this._loader.fullConfig();
|
const config = this._loader.fullConfig();
|
||||||
const outputDirs = new Set<string>();
|
const outputDirs = new Set<string>();
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ export interface FullConfigInternal extends FullConfigPublic {
|
||||||
_globalOutputDir: string;
|
_globalOutputDir: string;
|
||||||
_configDir: string;
|
_configDir: string;
|
||||||
_maxConcurrentTestGroups: number;
|
_maxConcurrentTestGroups: number;
|
||||||
_watchMode: boolean;
|
|
||||||
_ignoreSnapshots: boolean;
|
_ignoreSnapshots: boolean;
|
||||||
_workerIsolation: WorkerIsolation;
|
_workerIsolation: WorkerIsolation;
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue