chore: prepare to deps (#20513)

This commit is contained in:
Pavel Feldman 2023-01-30 14:34:48 -08:00 committed by GitHub
parent 99353038f0
commit 0dd090aeab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 54 deletions

View File

@ -40,7 +40,7 @@ export class Dispatcher {
private _queue: TestGroup[] = [];
private _queuedOrRunningHashCount = new Map<string, number>();
private _finished = new ManualPromise<void>();
private _isStopped = false;
private _isStopped = true;
private _testById = new Map<string, TestData>();
private _config: FullConfigInternal;
@ -48,15 +48,9 @@ export class Dispatcher {
private _hasWorkerErrors = false;
private _failureCount = 0;
constructor(config: FullConfigInternal, testGroups: TestGroup[], reporter: Reporter) {
constructor(config: FullConfigInternal, reporter: Reporter) {
this._config = config;
this._reporter = reporter;
this._queue = testGroups;
for (const group of testGroups) {
this._queuedOrRunningHashCount.set(group.workerHash, 1 + (this._queuedOrRunningHashCount.get(group.workerHash) || 0));
for (const test of group.tests)
this._testById.set(test.id, { test, resultByWorkerIndex: new Map() });
}
}
private _processFullySkippedJobs() {
@ -167,7 +161,14 @@ export class Dispatcher {
return workersWithSameHash > this._queuedOrRunningHashCount.get(worker.hash())!;
}
async run() {
async run(testGroups: TestGroup[]) {
this._queue = testGroups;
for (const group of testGroups) {
this._queuedOrRunningHashCount.set(group.workerHash, 1 + (this._queuedOrRunningHashCount.get(group.workerHash) || 0));
for (const test of group.tests)
this._testById.set(test.id, { test, resultByWorkerIndex: new Map() });
}
this._isStopped = false;
this._workerSlots = [];
// 1. Allocate workers.
for (let i = 0; i < this._config.workers; i++)

View File

@ -22,11 +22,11 @@ import type { Multiplexer } from '../reporters/multiplexer';
import { createRootSuite, filterOnly, filterSuite } from '../common/suiteUtils';
import type { Suite, TestCase } from '../common/test';
import { loadTestFilesInProcess } from '../common/testLoader';
import type { FullConfigInternal } from '../common/types';
import type { FullConfigInternal, FullProjectInternal } from '../common/types';
import { errorWithFile } from '../util';
import type { Matcher, TestFileFilter } from '../util';
import { createFileMatcher } from '../util';
import { collectFilesForProjects, filterProjects } from './projectUtils';
import { collectFilesForProject, filterProjects } from './projectUtils';
import { requireOrImport } from '../common/transform';
import { serializeConfig } from '../common/ipc';
@ -40,10 +40,13 @@ type LoadOptions = {
export async function loadAllTests(config: FullConfigInternal, reporter: Multiplexer, options: LoadOptions, errors: TestError[]): Promise<Suite> {
const projects = filterProjects(config.projects, options.projectFilter);
const filesByProject = await collectFilesForProjects(projects, options.testFileFilters);
const filesByProject = new Map<FullProjectInternal, string[]>();
const allTestFiles = new Set<string>();
for (const files of filesByProject.values())
for (const project of projects) {
const files = await collectFilesForProject(project, options.testFileFilters);
filesByProject.set(project, files);
files.forEach(file => allTestFiles.add(file));
}
// Load all tests.
const preprocessRoot = await loadTests(config, reporter, allTestFiles, errors);

View File

@ -50,29 +50,22 @@ export function filterProjects(projects: FullProjectInternal[], projectNames?: s
return result;
}
export async function collectFilesForProjects(projects: FullProjectInternal[], commandLineFileFilters: TestFileFilter[]): Promise<Map<FullProjectInternal, string[]>> {
export async function collectFilesForProject(project: FullProjectInternal, commandLineFileFilters: TestFileFilter[]): Promise<string[]> {
const extensions = ['.js', '.ts', '.mjs', '.tsx', '.jsx'];
const testFileExtension = (file: string) => extensions.includes(path.extname(file));
const filesByProject = new Map<FullProjectInternal, string[]>();
const fileToProjectName = new Map<string, string>();
const commandLineFileMatcher = commandLineFileFilters.length ? createFileMatcherFromFilters(commandLineFileFilters) : () => true;
for (const project of projects) {
const allFiles = await collectFiles(project.testDir, project._respectGitIgnore);
const testMatch = createFileMatcher(project.testMatch);
const testIgnore = createFileMatcher(project.testIgnore);
const testFiles = allFiles.filter(file => {
if (!testFileExtension(file))
return false;
const isTest = !testIgnore(file) && testMatch(file) && commandLineFileMatcher(file);
if (!isTest)
return false;
fileToProjectName.set(file, project.name);
return true;
});
filesByProject.set(project, testFiles);
}
return filesByProject;
const allFiles = await collectFiles(project.testDir, project._respectGitIgnore);
const testMatch = createFileMatcher(project.testMatch);
const testIgnore = createFileMatcher(project.testIgnore);
const testFiles = allFiles.filter(file => {
if (!testFileExtension(file))
return false;
const isTest = !testIgnore(file) && testMatch(file) && commandLineFileMatcher(file);
if (!isTest)
return false;
return true;
});
return testFiles;
}
async function collectFiles(testDir: string, respectGitIgnore: boolean): Promise<string[]> {

View File

@ -19,12 +19,13 @@ import { monotonicTime } from 'playwright-core/lib/utils';
import type { FullResult } from '../../types/testReporter';
import { dockerPlugin } from '../plugins/dockerPlugin';
import { webServerPluginsForConfig } from '../plugins/webServerPlugin';
import { collectFilesForProjects, filterProjects } from './projectUtils';
import { collectFilesForProject, filterProjects } from './projectUtils';
import { createReporter } from './reporters';
import { createTaskRunner, createTaskRunnerForList } from './tasks';
import type { TaskRunnerState } from './tasks';
import type { FullConfigInternal } from '../common/types';
import type { Matcher, TestFileFilter } from '../util';
import { colors } from 'playwright-core/lib/utilsBundle';
export type RunOptions = {
listOnly: boolean;
@ -43,14 +44,13 @@ export class Runner {
async listTestFiles(projectNames: string[] | undefined): Promise<any> {
const projects = filterProjects(this._config.projects, projectNames);
const filesByProject = await collectFilesForProjects(projects, []);
const report: any = {
projects: []
};
for (const [project, files] of filesByProject) {
for (const project of projects) {
report.projects.push({
...sanitizeConfigForJSON(project, new Set()),
files
files: await collectFilesForProject(project, [])
});
}
return report;
@ -78,6 +78,16 @@ export class Runner {
};
reporter.onConfigure(config);
if (!options.listOnly && config._ignoreSnapshots) {
reporter.onStdOut(colors.dim([
'NOTE: running with "ignoreSnapshots" option. All of the following asserts are silently ignored:',
'- expect().toMatchSnapshot()',
'- expect().toHaveScreenshot()',
'',
].join('\n')));
}
const taskStatus = await taskRunner.run(context, deadline);
let status: FullResult['status'] = 'passed';
if (context.dispatcher?.hasWorkerErrors() || context.rootSuite?.allTests().some(test => !test.ok()))

View File

@ -17,7 +17,7 @@
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import { colors, rimraf } from 'playwright-core/lib/utilsBundle';
import { rimraf } from 'playwright-core/lib/utilsBundle';
import { Dispatcher } from './dispatcher';
import type { TestRunnerPlugin, TestRunnerPluginRegistration } from '../plugins';
import type { Multiplexer } from '../reporters/multiplexer';
@ -72,7 +72,7 @@ export function createTaskRunner(config: FullConfigInternal, reporter: Multiplex
});
taskRunner.addTask('setup workers', createSetupWorkersTask());
taskRunner.addTask('test suite', async ({ dispatcher }) => dispatcher!.run());
taskRunner.addTask('test suite', async ({ dispatcher, testGroups }) => dispatcher!.run(testGroups));
return taskRunner;
}
@ -87,7 +87,7 @@ export function createTaskRunnerForList(config: FullConfigInternal, reporter: Mu
return taskRunner;
}
export function createPluginSetupTask(pluginRegistration: TestRunnerPluginRegistration): Task<TaskRunnerState> {
function createPluginSetupTask(pluginRegistration: TestRunnerPluginRegistration): Task<TaskRunnerState> {
return async ({ config, reporter, plugins }) => {
let plugin: TestRunnerPlugin;
if (typeof pluginRegistration === 'function')
@ -100,7 +100,7 @@ export function createPluginSetupTask(pluginRegistration: TestRunnerPluginRegist
};
}
export function createGlobalSetupTask(): Task<TaskRunnerState> {
function createGlobalSetupTask(): Task<TaskRunnerState> {
return async ({ config }) => {
const setupHook = config.globalSetup ? await loadGlobalHook(config, config.globalSetup) : undefined;
const teardownHook = config.globalTeardown ? await loadGlobalHook(config, config.globalTeardown) : undefined;
@ -113,19 +113,10 @@ export function createGlobalSetupTask(): Task<TaskRunnerState> {
};
}
export function createSetupWorkersTask(): Task<TaskRunnerState> {
function createSetupWorkersTask(): Task<TaskRunnerState> {
return async params => {
const { config, testGroups, reporter } = params;
if (config._ignoreSnapshots) {
reporter.onStdOut(colors.dim([
'NOTE: running with "ignoreSnapshots" option. All of the following asserts are silently ignored:',
'- expect().toMatchSnapshot()',
'- expect().toHaveScreenshot()',
'',
].join('\n')));
}
const dispatcher = new Dispatcher(config, testGroups!, reporter);
const { config, reporter } = params;
const dispatcher = new Dispatcher(config, reporter);
params.dispatcher = dispatcher;
return async () => {
await dispatcher.stop();
@ -133,7 +124,7 @@ export function createSetupWorkersTask(): Task<TaskRunnerState> {
};
}
export function createRemoveOutputDirsTask(): Task<TaskRunnerState> {
function createRemoveOutputDirsTask(): Task<TaskRunnerState> {
return async ({ config, options }) => {
const outputDirs = new Set<string>();
for (const p of config.projects) {