From 4469e5769592193654a18011595bc111923470f8 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 9 Feb 2023 18:39:20 -0800 Subject: [PATCH] chore: always grow component bundle (#20799) Fixes https://github.com/microsoft/playwright/issues/20581 --- .../playwright-test/src/plugins/vitePlugin.ts | 18 +++--- .../playwright.ct-build.spec.ts | 61 +++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/packages/playwright-test/src/plugins/vitePlugin.ts b/packages/playwright-test/src/plugins/vitePlugin.ts index ed5e3c658627a..0d37b1efe92ae 100644 --- a/packages/playwright-test/src/plugins/vitePlugin.ts +++ b/packages/playwright-test/src/plugins/vitePlugin.ts @@ -97,6 +97,8 @@ export function createPlugin( const hasNewComponents = await checkNewComponents(buildInfo, componentRegistry); // 3. Check component sources. const sourcesDirty = !buildExists || hasNewComponents || await checkSources(buildInfo); + // 4. Update component info. + buildInfo.components = [...componentRegistry.values()]; viteConfig.root = rootDir; viteConfig.preview = { port, ...viteConfig.preview }; @@ -218,12 +220,6 @@ async function checkNewTests(suite: Suite, buildInfo: BuildInfo, componentRegist componentRegistry.set(component.fullName, component); buildInfo.tests[testFile] = { timestamp, components: components.map(c => c.fullName) }; hasNewTests = true; - } else { - // The test has not changed, populate component registry from the buildInfo. - for (const componentName of buildInfo.tests[testFile].components) { - const component = buildInfo.components.find(c => c.fullName === componentName)!; - componentRegistry.set(component.fullName, component); - } } } @@ -232,7 +228,7 @@ async function checkNewTests(suite: Suite, buildInfo: BuildInfo, componentRegist async function checkNewComponents(buildInfo: BuildInfo, componentRegistry: ComponentRegistry): Promise { const newComponents = [...componentRegistry.keys()]; - const oldComponents = new Set(buildInfo.components.map(c => c.fullName)); + const oldComponents = new Map(buildInfo.components.map(c => [c.fullName, c])); let hasNewComponents = false; for (const c of newComponents) { @@ -241,10 +237,10 @@ async function checkNewComponents(buildInfo: BuildInfo, componentRegistry: Compo break; } } - if (!hasNewComponents) - return false; - buildInfo.components = newComponents.map(n => componentRegistry.get(n)!); - return true; + for (const c of oldComponents.values()) + componentRegistry.set(c.fullName, c); + + return hasNewComponents; } async function parseTestFile(testFile: string): Promise { diff --git a/tests/playwright-test/playwright.ct-build.spec.ts b/tests/playwright-test/playwright.ct-build.spec.ts index a15f42c7faa64..1a4a326c4472c 100644 --- a/tests/playwright-test/playwright.ct-build.spec.ts +++ b/tests/playwright-test/playwright.ct-build.spec.ts @@ -283,6 +283,67 @@ test('should cache build', async ({ runInlineTest }, testInfo) => { }); }); +test('should grow cache', async ({ runInlineTest }, testInfo) => { + test.slow(); + + await test.step('original test', async () => { + const result = await runInlineTest({ + 'playwright.config.ts': playwrightConfig, + 'playwright/index.html': ``, + 'playwright/index.ts': ``, + 'src/button1.tsx': ` + export const Button1 = () => ; + `, + 'src/button2.tsx': ` + export const Button2 = () => ; + `, + 'src/button1.test.tsx': ` + //@no-header + import { test, expect } from '@playwright/experimental-ct-react'; + import { Button1 } from './button1.tsx'; + test('pass', async ({ mount }) => { + const component = await mount(); + await expect(component).toHaveText('Button 1'); + }); + `, + 'src/button2.test.tsx': ` + //@no-header + import { test, expect } from '@playwright/experimental-ct-react'; + import { Button2 } from './button2.tsx'; + test('pass', async ({ mount }) => { + const component = await mount(); + await expect(component).toHaveText('Button 2'); + }); + `, + }, { workers: 1 }, undefined, { additionalArgs: ['button1'] }); + + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); + const output = result.output; + expect(output).toContain('modules transformed'); + }); + + await test.step('run second test', async () => { + const result = await runInlineTest({ + 'playwright.config.ts': playwrightConfig, + }, { workers: 1 }, undefined, { additionalArgs: ['button2'] }); + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); + const output = result.output; + expect(output).toContain('modules transformed'); + }); + + await test.step('run first test again', async () => { + const result = await runInlineTest({ + 'playwright.config.ts': playwrightConfig, + }, { workers: 1 }, undefined, { additionalArgs: ['button2'] }); + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); + const output = result.output; + expect(output).not.toContain('modules transformed'); + }); +}); + test('should not use global config for preview', async ({ runInlineTest }) => { const result1 = await runInlineTest({ 'playwright.config.ts': playwrightConfig,