chore: allow merging defineConfig (#26390)

This commit is contained in:
Pavel Feldman 2023-08-09 17:23:34 -07:00 committed by GitHub
parent cadc3153f7
commit 08d6abab4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 111 additions and 4 deletions

View File

@ -27,9 +27,53 @@ import { addToCompilationCache } from '../transform/compilationCache';
import { initializeEsmLoader } from './esmLoaderHost';
const kDefineConfigWasUsed = Symbol('defineConfigWasUsed');
export const defineConfig = (config: any) => {
config[kDefineConfigWasUsed] = true;
return config;
export const defineConfig = (...configs: any[]) => {
let result = configs[0];
for (let i = 1; i < configs.length; ++i) {
const config = configs[i];
result = {
...result,
...config,
expect: {
...result.expect,
...config.expect,
},
use: {
...result.use,
...config.use,
},
webServer: [
...(Array.isArray(result.webServer) ? result.webServer : (result.webServer ? [result.webServer] : [])),
...(Array.isArray(config.webServer) ? config.webServer : (config.webServer ? [config.webServer] : [])),
]
};
const projectOverrides = new Map<string, any>();
for (const project of config.projects || [])
projectOverrides.set(project.name, project);
const projects = [];
for (const project of result.projects || []) {
const projectOverride = projectOverrides.get(project.name);
if (projectOverride) {
projects.push({
...project,
...projectOverride,
use: {
...project.use,
...projectOverride.use,
}
});
projectOverrides.delete(project.name);
} else {
projects.push(project);
}
}
projects.push(...projectOverrides.values());
result.projects = projects;
}
result[kDefineConfigWasUsed] = true;
return result;
};
export class ConfigLoader {

View File

@ -5022,6 +5022,9 @@ export const expect: Expect;
export function defineConfig(config: PlaywrightTestConfig): PlaywrightTestConfig;
export function defineConfig<T>(config: PlaywrightTestConfig<T>): PlaywrightTestConfig<T>;
export function defineConfig<T, W>(config: PlaywrightTestConfig<T, W>): PlaywrightTestConfig<T, W>;
export function defineConfig(config: PlaywrightTestConfig, ...configs: PlaywrightTestConfig[]): PlaywrightTestConfig;
export function defineConfig<T>(config: PlaywrightTestConfig<T>, ...configs: PlaywrightTestConfig[]): PlaywrightTestConfig<T>;
export function defineConfig<T, W>(config: PlaywrightTestConfig<T, W>, ...configs: PlaywrightTestConfig[]): PlaywrightTestConfig<T, W>;
// This is required to not export everything by default. See https://github.com/Microsoft/TypeScript/issues/19545#issuecomment-340490459
export {};

View File

@ -17,7 +17,7 @@
import { config as loadEnv } from 'dotenv';
loadEnv({ path: path.join(__dirname, '..', '..', '.env'), override: true });
import type { Config, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription } from '@playwright/test';
import { type Config, type PlaywrightTestOptions, type PlaywrightWorkerOptions, type ReporterDescription } from '@playwright/test';
import * as path from 'path';
import type { TestModeWorkerOptions } from '../config/testModeFixtures';
import type { TestModeName } from '../config/testMode';

View File

@ -497,3 +497,60 @@ test('should not allow tracesDir in launchOptions', async ({ runTSC }) => {
});
expect(result.exitCode).not.toBe(0);
});
test('should merge configs', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': `
import { defineConfig, expect } from '@playwright/test';
const baseConfig = defineConfig({
timeout: 10,
use: {
foo: 1,
},
expect: {
timeout: 11,
},
projects: [
{
name: 'A',
timeout: 20,
}
],
});
const derivedConfig = defineConfig(baseConfig, {
timeout: 30,
use: {
bar: 2,
},
expect: {
timeout: 12,
},
projects: [
{ name: 'B', timeout: 40 },
{ name: 'A', timeout: 50 },
],
webServer: {
command: 'echo 123',
}
});
expect(derivedConfig).toEqual(expect.objectContaining({
timeout: 30,
use: { foo: 1, bar: 2 },
expect: { timeout: 12 },
projects: [
{ name: 'B', timeout: 40, use: {} },
{ name: 'A', timeout: 50, use: {} }
],
webServer: [{
command: 'echo 123',
}]
}));
`,
'a.test.ts': `
import { test } from '@playwright/test';
test('pass', async ({}) => {});
`
});
expect(result.exitCode).toBe(0);
});

View File

@ -400,6 +400,9 @@ export const expect: Expect;
export function defineConfig(config: PlaywrightTestConfig): PlaywrightTestConfig;
export function defineConfig<T>(config: PlaywrightTestConfig<T>): PlaywrightTestConfig<T>;
export function defineConfig<T, W>(config: PlaywrightTestConfig<T, W>): PlaywrightTestConfig<T, W>;
export function defineConfig(config: PlaywrightTestConfig, ...configs: PlaywrightTestConfig[]): PlaywrightTestConfig;
export function defineConfig<T>(config: PlaywrightTestConfig<T>, ...configs: PlaywrightTestConfig[]): PlaywrightTestConfig<T>;
export function defineConfig<T, W>(config: PlaywrightTestConfig<T, W>, ...configs: PlaywrightTestConfig[]): PlaywrightTestConfig<T, W>;
// This is required to not export everything by default. See https://github.com/Microsoft/TypeScript/issues/19545#issuecomment-340490459
export {};