chore: remove default config from cli (#13832)
This commit is contained in:
parent
4984878411
commit
18bff137ce
|
|
@ -17,6 +17,7 @@
|
|||
import * as crypto from 'crypto';
|
||||
import type stream from 'stream';
|
||||
import * as URL from 'url';
|
||||
import v8 from 'v8';
|
||||
|
||||
type NameValue = {
|
||||
name: string,
|
||||
|
|
@ -214,3 +215,7 @@ export function streamToString(stream: stream.Readable): Promise<string> {
|
|||
}
|
||||
|
||||
export const isLikelyNpxGlobal = () => process.argv.length >= 2 && process.argv[1].includes('_npx');
|
||||
|
||||
export function deepCopy<T>(obj: T): T {
|
||||
return v8.deserialize(v8.serialize(obj));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,18 +20,12 @@ import type { Command } from 'playwright-core/lib/utilsBundle';
|
|||
import fs from 'fs';
|
||||
import url from 'url';
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
import type { Config } from './types';
|
||||
import type { BuiltInReporter } from './runner';
|
||||
import { Runner, builtInReporters, kDefaultConfigFiles } from './runner';
|
||||
import { stopProfiling, startProfiling } from './profiler';
|
||||
import type { FilePatternFilter } from './util';
|
||||
import { showHTMLReport } from './reporters/html';
|
||||
import { hostPlatform } from 'playwright-core/lib/utils/hostPlatform';
|
||||
import { fileIsModule } from './loader';
|
||||
|
||||
const defaultTimeout = 30000;
|
||||
const defaultReporter: BuiltInReporter = process.env.CI ? 'dot' : 'list';
|
||||
import { baseFullConfig, defaultTimeout, fileIsModule } from './loader';
|
||||
|
||||
export function addTestCommand(program: Command) {
|
||||
const command = program.command('test [test-filter...]');
|
||||
|
|
@ -51,7 +45,7 @@ export function addTestCommand(program: Command) {
|
|||
command.option('--output <dir>', `Folder for output artifacts (default: "test-results")`);
|
||||
command.option('--quiet', `Suppress stdio`);
|
||||
command.option('--repeat-each <N>', `Run each test N times (default: 1)`);
|
||||
command.option('--reporter <reporter>', `Reporter to use, comma-separated, can be ${builtInReporters.map(name => `"${name}"`).join(', ')} (default: "${defaultReporter}")`);
|
||||
command.option('--reporter <reporter>', `Reporter to use, comma-separated, can be ${builtInReporters.map(name => `"${name}"`).join(', ')} (default: "${baseFullConfig.reporter[0]}")`);
|
||||
command.option('--retries <retries>', `Maximum retry count for flaky tests, zero for no retries (default: no retries)`);
|
||||
command.option('--shard <shard>', `Shard tests and execute only the selected shard, specify in the form "current/all", 1-based, for example "3/5"`);
|
||||
command.option('--project <project-name...>', `Only run tests from the specified list of projects (default: run all projects)`);
|
||||
|
|
@ -108,24 +102,13 @@ Examples:
|
|||
async function runTests(args: string[], opts: { [key: string]: any }) {
|
||||
await startProfiling();
|
||||
|
||||
const cpus = os.cpus().length;
|
||||
const workers = hostPlatform.startsWith('mac') && hostPlatform.endsWith('arm64') ? cpus : Math.ceil(cpus / 2);
|
||||
|
||||
const defaultConfig: Config = {
|
||||
preserveOutput: 'always',
|
||||
reporter: [ [defaultReporter] ],
|
||||
reportSlowTests: { max: 5, threshold: 15000 },
|
||||
timeout: defaultTimeout,
|
||||
updateSnapshots: 'missing',
|
||||
workers,
|
||||
};
|
||||
|
||||
const overrides = overridesFromOptions(opts);
|
||||
if (opts.browser) {
|
||||
const browserOpt = opts.browser.toLowerCase();
|
||||
if (!['all', 'chromium', 'firefox', 'webkit'].includes(browserOpt))
|
||||
throw new Error(`Unsupported browser "${opts.browser}", must be one of "all", "chromium", "firefox" or "webkit"`);
|
||||
const browserNames = browserOpt === 'all' ? ['chromium', 'firefox', 'webkit'] : [browserOpt];
|
||||
defaultConfig.projects = browserNames.map(browserName => {
|
||||
overrides.projects = browserNames.map(browserName => {
|
||||
return {
|
||||
name: browserName,
|
||||
use: { browserName },
|
||||
|
|
@ -133,7 +116,6 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
|
|||
});
|
||||
}
|
||||
|
||||
const overrides = overridesFromOptions(opts);
|
||||
if (opts.headed || opts.debug)
|
||||
overrides.use = { headless: false };
|
||||
if (opts.debug) {
|
||||
|
|
@ -149,7 +131,7 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
|
|||
if (restartWithExperimentalTsEsm(resolvedConfigFile))
|
||||
return;
|
||||
|
||||
const runner = new Runner(overrides, { defaultConfig });
|
||||
const runner = new Runner(overrides);
|
||||
const config = resolvedConfigFile ? await runner.loadConfigFromResolvedFile(resolvedConfigFile) : await runner.loadEmptyConfig(configFileOrDirectory);
|
||||
if (('projects' in config) && opts.browser)
|
||||
throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`);
|
||||
|
|
@ -185,7 +167,7 @@ async function listTestFiles(opts: { [key: string]: any }) {
|
|||
if (restartWithExperimentalTsEsm(resolvedConfigFile))
|
||||
return;
|
||||
|
||||
const runner = new Runner({}, { defaultConfig: {} });
|
||||
const runner = new Runner();
|
||||
await runner.loadConfigFromResolvedFile(resolvedConfigFile);
|
||||
const report = await runner.listTestFiles(resolvedConfigFile, opts.project);
|
||||
write(JSON.stringify(report), () => {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import type { TestError } from '../types/testReporter';
|
|||
import type { Config, TestStatus } from './types';
|
||||
|
||||
export type SerializedLoaderData = {
|
||||
defaultConfig: Config;
|
||||
overrides: Config;
|
||||
configFile: { file: string } | { configDir: string };
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,34 +24,36 @@ import type { SerializedLoaderData } from './ipc';
|
|||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import { ProjectImpl } from './project';
|
||||
import type { BuiltInReporter } from './runner';
|
||||
import type { Reporter } from '../types/testReporter';
|
||||
import { builtInReporters } from './runner';
|
||||
import { isRegExp } from 'playwright-core/lib/utils';
|
||||
import { deepCopy, isRegExp } from 'playwright-core/lib/utils';
|
||||
import { serializeError } from './util';
|
||||
import { _legacyWebServer } from './plugins/webServerPlugin';
|
||||
import { hostPlatform } from 'playwright-core/lib/utils/hostPlatform';
|
||||
|
||||
export const defaultTimeout = 30000;
|
||||
|
||||
// To allow multiple loaders in the same process without clearing require cache,
|
||||
// we make these maps global.
|
||||
const cachedFileSuites = new Map<string, Suite>();
|
||||
|
||||
export class Loader {
|
||||
private _defaultConfig: Config;
|
||||
private _configOverrides: Config;
|
||||
private _fullConfig: FullConfigInternal;
|
||||
private _configDir: string = '';
|
||||
private _configFile: string | undefined;
|
||||
private _projects: ProjectImpl[] = [];
|
||||
|
||||
constructor(defaultConfig: Config, configOverrides: Config) {
|
||||
this._defaultConfig = defaultConfig;
|
||||
this._configOverrides = configOverrides;
|
||||
constructor(configOverrides?: Config) {
|
||||
this._configOverrides = configOverrides || {};
|
||||
this._fullConfig = { ...baseFullConfig };
|
||||
}
|
||||
|
||||
static async deserialize(data: SerializedLoaderData): Promise<Loader> {
|
||||
const loader = new Loader(data.defaultConfig, data.overrides);
|
||||
const loader = new Loader(data.overrides);
|
||||
if ('file' in data.configFile)
|
||||
await loader.loadConfigFile(data.configFile.file);
|
||||
else
|
||||
|
|
@ -62,11 +64,12 @@ export class Loader {
|
|||
async loadConfigFile(file: string): Promise<Config> {
|
||||
if (this._configFile)
|
||||
throw new Error('Cannot load two config files');
|
||||
let config = await this._requireOrImport(file);
|
||||
let config = await this._requireOrImport(file) as Config;
|
||||
if (config && typeof config === 'object' && ('default' in config))
|
||||
config = config['default'];
|
||||
config = (config as any)['default'];
|
||||
this._configFile = file;
|
||||
const rawConfig = { ...config };
|
||||
const rawConfig = deepCopy({ ...config, plugins: [] });
|
||||
rawConfig.plugins = config.plugins?.slice() || [] as any;
|
||||
await this._processConfigObject(config, path.dirname(file));
|
||||
return rawConfig;
|
||||
}
|
||||
|
|
@ -108,9 +111,6 @@ export class Loader {
|
|||
if (config.webServer)
|
||||
config.webServer.cwd = config.webServer.cwd ? path.resolve(configDir, config.webServer.cwd) : configDir;
|
||||
|
||||
const configUse = mergeObjects(this._defaultConfig.use, config.use);
|
||||
config = mergeObjects(mergeObjects(this._defaultConfig, config), { use: configUse });
|
||||
|
||||
this._fullConfig._configDir = configDir;
|
||||
this._fullConfig.rootDir = config.testDir || this._configDir;
|
||||
this._fullConfig._globalOutputDir = takeFirst(config.outputDir, throwawayArtifactsPath, baseFullConfig._globalOutputDir);
|
||||
|
|
@ -132,7 +132,7 @@ export class Loader {
|
|||
this._fullConfig.webServer = takeFirst(this._configOverrides.webServer, config.webServer, baseFullConfig.webServer);
|
||||
this._fullConfig._plugins = takeFirst(this._configOverrides.plugins, config.plugins, baseFullConfig._plugins);
|
||||
|
||||
const projects: Project[] = ('projects' in config) && config.projects !== undefined ? config.projects : [config];
|
||||
const projects: Project[] = this._configOverrides.projects || config.projects || [config];
|
||||
for (const project of projects)
|
||||
this._addProject(config, project, throwawayArtifactsPath);
|
||||
this._fullConfig.projects = this._projects.map(p => p.config);
|
||||
|
|
@ -210,7 +210,6 @@ export class Loader {
|
|||
|
||||
serialize(): SerializedLoaderData {
|
||||
return {
|
||||
defaultConfig: this._defaultConfig,
|
||||
configFile: this._configFile ? { file: this._configFile } : { configDir: this._configDir },
|
||||
overrides: this._configOverrides,
|
||||
};
|
||||
|
|
@ -248,7 +247,7 @@ export class Loader {
|
|||
_screenshotsDir: screenshotsDir,
|
||||
testIgnore: takeFirst(this._configOverrides.testIgnore, projectConfig.testIgnore, config.testIgnore, []),
|
||||
testMatch: takeFirst(this._configOverrides.testMatch, projectConfig.testMatch, config.testMatch, '**/?(*.)@(spec|test).*'),
|
||||
timeout: takeFirst(this._configOverrides.timeout, projectConfig.timeout, config.timeout, 10000),
|
||||
timeout: takeFirst(this._configOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout),
|
||||
use: mergeObjects(mergeObjects(config.use, projectConfig.use), this._configOverrides.use),
|
||||
};
|
||||
this._projects.push(new ProjectImpl(fullProject, this._projects.length));
|
||||
|
|
@ -467,7 +466,10 @@ function validateProject(file: string, project: Project, title: string) {
|
|||
}
|
||||
}
|
||||
|
||||
const baseFullConfig: FullConfigInternal = {
|
||||
const cpus = os.cpus().length;
|
||||
const workers = hostPlatform.startsWith('mac') && hostPlatform.endsWith('arm64') ? cpus : Math.ceil(cpus / 2);
|
||||
|
||||
export const baseFullConfig: FullConfigInternal = {
|
||||
forbidOnly: false,
|
||||
fullyParallel: false,
|
||||
globalSetup: null,
|
||||
|
|
@ -478,14 +480,14 @@ const baseFullConfig: FullConfigInternal = {
|
|||
maxFailures: 0,
|
||||
preserveOutput: 'always',
|
||||
projects: [],
|
||||
reporter: [ ['list'] ],
|
||||
reportSlowTests: null,
|
||||
reporter: [ [process.env.CI ? 'dot' : 'list'] ],
|
||||
reportSlowTests: { max: 5, threshold: 15000 },
|
||||
rootDir: path.resolve(process.cwd()),
|
||||
quiet: false,
|
||||
shard: null,
|
||||
updateSnapshots: 'missing',
|
||||
version: require('../package.json').version,
|
||||
workers: 1,
|
||||
workers,
|
||||
webServer: null,
|
||||
_globalOutputDir: path.resolve(process.cwd()),
|
||||
_configDir: '',
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ export class Runner {
|
|||
private _reporter!: Reporter;
|
||||
private _globalInfo: GlobalInfoImpl;
|
||||
|
||||
constructor(configOverrides: Config, options: { defaultConfig?: Config } = {}) {
|
||||
this._loader = new Loader(options.defaultConfig || {}, configOverrides);
|
||||
constructor(configOverrides?: Config) {
|
||||
this._loader = new Loader(configOverrides);
|
||||
this._globalInfo = new GlobalInfoImpl(this._loader.fullConfig());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue