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:
Dmitry Gozman 2024-10-10 01:37:46 -07:00 коммит произвёл GitHub
Родитель 8f3353865d
Коммит 25dd9b5cd4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 109 добавлений и 0 удалений

Просмотреть файл

@ -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
* since: v1.10
- 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
```
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
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 plugins: TestRunnerPluginRegistration[];
readonly projects: FullProjectInternal[] = [];
readonly singleTSConfigPath?: string;
cliArgs: string[] = [];
cliGrep: string | undefined;
cliGrepInvert: string | undefined;
@ -69,6 +70,7 @@ export class FullConfigInternal {
this.configCLIOverrides = configCLIOverrides;
const privateConfiguration = (userConfig as any)['@playwright/test'];
this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p }));
this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
this.config = {
configFile: resolvedConfigFile,

Просмотреть файл

@ -118,6 +118,8 @@ export async function loadConfig(location: ConfigLocation, overrides?: ConfigCLI
const babelPlugins = (userConfig as any)['@playwright/test']?.babelPlugins || [];
const external = userConfig.build?.external || [];
setTransformConfig({ babelPlugins, external });
if (!overrides?.tsconfig)
setSingleTSConfig(fullConfig?.singleTSConfigPath);
// 4. Send transform options to ESM loader.
await configureESMLoaderTransformConfig();

Просмотреть файл

@ -77,5 +77,6 @@ export async function configureESMLoader() {
export async function configureESMLoaderTransformConfig() {
if (!loaderChannel)
return;
await loaderChannel.send('setSingleTSConfig', { tsconfig: singleTSConfig() });
await loaderChannel.send('setTransformConfig', { config: transformConfig() });
}

19
packages/playwright/types/test.d.ts поставляемый
Просмотреть файл

@ -1642,6 +1642,25 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
*/
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'`.
* - `'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`);
});
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('should resolve index.js without path mapping in CJS', async ({ runInlineTest, runTSC }) => {
const files = {