feat: config.build.tsconfig (#33026)
Allows to specify `tsconfig` in the configuration file, which applies to test files but not the config file itself. Fixes #32808.
This commit is contained in:
parent
8f3353865d
commit
25dd9b5cd4
|
|
@ -552,6 +552,22 @@ export default defineConfig({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## property: TestConfig.tsconfig
|
||||||
|
* since: v1.49
|
||||||
|
- type: ?<[string]>
|
||||||
|
|
||||||
|
Path to a single `tsconfig` applicable to all imported files. By default, `tsconfig` for each imported file is looked up separately. Note that `tsconfig` property has no effect while the configuration file or any of its dependencies are loaded. Ignored when `--tsconfig` command line option is specified.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
|
||||||
|
```js title="playwright.config.ts"
|
||||||
|
import { defineConfig } from '@playwright/test';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
tsconfig: './tsconfig.test.json',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
## property: TestConfig.updateSnapshots
|
## property: TestConfig.updateSnapshots
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
- type: ?<[UpdateSnapshots]<"all"|"none"|"missing">>
|
- type: ?<[UpdateSnapshots]<"all"|"none"|"missing">>
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,16 @@ Alternatively, you can specify a single tsconfig file to use in the command line
|
||||||
npx playwright test --tsconfig=tsconfig.test.json
|
npx playwright test --tsconfig=tsconfig.test.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can specify a single tsconfig file in the config file, that will be used for loading test files, reporters, etc. However, it will not be used while loading the playwright config itself or any files imported from it.
|
||||||
|
|
||||||
|
```js title="playwright.config.ts"
|
||||||
|
import { defineConfig } from '@playwright/test';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
tsconfig: './tsconfig.test.json',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
## Manually compile tests with TypeScript
|
## Manually compile tests with TypeScript
|
||||||
|
|
||||||
Sometimes, Playwright Test will not be able to transform your TypeScript code correctly, for example when you are using experimental or very recent features of TypeScript, usually configured in `tsconfig.json`.
|
Sometimes, Playwright Test will not be able to transform your TypeScript code correctly, for example when you are using experimental or very recent features of TypeScript, usually configured in `tsconfig.json`.
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ export class FullConfigInternal {
|
||||||
readonly webServers: NonNullable<FullConfig['webServer']>[];
|
readonly webServers: NonNullable<FullConfig['webServer']>[];
|
||||||
readonly plugins: TestRunnerPluginRegistration[];
|
readonly plugins: TestRunnerPluginRegistration[];
|
||||||
readonly projects: FullProjectInternal[] = [];
|
readonly projects: FullProjectInternal[] = [];
|
||||||
|
readonly singleTSConfigPath?: string;
|
||||||
cliArgs: string[] = [];
|
cliArgs: string[] = [];
|
||||||
cliGrep: string | undefined;
|
cliGrep: string | undefined;
|
||||||
cliGrepInvert: string | undefined;
|
cliGrepInvert: string | undefined;
|
||||||
|
|
@ -69,6 +70,7 @@ export class FullConfigInternal {
|
||||||
this.configCLIOverrides = configCLIOverrides;
|
this.configCLIOverrides = configCLIOverrides;
|
||||||
const privateConfiguration = (userConfig as any)['@playwright/test'];
|
const privateConfiguration = (userConfig as any)['@playwright/test'];
|
||||||
this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p }));
|
this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p }));
|
||||||
|
this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
|
||||||
|
|
||||||
this.config = {
|
this.config = {
|
||||||
configFile: resolvedConfigFile,
|
configFile: resolvedConfigFile,
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,8 @@ export async function loadConfig(location: ConfigLocation, overrides?: ConfigCLI
|
||||||
const babelPlugins = (userConfig as any)['@playwright/test']?.babelPlugins || [];
|
const babelPlugins = (userConfig as any)['@playwright/test']?.babelPlugins || [];
|
||||||
const external = userConfig.build?.external || [];
|
const external = userConfig.build?.external || [];
|
||||||
setTransformConfig({ babelPlugins, external });
|
setTransformConfig({ babelPlugins, external });
|
||||||
|
if (!overrides?.tsconfig)
|
||||||
|
setSingleTSConfig(fullConfig?.singleTSConfigPath);
|
||||||
|
|
||||||
// 4. Send transform options to ESM loader.
|
// 4. Send transform options to ESM loader.
|
||||||
await configureESMLoaderTransformConfig();
|
await configureESMLoaderTransformConfig();
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,6 @@ export async function configureESMLoader() {
|
||||||
export async function configureESMLoaderTransformConfig() {
|
export async function configureESMLoaderTransformConfig() {
|
||||||
if (!loaderChannel)
|
if (!loaderChannel)
|
||||||
return;
|
return;
|
||||||
|
await loaderChannel.send('setSingleTSConfig', { tsconfig: singleTSConfig() });
|
||||||
await loaderChannel.send('setTransformConfig', { config: transformConfig() });
|
await loaderChannel.send('setTransformConfig', { config: transformConfig() });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
packages/playwright/types/test.d.ts
vendored
19
packages/playwright/types/test.d.ts
vendored
|
|
@ -1642,6 +1642,25 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
|
||||||
*/
|
*/
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to a single `tsconfig` applicable to all imported files. By default, `tsconfig` for each imported file is
|
||||||
|
* looked up separately. Note that `tsconfig` property has no effect while the configuration file or any of its
|
||||||
|
* dependencies are loaded. Ignored when `--tsconfig` command line option is specified.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* // playwright.config.ts
|
||||||
|
* import { defineConfig } from '@playwright/test';
|
||||||
|
*
|
||||||
|
* export default defineConfig({
|
||||||
|
* tsconfig: './tsconfig.test.json',
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
tsconfig?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to update expected snapshots with the actual results produced by the test run. Defaults to `'missing'`.
|
* Whether to update expected snapshots with the actual results produced by the test run. Defaults to `'missing'`.
|
||||||
* - `'all'` - All tests that are executed will update snapshots that did not match. Matching snapshots will not be
|
* - `'all'` - All tests that are executed will update snapshots that did not match. Matching snapshots will not be
|
||||||
|
|
|
||||||
|
|
@ -675,6 +675,65 @@ test('should respect --tsconfig option', async ({ runInlineTest }) => {
|
||||||
expect(result.output).not.toContain(`Could not`);
|
expect(result.output).not.toContain(`Could not`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should respect config.tsconfig option', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'playwright.config.ts': `
|
||||||
|
export { configFoo } from '~/foo';
|
||||||
|
export default {
|
||||||
|
testDir: './tests',
|
||||||
|
tsconfig: './tsconfig.tests.json',
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
'tsconfig.json': `{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./mapped-from-config/*"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}`,
|
||||||
|
'mapped-from-config/foo.ts': `
|
||||||
|
export const configFoo = 17;
|
||||||
|
`,
|
||||||
|
'tsconfig.tests.json': `{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./mapped-from-tests/*"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}`,
|
||||||
|
'mapped-from-tests/foo.ts': `
|
||||||
|
export const testFoo = 42;
|
||||||
|
`,
|
||||||
|
'tests/tsconfig.json': `{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["../should-be-ignored/*"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}`,
|
||||||
|
'tests/a.test.ts': `
|
||||||
|
import { testFoo } from '~/foo';
|
||||||
|
import { configFoo } from '../playwright.config';
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('test', ({}) => {
|
||||||
|
expect(testFoo).toBe(42);
|
||||||
|
expect(configFoo).toBe(17);
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
'should-be-ignored/foo.ts': `
|
||||||
|
export const testFoo = 43;
|
||||||
|
export const configFoo = 18;
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.passed).toBe(1);
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.output).not.toContain(`Could not`);
|
||||||
|
});
|
||||||
|
|
||||||
test.describe('directory imports', () => {
|
test.describe('directory imports', () => {
|
||||||
test('should resolve index.js without path mapping in CJS', async ({ runInlineTest, runTSC }) => {
|
test('should resolve index.js without path mapping in CJS', async ({ runInlineTest, runTSC }) => {
|
||||||
const files = {
|
const files = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue