diff --git a/packages/playwright/src/runner/rebase.ts b/packages/playwright/src/runner/rebase.ts index c76ce43420..c75a346550 100644 --- a/packages/playwright/src/runner/rebase.ts +++ b/packages/playwright/src/runner/rebase.ts @@ -20,6 +20,7 @@ import type { T } from '../transform/babelBundle'; import { types, traverse, babelParse } from '../transform/babelBundle'; import { MultiMap } from 'playwright-core/lib/utils'; import { generateUnifiedDiff } from 'playwright-core/lib/utils'; +import { colors } from 'playwright-core/lib/utilsBundle'; import type { FullConfigInternal } from '../common/config'; import { filterProjects } from './projectUtils'; const t: typeof T = types; @@ -45,11 +46,16 @@ export function addSuggestedRebaseline(location: Location, suggestedRebaseline: export async function applySuggestedRebaselines(config: FullConfigInternal) { if (config.config.updateSnapshots !== 'all' && config.config.updateSnapshots !== 'missing') return; + if (!suggestedRebaselines.size) + return; const [project] = filterProjects(config.projects, config.cliProjectFilter); if (!project) return; - for (const fileName of suggestedRebaselines.keys()) { + const patches: string[] = []; + const files: string[] = []; + + for (const fileName of [...suggestedRebaselines.keys()].sort()) { const source = await fs.promises.readFile(fileName, 'utf8'); const lines = source.split('\n'); const replacements = suggestedRebaselines.get(fileName); @@ -86,10 +92,16 @@ export async function applySuggestedRebaselines(config: FullConfigInternal) { for (const range of ranges) result = result.substring(0, range.start) + range.newText + result.substring(range.end); - const relativeName = path.relative(process.cwd(), fileName).replace(/\\/g, '/'); - - const patchFile = path.join(project.project.outputDir, 'rebaselines.patch'); - await fs.promises.mkdir(path.dirname(patchFile), { recursive: true }); - await fs.promises.writeFile(patchFile, generateUnifiedDiff(source, result, relativeName)); + const relativeName = path.relative(process.cwd(), fileName); + files.push(relativeName); + patches.push(generateUnifiedDiff(source, result, relativeName.replace(/\\/g, '/'))); } + + const patchFile = path.join(project.project.outputDir, 'rebaselines.patch'); + await fs.promises.mkdir(path.dirname(patchFile), { recursive: true }); + await fs.promises.writeFile(patchFile, patches.join('\n')); + + const fileList = files.map(file => ' ' + colors.dim(file)).join('\n'); + // eslint-disable-next-line no-console + console.log(`New baselines created for:\n\n${fileList}\n\n ` + colors.cyan('git apply ' + path.relative(process.cwd(), patchFile)) + '\n'); } diff --git a/tests/playwright-test/stable-test-runner/package-lock.json b/tests/playwright-test/stable-test-runner/package-lock.json index 2aefdb7d5f..17cc3a9635 100644 --- a/tests/playwright-test/stable-test-runner/package-lock.json +++ b/tests/playwright-test/stable-test-runner/package-lock.json @@ -5,15 +5,15 @@ "packages": { "": { "dependencies": { - "@playwright/test": "1.49.0-alpha-2024-10-29" + "@playwright/test": "1.49.0-alpha-2024-10-30" } }, "node_modules/@playwright/test": { - "version": "1.49.0-alpha-2024-10-29", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0-alpha-2024-10-29.tgz", - "integrity": "sha512-JyT6BHjuJl5Iv91PvaYa1RXRQfSwHk1Abq/hzYFpebQQuKKNr3pck55qmih39+S/bGsuYW6XdzqAX+CfknR3sA==", + "version": "1.49.0-alpha-2024-10-30", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0-alpha-2024-10-30.tgz", + "integrity": "sha512-7pq4a+eDCkp6VmGGpr6KanL0gQ2SunC9dAjtP+VZLobdaY0ZL7XkmD2rL8UNANF2AkmKdOf+GmTS+wZ42qhvLg==", "dependencies": { - "playwright": "1.49.0-alpha-2024-10-29" + "playwright": "1.49.0-alpha-2024-10-30" }, "bin": { "playwright": "cli.js" @@ -36,11 +36,11 @@ } }, "node_modules/playwright": { - "version": "1.49.0-alpha-2024-10-29", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0-alpha-2024-10-29.tgz", - "integrity": "sha512-ypwaWQwpxAiB5JEz4ACrztZsII4BdD5zOuAnjPtiXZtemSZNwxxY7phKlX8nLUlGwWDpb8aGe9tBcxoyrcFIww==", + "version": "1.49.0-alpha-2024-10-30", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0-alpha-2024-10-30.tgz", + "integrity": "sha512-OJ++0IaaTyBHZuPMi7kNZ/ssyRvN4Fkh7NCpYBRyfPL8H90bEVwDe7j4Ab79HMBLxUZMg7D7aRIlimmYmVdbpQ==", "dependencies": { - "playwright-core": "1.49.0-alpha-2024-10-29" + "playwright-core": "1.49.0-alpha-2024-10-30" }, "bin": { "playwright": "cli.js" @@ -53,9 +53,9 @@ } }, "node_modules/playwright-core": { - "version": "1.49.0-alpha-2024-10-29", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0-alpha-2024-10-29.tgz", - "integrity": "sha512-pJmBdOnVFzBzA6Jo1q7FtJferyLK0a2cNZGbuOMO0LOPWY7FOT91225TYZ9a1qgaYMav+uudmYw6im/qjEwmIQ==", + "version": "1.49.0-alpha-2024-10-30", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0-alpha-2024-10-30.tgz", + "integrity": "sha512-T1KDI5SQPqzVIahMOpCX7GE2Slv/5KEM+gSnj5mQZDi57Z8Ij5xnGz6ZX4KBdDrmkBRHLrRM4ijXfH1Q7zNkEg==", "bin": { "playwright-core": "cli.js" }, @@ -66,11 +66,11 @@ }, "dependencies": { "@playwright/test": { - "version": "1.49.0-alpha-2024-10-29", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0-alpha-2024-10-29.tgz", - "integrity": "sha512-JyT6BHjuJl5Iv91PvaYa1RXRQfSwHk1Abq/hzYFpebQQuKKNr3pck55qmih39+S/bGsuYW6XdzqAX+CfknR3sA==", + "version": "1.49.0-alpha-2024-10-30", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0-alpha-2024-10-30.tgz", + "integrity": "sha512-7pq4a+eDCkp6VmGGpr6KanL0gQ2SunC9dAjtP+VZLobdaY0ZL7XkmD2rL8UNANF2AkmKdOf+GmTS+wZ42qhvLg==", "requires": { - "playwright": "1.49.0-alpha-2024-10-29" + "playwright": "1.49.0-alpha-2024-10-30" } }, "fsevents": { @@ -80,18 +80,18 @@ "optional": true }, "playwright": { - "version": "1.49.0-alpha-2024-10-29", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0-alpha-2024-10-29.tgz", - "integrity": "sha512-ypwaWQwpxAiB5JEz4ACrztZsII4BdD5zOuAnjPtiXZtemSZNwxxY7phKlX8nLUlGwWDpb8aGe9tBcxoyrcFIww==", + "version": "1.49.0-alpha-2024-10-30", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0-alpha-2024-10-30.tgz", + "integrity": "sha512-OJ++0IaaTyBHZuPMi7kNZ/ssyRvN4Fkh7NCpYBRyfPL8H90bEVwDe7j4Ab79HMBLxUZMg7D7aRIlimmYmVdbpQ==", "requires": { "fsevents": "2.3.2", - "playwright-core": "1.49.0-alpha-2024-10-29" + "playwright-core": "1.49.0-alpha-2024-10-30" } }, "playwright-core": { - "version": "1.49.0-alpha-2024-10-29", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0-alpha-2024-10-29.tgz", - "integrity": "sha512-pJmBdOnVFzBzA6Jo1q7FtJferyLK0a2cNZGbuOMO0LOPWY7FOT91225TYZ9a1qgaYMav+uudmYw6im/qjEwmIQ==" + "version": "1.49.0-alpha-2024-10-30", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0-alpha-2024-10-30.tgz", + "integrity": "sha512-T1KDI5SQPqzVIahMOpCX7GE2Slv/5KEM+gSnj5mQZDi57Z8Ij5xnGz6ZX4KBdDrmkBRHLrRM4ijXfH1Q7zNkEg==" } } } diff --git a/tests/playwright-test/stable-test-runner/package.json b/tests/playwright-test/stable-test-runner/package.json index 2e185ba7e3..793663f7d5 100644 --- a/tests/playwright-test/stable-test-runner/package.json +++ b/tests/playwright-test/stable-test-runner/package.json @@ -1,6 +1,6 @@ { "private": true, "dependencies": { - "@playwright/test": "1.49.0-alpha-2024-10-29" + "@playwright/test": "1.49.0-alpha-2024-10-30" } } diff --git a/tests/playwright-test/update-aria-snapshot.spec.ts b/tests/playwright-test/update-aria-snapshot.spec.ts index 8721bebcc9..5bc1d28544 100644 --- a/tests/playwright-test/update-aria-snapshot.spec.ts +++ b/tests/playwright-test/update-aria-snapshot.spec.ts @@ -204,3 +204,65 @@ test('should update missing snapshots in tsx', async ({ runInlineTest }, testInf `); }); + +test('should update multiple files', async ({ runInlineTest }, testInfo) => { + const result = await runInlineTest({ + 'playwright.config.ts': playwrightCtConfigText, + 'playwright/index.html': ``, + 'playwright/index.ts': ``, + + 'src/button.tsx': ` + export const Button = () => ; + `, + + 'src/button-1.test.tsx': ` + import { test, expect } from '@playwright/experimental-ct-react'; + import { Button } from './button.tsx'; + + test('pass 1', async ({ mount }) => { + const component = await mount(); + await expect(component).toMatchAriaSnapshot(\`\`); + }); + `, + + 'src/button-2.test.tsx': ` + import { test, expect } from '@playwright/experimental-ct-react'; + import { Button } from './button.tsx'; + + test('pass 2', async ({ mount }) => { + const component = await mount(); + await expect(component).toMatchAriaSnapshot(\`\`); + }); + `, + }); + + expect(result.exitCode).toBe(0); + const patchPath = testInfo.outputPath('test-results/rebaselines.patch'); + const data = fs.readFileSync(patchPath, 'utf-8'); + expect(data).toBe(`--- a/src/button-1.test.tsx ++++ b/src/button-1.test.tsx +@@ -4,6 +4,8 @@ + + test('pass 1', async ({ mount }) => { + const component = await mount(); +- await expect(component).toMatchAriaSnapshot(\`\`); ++ await expect(component).toMatchAriaSnapshot(\` ++ - button \"Button\" ++ \`); + }); + + +--- a/src/button-2.test.tsx ++++ b/src/button-2.test.tsx +@@ -4,6 +4,8 @@ + + test('pass 2', async ({ mount }) => { + const component = await mount(); +- await expect(component).toMatchAriaSnapshot(\`\`); ++ await expect(component).toMatchAriaSnapshot(\` ++ - button \"Button\" ++ \`); + }); + +`); +});