diff --git a/packages/playwright-test/src/cli.ts b/packages/playwright-test/src/cli.ts index baa3750732..f930ecf069 100644 --- a/packages/playwright-test/src/cli.ts +++ b/packages/playwright-test/src/cli.ts @@ -121,7 +121,7 @@ async function runTests(args: string[], opts: { [key: string]: any }) { 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. 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) 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); return { re: forceRegExp(match ? match[1] : arg), @@ -139,15 +139,13 @@ async function runTests(args: string[], opts: { [key: string]: any }) { if (process.env.PLAYWRIGHT_DOCKER) 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); - // 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(resolve => process.stdout.write('', () => resolve())); - await new Promise(resolve => process.stderr.write('', () => resolve())); - if (result.status === 'interrupted') process.exit(130); process.exit(result.status === 'passed' ? 0 : 1); diff --git a/packages/playwright-test/src/runner.ts b/packages/playwright-test/src/runner.ts index e2149a33e0..27ce6ff227 100644 --- a/packages/playwright-test/src/runner.ts +++ b/packages/playwright-test/src/runner.ts @@ -46,20 +46,28 @@ export const kDefaultConfigFiles = ['playwright.config.ts', 'playwright.config.j type InternalGlobalSetupFunction = () => Promise<() => Promise>; +type RunOptions = { + listOnly?: boolean; + filePatternFilter?: FilePatternFilter[]; + projectFilter?: string[]; +}; + export class Runner { private _loader: Loader; + private _printResolvedConfig: boolean; private _reporter!: Reporter; private _didBegin = false; private _internalGlobalSetups: Array = []; - constructor(configOverrides: Config, defaultConfig: Config = {}) { - this._loader = new Loader(defaultConfig, configOverrides); + constructor(configOverrides: Config, options: { defaultConfig?: Config, printResolvedConfig?: boolean } = {}) { + this._printResolvedConfig = !!options.printResolvedConfig; + this._loader = new Loader(options.defaultConfig || {}, configOverrides); } async loadConfigFromFile(configFileOrDirectory: string): Promise { const loadConfig = async (configFile: string) => { if (fs.existsSync(configFile)) { - if (process.stdout.isTTY) + if (this._printResolvedConfig) console.log(`Using config at ` + configFile); const config = await this._loader.loadConfigFile(configFile); return config; @@ -130,12 +138,12 @@ export class Runner { this._internalGlobalSetups.push(internalGlobalSetup); } - async run(list: boolean, filePatternFilters: FilePatternFilter[], projectNames?: string[]): Promise { - this._reporter = await this._createReporter(list); + async runAllTests(options: RunOptions = {}): Promise { + this._reporter = await this._createReporter(!!options.listOnly); try { const config = this._loader.fullConfig(); 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) { const actualResult: FullResult = { status: 'timedout' }; if (this._didBegin) @@ -152,6 +160,12 @@ export class Runner { } catch (ignored) { } 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(resolve => process.stdout.write('', () => resolve())); + await new Promise(resolve => process.stderr.write('', () => resolve())); } }