chore(test runner): preparation for TestRunner api (#11209)

This commit is contained in:
Dmitry Gozman 2022-01-05 15:49:01 -08:00 committed by GitHub
parent 3839917eb6
commit ccc61e31ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 15 deletions

View File

@ -121,7 +121,7 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
process.env.PWDEBUG = '1'; process.env.PWDEBUG = '1';
} }
const runner = new Runner(overrides, defaultConfig); const runner = new Runner(overrides, { defaultConfig, printResolvedConfig: process.stdout.isTTY });
// When no --config option is passed, let's look for the config file in the current directory. // When no --config option is passed, let's look for the config file in the current directory.
const configFile = opts.config ? path.resolve(process.cwd(), opts.config) : process.cwd(); const configFile = opts.config ? path.resolve(process.cwd(), opts.config) : process.cwd();
@ -129,7 +129,7 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
if (('projects' in config) && opts.browser) if (('projects' in config) && opts.browser)
throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`); throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`);
const filePatternFilters: FilePatternFilter[] = args.map(arg => { const filePatternFilter: FilePatternFilter[] = args.map(arg => {
const match = /^(.*):(\d+)$/.exec(arg); const match = /^(.*):(\d+)$/.exec(arg);
return { return {
re: forceRegExp(match ? match[1] : arg), re: forceRegExp(match ? match[1] : arg),
@ -139,15 +139,13 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
if (process.env.PLAYWRIGHT_DOCKER) if (process.env.PLAYWRIGHT_DOCKER)
runner.addInternalGlobalSetup(launchDockerContainer); runner.addInternalGlobalSetup(launchDockerContainer);
const result = await runner.run(!!opts.list, filePatternFilters, opts.project || undefined); const result = await runner.runAllTests({
listOnly: !!opts.list,
filePatternFilter,
projectFilter: opts.project || undefined,
});
await stopProfiling(undefined); await stopProfiling(undefined);
// Calling process.exit() might truncate large stdout/stderr output.
// See https://github.com/nodejs/node/issues/6456.
// See https://github.com/nodejs/node/issues/12921
await new Promise<void>(resolve => process.stdout.write('', () => resolve()));
await new Promise<void>(resolve => process.stderr.write('', () => resolve()));
if (result.status === 'interrupted') if (result.status === 'interrupted')
process.exit(130); process.exit(130);
process.exit(result.status === 'passed' ? 0 : 1); process.exit(result.status === 'passed' ? 0 : 1);

View File

@ -46,20 +46,28 @@ export const kDefaultConfigFiles = ['playwright.config.ts', 'playwright.config.j
type InternalGlobalSetupFunction = () => Promise<() => Promise<void>>; type InternalGlobalSetupFunction = () => Promise<() => Promise<void>>;
type RunOptions = {
listOnly?: boolean;
filePatternFilter?: FilePatternFilter[];
projectFilter?: string[];
};
export class Runner { export class Runner {
private _loader: Loader; private _loader: Loader;
private _printResolvedConfig: boolean;
private _reporter!: Reporter; private _reporter!: Reporter;
private _didBegin = false; private _didBegin = false;
private _internalGlobalSetups: Array<InternalGlobalSetupFunction> = []; private _internalGlobalSetups: Array<InternalGlobalSetupFunction> = [];
constructor(configOverrides: Config, defaultConfig: Config = {}) { constructor(configOverrides: Config, options: { defaultConfig?: Config, printResolvedConfig?: boolean } = {}) {
this._loader = new Loader(defaultConfig, configOverrides); this._printResolvedConfig = !!options.printResolvedConfig;
this._loader = new Loader(options.defaultConfig || {}, configOverrides);
} }
async loadConfigFromFile(configFileOrDirectory: string): Promise<Config> { async loadConfigFromFile(configFileOrDirectory: string): Promise<Config> {
const loadConfig = async (configFile: string) => { const loadConfig = async (configFile: string) => {
if (fs.existsSync(configFile)) { if (fs.existsSync(configFile)) {
if (process.stdout.isTTY) if (this._printResolvedConfig)
console.log(`Using config at ` + configFile); console.log(`Using config at ` + configFile);
const config = await this._loader.loadConfigFile(configFile); const config = await this._loader.loadConfigFile(configFile);
return config; return config;
@ -130,12 +138,12 @@ export class Runner {
this._internalGlobalSetups.push(internalGlobalSetup); this._internalGlobalSetups.push(internalGlobalSetup);
} }
async run(list: boolean, filePatternFilters: FilePatternFilter[], projectNames?: string[]): Promise<FullResult> { async runAllTests(options: RunOptions = {}): Promise<FullResult> {
this._reporter = await this._createReporter(list); this._reporter = await this._createReporter(!!options.listOnly);
try { try {
const config = this._loader.fullConfig(); const config = this._loader.fullConfig();
const globalDeadline = config.globalTimeout ? config.globalTimeout + monotonicTime() : 0; const globalDeadline = config.globalTimeout ? config.globalTimeout + monotonicTime() : 0;
const result = await raceAgainstDeadline(this._run(list, filePatternFilters, projectNames), globalDeadline); const result = await raceAgainstDeadline(this._run(!!options.listOnly, options.filePatternFilter || [], options.projectFilter), globalDeadline);
if (result.timedOut) { if (result.timedOut) {
const actualResult: FullResult = { status: 'timedout' }; const actualResult: FullResult = { status: 'timedout' };
if (this._didBegin) if (this._didBegin)
@ -152,6 +160,12 @@ export class Runner {
} catch (ignored) { } catch (ignored) {
} }
return result; return result;
} finally {
// Calling process.exit() might truncate large stdout/stderr output.
// See https://github.com/nodejs/node/issues/6456.
// See https://github.com/nodejs/node/issues/12921
await new Promise<void>(resolve => process.stdout.write('', () => resolve()));
await new Promise<void>(resolve => process.stderr.write('', () => resolve()));
} }
} }