From 3917f5e842ce57e1221c1847e823a412e28aef64 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Tue, 24 Sep 2024 16:18:44 -0700 Subject: [PATCH] fix(ui-mode): respec --tsconfig option Fixes https://github.com/microsoft/playwright/issues/32797 --- .../src/server/trace/viewer/traceViewer.ts | 3 + .../src/isomorphic/testServerInterface.ts | 4 +- packages/playwright/src/program.ts | 1 + packages/playwright/src/runner/testServer.ts | 3 + packages/trace-viewer/src/ui/uiModeView.tsx | 7 ++- .../playwright-test/ui-mode-test-run.spec.ts | 57 +++++++++++++++++++ 6 files changed, 72 insertions(+), 3 deletions(-) diff --git a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts index ee2ccac593..716d0beda7 100644 --- a/packages/playwright-core/src/server/trace/viewer/traceViewer.ts +++ b/packages/playwright-core/src/server/trace/viewer/traceViewer.ts @@ -48,6 +48,7 @@ export type TraceViewerRedirectOptions = { isServer?: boolean; outputDir?: string; updateSnapshots?: 'all' | 'none' | 'missing'; + tsconfig?: string; }; export type TraceViewerAppOptions = { @@ -137,6 +138,8 @@ export async function installRootRedirect(server: HttpServer, traceUrls: string[ params.append('outputDir', options.outputDir); if (options.updateSnapshots) params.append('updateSnapshots', options.updateSnapshots); + if (options.tsconfig) + params.append('tsconfig', options.tsconfig); for (const reporter of options.reporter || []) params.append('reporter', reporter); diff --git a/packages/playwright/src/isomorphic/testServerInterface.ts b/packages/playwright/src/isomorphic/testServerInterface.ts index 22cb9e35ef..ac98f8496f 100644 --- a/packages/playwright/src/isomorphic/testServerInterface.ts +++ b/packages/playwright/src/isomorphic/testServerInterface.ts @@ -45,7 +45,7 @@ export interface TestServerInterface { installBrowsers(params: {}): Promise; - runGlobalSetup(params: { outputDir?: string }): Promise<{ + runGlobalSetup(params: { outputDir?: string, tsconfig?: string }): Promise<{ report: ReportEntry[], status: reporterTypes.FullResult['status'] }>; @@ -83,6 +83,7 @@ export interface TestServerInterface { grep?: string; grepInvert?: string; outputDir?: string; + tsconfig?: string; }): Promise<{ report: ReportEntry[], status: reporterTypes.FullResult['status'] @@ -98,6 +99,7 @@ export interface TestServerInterface { timeout?: number, outputDir?: string; updateSnapshots?: 'all' | 'none' | 'missing'; + tsconfig?: string; reporters?: string[], trace?: 'on' | 'off'; video?: 'on' | 'off'; diff --git a/packages/playwright/src/program.ts b/packages/playwright/src/program.ts index 775ef27065..0cc12580dd 100644 --- a/packages/playwright/src/program.ts +++ b/packages/playwright/src/program.ts @@ -174,6 +174,7 @@ async function runTests(args: string[], opts: { [key: string]: any }) { timeout: cliOverrides.timeout, outputDir: cliOverrides.outputDir, updateSnapshots: cliOverrides.updateSnapshots, + tsconfig: cliOverrides.tsconfig, }); await stopProfiling('runner'); if (status === 'restarted') diff --git a/packages/playwright/src/runner/testServer.ts b/packages/playwright/src/runner/testServer.ts index d4433b2d85..675c836088 100644 --- a/packages/playwright/src/runner/testServer.ts +++ b/packages/playwright/src/runner/testServer.ts @@ -147,6 +147,7 @@ export class TestServerDispatcher implements TestServerInterface { const overrides: ConfigCLIOverrides = { outputDir: params.outputDir, + tsconfig: params.tsconfig, }; const { reporter, report } = await this._collectingInternalReporter(new ListReporter()); const config = await this._loadConfigOrReportError(reporter, overrides); @@ -242,6 +243,7 @@ export class TestServerDispatcher implements TestServerInterface { repeatEach: 1, retries: 0, outputDir: params.outputDir, + tsconfig: params.tsconfig, }; const { reporter, report } = await this._collectingInternalReporter(); const config = await this._loadConfigOrReportError(reporter, overrides); @@ -308,6 +310,7 @@ export class TestServerDispatcher implements TestServerInterface { _optionConnectOptions: params.connectWsEndpoint ? { wsEndpoint: params.connectWsEndpoint } : undefined, }, outputDir: params.outputDir, + tsconfig: params.tsconfig, updateSnapshots: params.updateSnapshots, workers: params.workers, }; diff --git a/packages/trace-viewer/src/ui/uiModeView.tsx b/packages/trace-viewer/src/ui/uiModeView.tsx index ba74e60092..bc039e1b93 100644 --- a/packages/trace-viewer/src/ui/uiModeView.tsx +++ b/packages/trace-viewer/src/ui/uiModeView.tsx @@ -62,6 +62,7 @@ const queryParams = { updateSnapshots: (searchParams.get('updateSnapshots') as 'all' | 'none' | 'missing' | undefined) || undefined, reporters: searchParams.has('reporter') ? searchParams.getAll('reporter') : undefined, pathSeparator: searchParams.get('pathSeparator') || '/', + tsconfig: searchParams.get('tsconfig') || undefined, }; if (queryParams.updateSnapshots && !['all', 'none', 'missing'].includes(queryParams.updateSnapshots)) queryParams.updateSnapshots = undefined; @@ -189,12 +190,13 @@ export const UIModeView: React.FC<{}> = ({ }); const { status, report } = await testServerConnection.runGlobalSetup({ outputDir: queryParams.outputDir, + tsconfig: queryParams.tsconfig, }); teleSuiteUpdater.processGlobalReport(report); if (status !== 'passed') return; - const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert, outputDir: queryParams.outputDir }); + const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert, outputDir: queryParams.outputDir, tsconfig: queryParams.tsconfig }); teleSuiteUpdater.processListReport(result.report); testServerConnection.onReport(params => { @@ -300,6 +302,7 @@ export const UIModeView: React.FC<{}> = ({ updateSnapshots: updateSnapshots ? 'all' : queryParams.updateSnapshots, reporters: queryParams.reporters, trace: 'on', + tsconfig: queryParams.tsconfig, }); // Clear pending tests in case of interrupt. for (const test of testModel.rootSuite?.allTests() || []) { @@ -319,7 +322,7 @@ export const UIModeView: React.FC<{}> = ({ commandQueue.current = commandQueue.current.then(async () => { setIsLoading(true); try { - const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert, outputDir: queryParams.outputDir }); + const result = await testServerConnection.listTests({ projects: queryParams.projects, locations: queryParams.args, grep: queryParams.grep, grepInvert: queryParams.grepInvert, outputDir: queryParams.outputDir, tsconfig: queryParams.tsconfig }); teleSuiteUpdater.processListReport(result.report); } catch (e) { // eslint-disable-next-line no-console diff --git a/tests/playwright-test/ui-mode-test-run.spec.ts b/tests/playwright-test/ui-mode-test-run.spec.ts index 9c1120ea04..e97126792a 100644 --- a/tests/playwright-test/ui-mode-test-run.spec.ts +++ b/tests/playwright-test/ui-mode-test-run.spec.ts @@ -444,3 +444,60 @@ test('should show proper total when using deps', async ({ runUITest }) => { `); await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)'); }); + +test('should respect --tsconfig option', async ({ runUITest }) => { + const { page } = await runUITest({ + 'playwright.config.ts': ` + import { foo } from '~/foo'; + export default { + testDir: './tests' + foo, + }; + `, + 'tsconfig.json': `{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "~/*": ["./does-not-exist/*"], + }, + }, + }`, + 'tsconfig.special.json': `{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "~/*": ["./mapped-from-root/*"], + }, + }, + }`, + 'mapped-from-root/foo.ts': ` + export const foo = 42; + `, + 'tests42/tsconfig.json': `{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "~/*": ["../should-be-ignored/*"], + }, + }, + }`, + 'tests42/a.test.ts': ` + import { foo } from '~/foo'; + import { test, expect } from '@playwright/test'; + test('test', ({}) => { + expect(foo).toBe(42); + }); + `, + 'should-be-ignored/foo.ts': ` + export const foo = 43; + `, + }, undefined, { additionalArgs: ['--tsconfig=tsconfig.special.json'] }); + + await page.getByTitle('Run all').click(); + + await expect.poll(dumpTestTree(page)).toBe(` + ▼ ✅ a.test.ts + ✅ test + `); + + await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); +}); \ No newline at end of file