Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/test-typescript-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ npx tsc -p tsconfig.json --noEmit -w

## tsconfig.json

Playwright will pick up `tsconfig.json` for each source file it loads. Note that Playwright **only supports** the following tsconfig options: `allowJs`, `baseUrl`, `paths` and `references`.
Playwright will pick up `tsconfig.json` for each source file it loads. Note that Playwright **only supports** the following tsconfig options: `allowJs`, `baseUrl`, `paths`, `references` and `extends`.

We recommend setting up a separate `tsconfig.json` in the tests directory so that you can change some preferences specifically for the tests. Here is an example directory structure.

Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/browsers.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
},
{
"name": "webkit",
"revision": "2319",
"revision": "2321",
"installByDefault": true,
"revisionOverrides": {
"mac14": "2251",
Expand Down
8 changes: 4 additions & 4 deletions packages/playwright/src/common/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import util from 'util';
import { serializeCompilationCache } from '../transform/compilationCache';

import type { ConfigLocation, FullConfigInternal } from './config';
import type { ReporterDescription, TestInfoError, TestStatus } from '../../types/test';
import type { ReporterDescription, TestInfoError, TestStatus, TestAnnotation } from '../../types/test';
import type { SerializedCompilationCache } from '../transform/compilationCache';

export type ConfigCLIOverrides = {
Expand Down Expand Up @@ -116,7 +116,7 @@ export type TestEndPayload = {
errors: TestInfoErrorPayload[];
hasNonRetriableError: boolean;
expectedStatus: TestStatus;
annotations: { type: string, description?: string }[];
annotations: TestAnnotation[];
timeout: number;
};

Expand All @@ -136,13 +136,13 @@ export type StepEndPayload = {
wallTime: number; // milliseconds since unix epoch
error?: TestInfoErrorPayload;
suggestedRebaseline?: string;
annotations: { type: string, description?: string }[];
annotations: TestAnnotation[];
};

export type TestEntry = {
testId: string;
retry: number;
planAnnotations: { type: string, description?: string, location?: { file: string, line: number, column: number } }[];
planAnnotations: TestAnnotation[];
};

export type RunPayload = {
Expand Down
9 changes: 6 additions & 3 deletions packages/playwright/src/transform/tsconfig-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,17 @@ export function loadTsConfig(configPath: string): LoadedTsConfig[] {
}
}

function resolveConfigFile(baseConfigFile: string, referencedConfigFile: string) {
function resolveConfigFile(baseConfigFile: string, referencedConfigFile: string, kind: 'extends' | 'references') {
const originalReferencedConfigFile = referencedConfigFile;
if (!referencedConfigFile.endsWith('.json'))
referencedConfigFile += '.json';
const currentDir = path.dirname(baseConfigFile);
let resolvedConfigFile = path.resolve(currentDir, referencedConfigFile);
// TODO: I don't see how this makes sense, delete in the next minor release.
if (referencedConfigFile.includes('/') && referencedConfigFile.includes('.') && !fs.existsSync(resolvedConfigFile))
resolvedConfigFile = path.join(currentDir, 'node_modules', referencedConfigFile);
if (!fs.existsSync(resolvedConfigFile))
throw new Error(`Failed to resolve "${kind}" path "${originalReferencedConfigFile}" referenced from ${baseConfigFile}`);
return resolvedConfigFile;
}

Expand All @@ -95,7 +98,7 @@ function innerLoadTsConfig(

const extendsArray = Array.isArray(parsedConfig.extends) ? parsedConfig.extends : (parsedConfig.extends ? [parsedConfig.extends] : []);
for (const extendedConfig of extendsArray) {
const extendedConfigPath = resolveConfigFile(configFilePath, extendedConfig);
const extendedConfigPath = resolveConfigFile(configFilePath, extendedConfig, 'extends');
const base = innerLoadTsConfig(extendedConfigPath, references, visited);
// Retain result instance, so that caching works.
Object.assign(result, base, { tsConfigPath: configFilePath });
Expand All @@ -120,7 +123,7 @@ function innerLoadTsConfig(
}

for (const ref of parsedConfig.references || [])
references.push(innerLoadTsConfig(resolveConfigFile(configFilePath, ref.path), references, visited));
references.push(innerLoadTsConfig(resolveConfigFile(configFilePath, ref.path, 'references'), references, visited));

if (path.basename(configFilePath) === 'jsconfig.json' && result.allowJs === undefined)
result.allowJs = true;
Expand Down
6 changes: 3 additions & 3 deletions packages/playwright/types/testReporter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location, WorkerInfo } from './test';
import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location, WorkerInfo, TestAnnotation } from './test';
export type { FullConfig, FullProject, TestStatus, Location, WorkerInfo } from './test';

/**
Expand Down Expand Up @@ -300,7 +300,7 @@ export interface JSONReportSpec {

export interface JSONReportTest {
timeout: number;
annotations: { type: string, description?: string }[],
annotations: TestAnnotation[],
expectedStatus: TestStatus;
projectName: string;
projectId: string;
Expand Down Expand Up @@ -332,7 +332,7 @@ export interface JSONReportTestResult {
body?: string;
contentType: string;
}[];
annotations: { type: string, description?: string }[];
annotations: TestAnnotation[];
errorLocation?: Location;
}

Expand Down
40 changes: 40 additions & 0 deletions tests/playwright-test/resolver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,43 @@ test('should resolve paths relative to the originating config when extending and
expect(result.exitCode).toBe(0);
});

test('should fail loudly when extends path cannot be resolved', async ({ runInlineTest }) => {
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/41543' });

const result = await runInlineTest({
'tsconfig.json': `{
"extends": "./tsconfig.bas.json",
}`,
'a.test.ts': `
import { test, expect } from '@playwright/test';
test('test', () => {});
`,
});

expect(result.exitCode).toBe(1);
expect(result.output).toContain('Failed to resolve "extends" path "./tsconfig.bas.json"');
});

test('should fail loudly when references path cannot be resolved', async ({ runInlineTest }) => {
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/41543' });

const result = await runInlineTest({
'tsconfig.json': `{
"files": [],
"references": [
{ "path": "./tsconfig.doesnotexist.json" }
]
}`,
'a.test.ts': `
import { test, expect } from '@playwright/test';
test('test', () => {});
`,
});

expect(result.exitCode).toBe(1);
expect(result.output).toContain('Failed to resolve "references" path "./tsconfig.doesnotexist.json"');
});

test('should respect tsconfig project references', async ({ runInlineTest }) => {
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29256' });

Expand All @@ -599,6 +636,9 @@ test('should respect tsconfig project references', async ({ runInlineTest }) =>
{ "path": "./tsconfig.test.json" }
]
}`,
'tsconfig.app.json': `{
"compilerOptions": {},
}`,
'tsconfig.test.json': `{
"compilerOptions": {
"baseUrl": ".",
Expand Down
6 changes: 3 additions & 3 deletions utils/generate_types/overrides-testReporter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location, WorkerInfo } from './test';
import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location, WorkerInfo, TestAnnotation } from './test';
export type { FullConfig, FullProject, TestStatus, Location, WorkerInfo } from './test';

/**
Expand Down Expand Up @@ -95,7 +95,7 @@ export interface JSONReportSpec {

export interface JSONReportTest {
timeout: number;
annotations: { type: string, description?: string }[],
annotations: TestAnnotation[],
expectedStatus: TestStatus;
projectName: string;
projectId: string;
Expand Down Expand Up @@ -127,7 +127,7 @@ export interface JSONReportTestResult {
body?: string;
contentType: string;
}[];
annotations: { type: string, description?: string }[];
annotations: TestAnnotation[];
errorLocation?: Location;
}

Expand Down
Loading