@@ -115,11 +115,12 @@ export async function resolveCLIConfigForMCP(cliOptions: CLIOptions, env?: NodeJ
115115 const cliOverrides = configFromCLIOptions ( cliOptions ) ;
116116 const configFile = cliOverrides . configFile ?? envOverrides . configFile ;
117117 const configInFile = await loadConfig ( configFile ) ;
118+ const configDir = configFile ? path . dirname ( path . resolve ( configFile ) ) : process . cwd ( ) ;
118119
119120 let result = defaultConfig ;
120- result = mergeConfig ( result , configInFile ) ;
121- result = mergeConfig ( result , envOverrides ) ;
122- result = mergeConfig ( result , cliOverrides ) ;
121+ result = mergeConfig ( result , resolveConfigPaths ( configInFile , configDir ) ) ;
122+ result = mergeConfig ( result , resolveConfigPaths ( envOverrides , process . cwd ( ) ) ) ;
123+ result = mergeConfig ( result , resolveConfigPaths ( cliOverrides , process . cwd ( ) ) ) ;
123124
124125 const browser = await validateBrowserConfig ( result . browser ) ;
125126 if ( browser . launchOptions . headless === undefined )
@@ -151,14 +152,17 @@ export async function resolveCLIConfigForCLI(daemonProfilesDir: string, sessionN
151152 const envOverrides = configFromEnv ( env ) ;
152153 const configFile = daemonOverrides . configFile ?? envOverrides . configFile ;
153154 const configInFile = await loadConfig ( configFile ) ;
155+ const configDir = configFile ? path . dirname ( path . resolve ( configFile ) ) : process . cwd ( ) ;
154156 const globalConfigPath = path . join ( ( env ?? process . env ) [ 'PWTEST_CLI_GLOBAL_CONFIG' ] ?? os . homedir ( ) , '.playwright' , 'cli.config.json' ) ;
155- const globalConfigInFile = await loadConfig ( fs . existsSync ( globalConfigPath ) ? globalConfigPath : undefined ) ;
157+ const globalConfigExists = fs . existsSync ( globalConfigPath ) ;
158+ const globalConfigInFile = await loadConfig ( globalConfigExists ? globalConfigPath : undefined ) ;
159+ const globalConfigDir = globalConfigExists ? path . dirname ( globalConfigPath ) : process . cwd ( ) ;
156160
157161 let result = defaultConfig ;
158- result = mergeConfig ( result , globalConfigInFile ) ;
159- result = mergeConfig ( result , configInFile ) ;
160- result = mergeConfig ( result , envOverrides ) ;
161- result = mergeConfig ( result , daemonOverrides ) ;
162+ result = mergeConfig ( result , resolveConfigPaths ( globalConfigInFile , globalConfigDir ) ) ;
163+ result = mergeConfig ( result , resolveConfigPaths ( configInFile , configDir ) ) ;
164+ result = mergeConfig ( result , resolveConfigPaths ( envOverrides , process . cwd ( ) ) ) ;
165+ result = mergeConfig ( result , resolveConfigPaths ( daemonOverrides , process . cwd ( ) ) ) ;
162166
163167 if ( result . browser . isolated === undefined )
164168 result . browser . isolated = ! options . profile && ! options . persistent && ! result . browser . userDataDir && ! result . browser . remoteEndpoint && ! result . browser . cdpEndpoint && ! result . extension ;
@@ -408,6 +412,18 @@ export async function loadConfig(configFile: string | undefined): Promise<Config
408412 }
409413}
410414
415+ // initPage/initScript paths are resolved against a per-source base dir
416+ // (config-file dir for entries loaded from a --config file, cwd for entries
417+ // supplied via CLI flags or PLAYWRIGHT_MCP_INIT_* env vars) so they keep
418+ // working when the CLI is invoked from a different cwd.
419+ function resolveConfigPaths ( config : Config , baseDir : string ) : Config {
420+ if ( config . browser ?. initPage )
421+ config . browser . initPage = config . browser . initPage . map ( p => path . resolve ( baseDir , p ) ) ;
422+ if ( config . browser ?. initScript )
423+ config . browser . initScript = config . browser . initScript . map ( p => path . resolve ( baseDir , p ) ) ;
424+ return config ;
425+ }
426+
411427function pickDefined < T extends object > ( obj : T | undefined ) : Partial < T > {
412428 return Object . fromEntries (
413429 Object . entries ( obj ?? { } ) . filter ( ( [ _ , v ] ) => v !== undefined )
0 commit comments