diff --git a/packages/playwright/src/transform/transform.ts b/packages/playwright/src/transform/transform.ts index 30d9be038f..e011e7fb2d 100644 --- a/packages/playwright/src/transform/transform.ts +++ b/packages/playwright/src/transform/transform.ts @@ -58,11 +58,14 @@ export function transformConfig(): TransformConfig { } function validateTsConfig(tsconfig: TsConfigLoaderResult): ParsedTsConfigData | undefined { - if (!tsconfig.tsConfigPath || !tsconfig.baseUrl) + if (!tsconfig.tsConfigPath) return; // Make 'baseUrl' absolute, because it is relative to the tsconfig.json, not to cwd. - const absoluteBaseUrl = path.resolve(path.dirname(tsconfig.tsConfigPath), tsconfig.baseUrl); - const pathsFallback = [{ key: '*', values: ['*'] }]; + // When no explicit baseUrl is set, resolve paths relative to the tsconfig file. + // See https://www.typescriptlang.org/tsconfig#paths + const absoluteBaseUrl = path.resolve(path.dirname(tsconfig.tsConfigPath), tsconfig.baseUrl ?? '.'); + // Only add the catch-all mapping when baseUrl is specified + const pathsFallback = tsconfig.baseUrl ? [{ key: '*', values: ['*'] }] : []; return { allowJs: tsconfig.allowJs, absoluteBaseUrl, diff --git a/tests/playwright-test/resolver.spec.ts b/tests/playwright-test/resolver.spec.ts index 56b3da0a56..f0e95e91ca 100644 --- a/tests/playwright-test/resolver.spec.ts +++ b/tests/playwright-test/resolver.spec.ts @@ -201,6 +201,34 @@ test('should fallback to *:* when baseurl and paths are specified', async ({ run expect(result.output).not.toContain(`Could not`); }); +test('should use the location of the tsconfig as the paths root when no baseUrl is specified', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'foo/bar/util/b.ts': ` + export const foo = 42; + `, + 'dir2/tsconfig.json': `{ + "compilerOptions": { + "target": "ES2019", + "module": "commonjs", + "lib": ["esnext", "dom", "DOM.Iterable"], + "paths": {"foo/*": ["../foo/*"]}, + }, + }`, + 'dir2/inner.spec.ts': ` + // This import should pick up ../foo/bar/util/b due to paths. + import { foo } from 'foo/bar/util/b'; + import { test, expect } from '@playwright/test'; + test('test', ({}, testInfo) => { + expect(foo).toBe(42); + }); + `, + }); + + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); + expect(result.output).not.toContain(`Could not`); +}); + test('should respect complex path resolver', async ({ runInlineTest }) => { const result = await runInlineTest({ 'playwright.config.ts': `