From ee9313613227470bfad3c4288d5f4e99bff266cd Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 22 Feb 2024 15:14:13 -0800 Subject: [PATCH] chore: streamline config loader (#29627) --- packages/playwright-ct-core/src/devServer.ts | 4 +- packages/playwright/src/common/config.ts | 64 ++++++------ .../playwright/src/common/configLoader.ts | 99 +++++++------------ packages/playwright/src/common/globals.ts | 9 -- packages/playwright/src/common/ipc.ts | 8 +- packages/playwright/src/loader/loaderMain.ts | 4 +- packages/playwright/src/program.ts | 17 +--- packages/playwright/src/runner/testServer.ts | 32 +++--- packages/playwright/src/worker/workerMain.ts | 4 +- 9 files changed, 99 insertions(+), 142 deletions(-) diff --git a/packages/playwright-ct-core/src/devServer.ts b/packages/playwright-ct-core/src/devServer.ts index e802808102..46fc604188 100644 --- a/packages/playwright-ct-core/src/devServer.ts +++ b/packages/playwright-ct-core/src/devServer.ts @@ -17,7 +17,7 @@ import fs from 'fs'; import path from 'path'; import { Watcher } from 'playwright/lib/fsWatcher'; -import { loadConfigFromFile } from 'playwright/lib/common/configLoader'; +import { loadConfigFromFileRestartIfNeeded } from 'playwright/lib/common/configLoader'; import { Runner } from 'playwright/lib/runner/runner'; import type { PluginContext } from 'rollup'; import { source as injectedSource } from './generated/indexSource'; @@ -25,7 +25,7 @@ import { createConfig, populateComponentsFromTests, resolveDirs, transformIndexF import type { ComponentRegistry } from './viteUtils'; export async function runDevServer(configFile: string) { - const config = await loadConfigFromFile(configFile); + const config = await loadConfigFromFileRestartIfNeeded(configFile); if (!config) return; diff --git a/packages/playwright/src/common/config.ts b/packages/playwright/src/common/config.ts index 32ad9e586f..d1c86fe159 100644 --- a/packages/playwright/src/common/config.ts +++ b/packages/playwright/src/common/config.ts @@ -26,6 +26,11 @@ import type { ConfigCLIOverrides } from './ipc'; import type { FullConfig, FullProject } from '../../types/test'; import { setTransformConfig } from '../transform/transform'; +export type ConfigLocation = { + resolvedConfigFile?: string; + configDir: string; +}; + export type FixturesWithLocation = { fixtures: Fixtures; location: Location; @@ -58,53 +63,54 @@ export class FullConfigInternal { return (config as any)[configInternalSymbol]; } - constructor(configDir: string, configFile: string | undefined, config: Config, configCLIOverrides: ConfigCLIOverrides) { - if (configCLIOverrides.projects && config.projects) + constructor(location: ConfigLocation, userConfig: Config, configCLIOverrides: ConfigCLIOverrides) { + if (configCLIOverrides.projects && userConfig.projects) throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`); + const { resolvedConfigFile, configDir } = location; const packageJsonPath = getPackageJsonPath(configDir); const packageJsonDir = packageJsonPath ? path.dirname(packageJsonPath) : undefined; const throwawayArtifactsPath = packageJsonDir || process.cwd(); this.configDir = configDir; this.configCLIOverrides = configCLIOverrides; - this.globalOutputDir = takeFirst(configCLIOverrides.outputDir, pathResolve(configDir, config.outputDir), throwawayArtifactsPath, path.resolve(process.cwd())); + this.globalOutputDir = takeFirst(configCLIOverrides.outputDir, pathResolve(configDir, userConfig.outputDir), throwawayArtifactsPath, path.resolve(process.cwd())); this.preserveOutputDir = configCLIOverrides.preserveOutputDir || false; - this.ignoreSnapshots = takeFirst(configCLIOverrides.ignoreSnapshots, config.ignoreSnapshots, false); - const privateConfiguration = (config as any)['@playwright/test']; + this.ignoreSnapshots = takeFirst(configCLIOverrides.ignoreSnapshots, userConfig.ignoreSnapshots, false); + const privateConfiguration = (userConfig as any)['@playwright/test']; this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p })); this.config = { - configFile, - rootDir: pathResolve(configDir, config.testDir) || configDir, - forbidOnly: takeFirst(configCLIOverrides.forbidOnly, config.forbidOnly, false), - fullyParallel: takeFirst(configCLIOverrides.fullyParallel, config.fullyParallel, false), - globalSetup: takeFirst(resolveScript(config.globalSetup, configDir), null), - globalTeardown: takeFirst(resolveScript(config.globalTeardown, configDir), null), - globalTimeout: takeFirst(configCLIOverrides.globalTimeout, config.globalTimeout, 0), - grep: takeFirst(config.grep, defaultGrep), - grepInvert: takeFirst(config.grepInvert, null), - maxFailures: takeFirst(configCLIOverrides.maxFailures, config.maxFailures, 0), - metadata: takeFirst(config.metadata, {}), - preserveOutput: takeFirst(config.preserveOutput, 'always'), - reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(config.reporter, configDir), [[defaultReporter]]), - reportSlowTests: takeFirst(config.reportSlowTests, { max: 5, threshold: 15000 }), - quiet: takeFirst(configCLIOverrides.quiet, config.quiet, false), + configFile: resolvedConfigFile, + rootDir: pathResolve(configDir, userConfig.testDir) || configDir, + forbidOnly: takeFirst(configCLIOverrides.forbidOnly, userConfig.forbidOnly, false), + fullyParallel: takeFirst(configCLIOverrides.fullyParallel, userConfig.fullyParallel, false), + globalSetup: takeFirst(resolveScript(userConfig.globalSetup, configDir), null), + globalTeardown: takeFirst(resolveScript(userConfig.globalTeardown, configDir), null), + globalTimeout: takeFirst(configCLIOverrides.globalTimeout, userConfig.globalTimeout, 0), + grep: takeFirst(userConfig.grep, defaultGrep), + grepInvert: takeFirst(userConfig.grepInvert, null), + maxFailures: takeFirst(configCLIOverrides.maxFailures, userConfig.maxFailures, 0), + metadata: takeFirst(userConfig.metadata, {}), + preserveOutput: takeFirst(userConfig.preserveOutput, 'always'), + reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(userConfig.reporter, configDir), [[defaultReporter]]), + reportSlowTests: takeFirst(userConfig.reportSlowTests, { max: 5, threshold: 15000 }), + quiet: takeFirst(configCLIOverrides.quiet, userConfig.quiet, false), projects: [], - shard: takeFirst(configCLIOverrides.shard, config.shard, null), - updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, config.updateSnapshots, 'missing'), + shard: takeFirst(configCLIOverrides.shard, userConfig.shard, null), + updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, 'missing'), version: require('../../package.json').version, workers: 0, webServer: null, }; - for (const key in config) { + for (const key in userConfig) { if (key.startsWith('@')) - (this.config as any)[key] = (config as any)[key]; + (this.config as any)[key] = (userConfig as any)[key]; } (this.config as any)[configInternalSymbol] = this; - const workers = takeFirst(configCLIOverrides.workers, config.workers, '50%'); + const workers = takeFirst(configCLIOverrides.workers, userConfig.workers, '50%'); if (typeof workers === 'string') { if (workers.endsWith('%')) { const cpus = os.cpus().length; @@ -116,7 +122,7 @@ export class FullConfigInternal { this.config.workers = workers; } - const webServers = takeFirst(config.webServer, null); + const webServers = takeFirst(userConfig.webServer, null); if (Array.isArray(webServers)) { // multiple web server mode // Due to previous choices, this value shows up to the user in globalSetup as part of FullConfig. Arrays are not supported by the old type. this.config.webServer = null; @@ -128,13 +134,13 @@ export class FullConfigInternal { this.webServers = []; } - const projectConfigs = configCLIOverrides.projects || config.projects || [config]; - this.projects = projectConfigs.map(p => new FullProjectInternal(configDir, config, this, p, this.configCLIOverrides, throwawayArtifactsPath)); + const projectConfigs = configCLIOverrides.projects || userConfig.projects || [userConfig]; + this.projects = projectConfigs.map(p => new FullProjectInternal(configDir, userConfig, this, p, this.configCLIOverrides, throwawayArtifactsPath)); resolveProjectDependencies(this.projects); this._assignUniqueProjectIds(this.projects); setTransformConfig({ babelPlugins: privateConfiguration?.babelPlugins || [], - external: config.build?.external || [], + external: userConfig.build?.external || [], }); this.config.projects = this.projects.map(p => p.project); } diff --git a/packages/playwright/src/common/configLoader.ts b/packages/playwright/src/common/configLoader.ts index a5144de168..70c20c045e 100644 --- a/packages/playwright/src/common/configLoader.ts +++ b/packages/playwright/src/common/configLoader.ts @@ -21,7 +21,7 @@ import type { ConfigCLIOverrides, SerializedConfig } from './ipc'; import { requireOrImport } from '../transform/transform'; import type { Config, Project } from '../../types/test'; import { errorWithFile, fileIsModule } from '../util'; -import { setCurrentConfig } from './globals'; +import type { ConfigLocation } from './config'; import { FullConfigInternal } from './config'; import { addToCompilationCache } from '../transform/compilationCache'; import { initializeEsmLoader, registerESMLoader } from './esmLoaderHost'; @@ -84,60 +84,34 @@ export const defineConfig = (...configs: any[]) => { return result; }; -export class ConfigLoader { - private _configCLIOverrides: ConfigCLIOverrides; - private _fullConfig: FullConfigInternal | undefined; +export async function deserializeConfig(data: SerializedConfig): Promise { + if (data.compilationCache) + addToCompilationCache(data.compilationCache); - constructor(configCLIOverrides?: ConfigCLIOverrides) { - this._configCLIOverrides = configCLIOverrides || {}; - } - - static async deserialize(data: SerializedConfig): Promise { - if (data.compilationCache) - addToCompilationCache(data.compilationCache); - - const loader = new ConfigLoader(data.configCLIOverrides); - const config = data.configFile ? await loader.loadConfigFile(data.configFile) : await loader.loadEmptyConfig(data.configDir); - await initializeEsmLoader(); - return config; - } - - async loadConfigFile(file: string, ignoreProjectDependencies = false): Promise { - if (this._fullConfig) - throw new Error('Cannot load two config files'); - const config = await requireOrImportDefaultObject(file) as Config; - const fullConfig = await this._loadConfig(config, path.dirname(file), file); - setCurrentConfig(fullConfig); - if (ignoreProjectDependencies) { - for (const project of fullConfig.projects) { - project.deps = []; - project.teardown = undefined; - } - } - this._fullConfig = fullConfig; - return fullConfig; - } - - async loadEmptyConfig(configDir: string): Promise { - const fullConfig = await this._loadConfig({}, configDir); - setCurrentConfig(fullConfig); - return fullConfig; - } - - private async _loadConfig(config: Config, configDir: string, configFile?: string): Promise { - // 1. Validate data provided in the config file. - validateConfig(configFile || '', config); - const fullConfig = new FullConfigInternal(configDir, configFile, config, this._configCLIOverrides); - fullConfig.defineConfigWasUsed = !!(config as any)[kDefineConfigWasUsed]; - return fullConfig; - } + const config = await loadConfig(data.location, data.configCLIOverrides); + await initializeEsmLoader(); + return config; } -async function requireOrImportDefaultObject(file: string) { - let object = await requireOrImport(file); +export async function loadUserConfig(location: ConfigLocation): Promise { + let object = location.resolvedConfigFile ? await requireOrImport(location.resolvedConfigFile) : {}; if (object && typeof object === 'object' && ('default' in object)) object = object['default']; - return object; + return object as Config; +} + +export async function loadConfig(location: ConfigLocation, overrides?: ConfigCLIOverrides, ignoreProjectDependencies = false): Promise { + const userConfig = await loadUserConfig(location); + validateConfig(location.resolvedConfigFile || '', userConfig); + const fullConfig = new FullConfigInternal(location, userConfig, overrides || {}); + fullConfig.defineConfigWasUsed = !!(userConfig as any)[kDefineConfigWasUsed]; + if (ignoreProjectDependencies) { + for (const project of fullConfig.projects) { + project.deps = []; + project.teardown = undefined; + } + } + return fullConfig; } function validateConfig(file: string, config: Config) { @@ -312,7 +286,7 @@ function validateProject(file: string, project: Project, title: string) { } } -export function resolveConfigFile(configFileOrDirectory: string): string | null { +export function resolveConfigFile(configFileOrDirectory: string): string | undefined { const resolveConfig = (configFile: string) => { if (fs.existsSync(configFile)) return configFile; @@ -334,7 +308,7 @@ export function resolveConfigFile(configFileOrDirectory: string): string | null if (configFile) return configFile; // If there is no config, assume this as a root testing directory. - return null; + return undefined; } else { // When passed a file, it must be a config file. const configFile = resolveConfig(configFileOrDirectory); @@ -342,21 +316,24 @@ export function resolveConfigFile(configFileOrDirectory: string): string | null } } -export async function loadConfigFromFile(configFile: string | undefined, overrides?: ConfigCLIOverrides, ignoreDeps?: boolean): Promise { +export async function loadConfigFromFileRestartIfNeeded(configFile: string | undefined, overrides?: ConfigCLIOverrides, ignoreDeps?: boolean): Promise { const configFileOrDirectory = configFile ? path.resolve(process.cwd(), configFile) : process.cwd(); const resolvedConfigFile = resolveConfigFile(configFileOrDirectory); if (restartWithExperimentalTsEsm(resolvedConfigFile)) return null; - const configLoader = new ConfigLoader(overrides); - let config: FullConfigInternal; - if (resolvedConfigFile) - config = await configLoader.loadConfigFile(resolvedConfigFile, ignoreDeps); - else - config = await configLoader.loadEmptyConfig(configFileOrDirectory); - return config; + const location: ConfigLocation = { + configDir: resolvedConfigFile ? path.dirname(resolvedConfigFile) : configFileOrDirectory, + resolvedConfigFile, + }; + return await loadConfig(location, overrides, ignoreDeps); } -export function restartWithExperimentalTsEsm(configFile: string | null): boolean { +export async function loadEmptyConfigForMergeReports() { + // Merge reports is "different" for no good reason. It should not pick up local config from the cwd. + return await loadConfig({ configDir: process.cwd() }); +} + +export function restartWithExperimentalTsEsm(configFile: string | undefined): boolean { const nodeVersion = +process.versions.node.split('.')[0]; // New experimental loader is only supported on Node 16+. if (nodeVersion < 16) diff --git a/packages/playwright/src/common/globals.ts b/packages/playwright/src/common/globals.ts index 9443db25d3..c2ead505e6 100644 --- a/packages/playwright/src/common/globals.ts +++ b/packages/playwright/src/common/globals.ts @@ -16,7 +16,6 @@ import type { TestInfoImpl } from '../worker/testInfo'; import type { Suite } from './test'; -import type { FullConfigInternal } from './config'; let currentTestInfoValue: TestInfoImpl | null = null; export function setCurrentTestInfo(testInfo: TestInfoImpl | null) { @@ -61,11 +60,3 @@ export function setIsWorkerProcess() { export function isWorkerProcess() { return _isWorkerProcess; } - -let currentConfigValue: FullConfigInternal | null = null; -export function setCurrentConfig(config: FullConfigInternal | null) { - currentConfigValue = config; -} -export function currentConfig(): FullConfigInternal | null { - return currentConfigValue; -} diff --git a/packages/playwright/src/common/ipc.ts b/packages/playwright/src/common/ipc.ts index ef4b445595..bb35f6c06d 100644 --- a/packages/playwright/src/common/ipc.ts +++ b/packages/playwright/src/common/ipc.ts @@ -16,7 +16,7 @@ import util from 'util'; import { serializeCompilationCache } from '../transform/compilationCache'; -import type { FullConfigInternal } from './config'; +import type { ConfigLocation, FullConfigInternal } from './config'; import type { ReporterDescription, TestInfoError, TestStatus } from '../../types/test'; export type ConfigCLIOverrides = { @@ -41,8 +41,7 @@ export type ConfigCLIOverrides = { }; export type SerializedConfig = { - configFile: string | undefined; - configDir: string; + location: ConfigLocation; configCLIOverrides: ConfigCLIOverrides; compilationCache: any; }; @@ -138,8 +137,7 @@ export type EnvProducedPayload = [string, string | null][]; export function serializeConfig(config: FullConfigInternal, passCompilationCache: boolean): SerializedConfig { const result: SerializedConfig = { - configFile: config.config.configFile, - configDir: config.configDir, + location: { configDir: config.configDir, resolvedConfigFile: config.config.configFile }, configCLIOverrides: config.configCLIOverrides, compilationCache: passCompilationCache ? serializeCompilationCache() : undefined, }; diff --git a/packages/playwright/src/loader/loaderMain.ts b/packages/playwright/src/loader/loaderMain.ts index 7e865c7e4b..97befeea9d 100644 --- a/packages/playwright/src/loader/loaderMain.ts +++ b/packages/playwright/src/loader/loaderMain.ts @@ -15,7 +15,7 @@ */ import type { SerializedConfig } from '../common/ipc'; -import { ConfigLoader } from '../common/configLoader'; +import { deserializeConfig } from '../common/configLoader'; import { ProcessRunner } from '../common/process'; import type { FullConfigInternal } from '../common/config'; import { loadTestFile } from '../common/testLoader'; @@ -36,7 +36,7 @@ export class LoaderMain extends ProcessRunner { private _config(): Promise { if (!this._configPromise) - this._configPromise = ConfigLoader.deserialize(this._serializedConfig); + this._configPromise = deserializeConfig(this._serializedConfig); return this._configPromise; } diff --git a/packages/playwright/src/program.ts b/packages/playwright/src/program.ts index cbe161b59f..ccd0ec9a1d 100644 --- a/packages/playwright/src/program.ts +++ b/packages/playwright/src/program.ts @@ -24,12 +24,11 @@ import { stopProfiling, startProfiling, gracefullyProcessExitDoNotHang } from 'p import { serializeError } from './util'; import { showHTMLReport } from './reporters/html'; import { createMergedReport } from './reporters/merge'; -import { ConfigLoader, loadConfigFromFile } from './common/configLoader'; +import { loadConfigFromFileRestartIfNeeded, loadEmptyConfigForMergeReports } from './common/configLoader'; import type { ConfigCLIOverrides } from './common/ipc'; import type { FullResult, TestError } from '../types/testReporter'; import type { FullConfig, TraceMode } from '../types/test'; import { builtInReporters, defaultReporter, defaultTimeout } from './common/config'; -import type { FullConfigInternal } from './common/config'; import { program } from 'playwright-core/lib/cli/program'; export { program } from 'playwright-core/lib/cli/program'; import type { ReporterDescription } from '../types/test'; @@ -74,7 +73,7 @@ function addClearCacheCommand(program: Command) { command.description('clears build and test caches'); command.option('-c, --config ', `Configuration file, or a test directory with optional "playwright.config.{m,c}?{js,ts}"`); command.action(async opts => { - const configInternal = await loadConfigFromFile(opts.config); + const configInternal = await loadConfigFromFileRestartIfNeeded(opts.config); if (!configInternal) return; const { config, configDir } = configInternal; @@ -154,7 +153,7 @@ Examples: async function runTests(args: string[], opts: { [key: string]: any }) { await startProfiling(); - const config = await loadConfigFromFile(opts.config, overridesFromOptions(opts), opts.deps === false); + const config = await loadConfigFromFileRestartIfNeeded(opts.config, overridesFromOptions(opts), opts.deps === false); if (!config) return; @@ -183,7 +182,7 @@ export async function withRunnerAndMutedWrite(configFile: string | undefined, ca const stdoutWrite = process.stdout.write.bind(process.stdout); process.stdout.write = ((a: any, b: any, c: any) => process.stderr.write(a, b, c)) as any; try { - const config = await loadConfigFromFile(configFile); + const config = await loadConfigFromFileRestartIfNeeded(configFile); if (!config) return; const runner = new Runner(config); @@ -209,13 +208,7 @@ async function listTestFiles(opts: { [key: string]: any }) { async function mergeReports(reportDir: string | undefined, opts: { [key: string]: any }) { const configFile = opts.config; - let config: FullConfigInternal | null; - if (configFile) { - config = await loadConfigFromFile(configFile); - } else { - const configLoader = new ConfigLoader(); - config = await configLoader.loadEmptyConfig(process.cwd()); - } + const config = configFile ? await loadConfigFromFileRestartIfNeeded(configFile) : await loadEmptyConfigForMergeReports(); if (!config) return; diff --git a/packages/playwright/src/runner/testServer.ts b/packages/playwright/src/runner/testServer.ts index 805a73ceb8..e07fc1b9f1 100644 --- a/packages/playwright/src/runner/testServer.ts +++ b/packages/playwright/src/runner/testServer.ts @@ -16,12 +16,11 @@ import type http from 'http'; import path from 'path'; -import { ManualPromise, createGuid } from 'playwright-core/lib/utils'; +import { ManualPromise, createGuid, gracefullyProcessExitDoNotHang } from 'playwright-core/lib/utils'; import { WSServer } from 'playwright-core/lib/utils'; import type { WebSocket } from 'playwright-core/lib/utilsBundle'; import type { FullResult } from 'playwright/types/testReporter'; -import type { FullConfigInternal } from '../common/config'; -import { ConfigLoader, resolveConfigFile, restartWithExperimentalTsEsm } from '../common/configLoader'; +import { loadConfig, resolveConfigFile, restartWithExperimentalTsEsm } from '../common/configLoader'; import { InternalReporter } from '../reporters/internalReporter'; import { Multiplexer } from '../reporters/multiplexer'; import { createReporters } from './reporters'; @@ -29,6 +28,7 @@ import { TestRun, createTaskRunnerForList, createTaskRunnerForTestServer } from import type { ConfigCLIOverrides } from '../common/ipc'; import { Runner } from './runner'; import type { FindRelatedTestFilesReport } from './runner'; +import type { ConfigLocation } from '../common/config'; type PlaywrightTestOptions = { headed?: boolean, @@ -40,11 +40,6 @@ type PlaywrightTestOptions = { connectWsEndpoint?: string; }; -type ConfigPaths = { - configFile: string | null; - configDir: string; -}; - export async function runTestServer(configFile: string | undefined) { process.env.PW_TEST_HTML_REPORT_OPEN = 'never'; @@ -52,8 +47,8 @@ export async function runTestServer(configFile: string | undefined) { const resolvedConfigFile = resolveConfigFile(configFileOrDirectory); if (restartWithExperimentalTsEsm(resolvedConfigFile)) return null; - const configPaths: ConfigPaths = { - configFile: resolvedConfigFile, + const configPaths: ConfigLocation = { + resolvedConfigFile, configDir: resolvedConfigFile ? path.dirname(resolvedConfigFile) : configFileOrDirectory }; @@ -77,16 +72,19 @@ export async function runTestServer(configFile: string | undefined) { }); const url = await wss.listen(0, 'localhost', '/' + createGuid()); // eslint-disable-next-line no-console + process.on('exit', () => wss.close().catch(console.error)); + // eslint-disable-next-line no-console console.log(`Listening on ${url}`); + process.stdin.on('close', () => gracefullyProcessExitDoNotHang(0)); } class Dispatcher { private _testRun: { run: Promise, stop: ManualPromise } | undefined; private _ws: WebSocket; - private _configPaths: ConfigPaths; + private _configLocation: ConfigLocation; - constructor(configPaths: ConfigPaths, ws: WebSocket) { - this._configPaths = configPaths; + constructor(configLocation: ConfigLocation, ws: WebSocket) { + this._configLocation = configLocation; this._ws = ws; process.stdout.write = ((chunk: string | Buffer, cb?: Buffer | Function, cb2?: Function) => { @@ -190,13 +188,7 @@ class Dispatcher { } private async _loadConfig(overrides: ConfigCLIOverrides) { - const configLoader = new ConfigLoader(overrides); - let config: FullConfigInternal; - if (this._configPaths.configFile) - config = await configLoader.loadConfigFile(this._configPaths.configFile, false); - else - config = await configLoader.loadEmptyConfig(this._configPaths.configDir); - return config; + return await loadConfig(this._configLocation, overrides); } private _dispatchEvent(method: string, params: any) { diff --git a/packages/playwright/src/worker/workerMain.ts b/packages/playwright/src/worker/workerMain.ts index ffc6e81671..d678e485aa 100644 --- a/packages/playwright/src/worker/workerMain.ts +++ b/packages/playwright/src/worker/workerMain.ts @@ -18,7 +18,7 @@ import { colors } from 'playwright-core/lib/utilsBundle'; import { debugTest, formatLocation, relativeFilePath, serializeError } from '../util'; import { type TestBeginPayload, type TestEndPayload, type RunPayload, type DonePayload, type WorkerInitParams, type TeardownErrorsPayload, stdioChunkToParams } from '../common/ipc'; import { setCurrentTestInfo, setIsWorkerProcess } from '../common/globals'; -import { ConfigLoader } from '../common/configLoader'; +import { deserializeConfig } from '../common/configLoader'; import type { Suite, TestCase } from '../common/test'; import type { Annotation, FullConfigInternal, FullProjectInternal } from '../common/config'; import { FixtureRunner } from './fixtureRunner'; @@ -205,7 +205,7 @@ export class WorkerMain extends ProcessRunner { if (this._config) return; - this._config = await ConfigLoader.deserialize(this._params.config); + this._config = await deserializeConfig(this._params.config); this._project = this._config.projects.find(p => p.id === this._params.projectId)!; this._poolBuilder = PoolBuilder.createForWorker(this._project); }