diff --git a/.changeset/slimy-cups-protect.md b/.changeset/slimy-cups-protect.md new file mode 100644 index 00000000..c72ca495 --- /dev/null +++ b/.changeset/slimy-cups-protect.md @@ -0,0 +1,7 @@ +--- +'@chromatic-com/playwright': patch +'@chromatic-com/cypress': patch +--- + +- Use the configured `downloadsFolder` in Cypress as the output dir for archives +- Move Playwright-related path logic out of the shared package into the Playwright package diff --git a/.gitignore b/.gitignore index e8e3064e..5a91a658 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ test-archives **/playwright/.cache/ packages/playwright/test-results/ packages/cypress/tests/cypress/downloads/ +packages/cypress/tests/cypress/test-downloads/ packages/*/coverage/ diff --git a/package.json b/package.json index 1cb36ac8..5b37dc90 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "scripts": { "archive-storybook:playwright": "CHROMATIC_ARCHIVE_LOCATION=packages/playwright/test-results packages/playwright/dist/bin/archive-storybook.js", "build-archive-storybook:playwright": "CHROMATIC_ARCHIVE_LOCATION=packages/playwright/test-results packages/playwright/dist/bin/build-archive-storybook.js", - "archive-storybook:cypress": "CHROMATIC_ARCHIVE_LOCATION=packages/cypress/tests/cypress/downloads packages/cypress/dist/bin/archive-storybook.js", - "build-archive-storybook:cypress": "CHROMATIC_ARCHIVE_LOCATION=packages/cypress/tests/cypress/downloads packages/cypress/dist/bin/build-archive-storybook.js", + "archive-storybook:cypress": "CHROMATIC_ARCHIVE_LOCATION=packages/cypress/tests/cypress/test-downloads packages/cypress/dist/bin/archive-storybook.js", + "build-archive-storybook:cypress": "CHROMATIC_ARCHIVE_LOCATION=packages/cypress/tests/cypress/test-downloads packages/cypress/dist/bin/build-archive-storybook.js", "clean": "yarn workspaces foreach --all --parallel run clean", "prebuild": "yarn clean", "build": "yarn workspaces foreach --all --topological-dev --parallel run build", diff --git a/packages/cypress/src/index.ts b/packages/cypress/src/index.ts index 2f80ceba..5e958dea 100644 --- a/packages/cypress/src/index.ts +++ b/packages/cypress/src/index.ts @@ -21,6 +21,7 @@ interface WriteParams { chromaticStorybookParams: ChromaticStorybookParameters; pageUrl: string; viewport: Viewport; + outputDir: string; } interface WriteArchivesParams extends WriteParams { @@ -34,6 +35,7 @@ const writeArchives = async ({ chromaticStorybookParams, pageUrl, viewport, + outputDir, }: WriteArchivesParams) => { const bufferedArchiveList = Object.entries(resourceArchive).map(([key, value]) => { return [ @@ -59,9 +61,7 @@ const writeArchives = async ({ await writeTestResult( { titlePath: testTitlePath, - // this will store it at ./cypress/downloads (the last directory doesn't matter) - // TODO: change so we don't have to do this trickery - outputDir: './cypress/downloads/some', + outputDir, pageUrl, viewport, }, diff --git a/packages/cypress/src/support.ts b/packages/cypress/src/support.ts index a4536154..c247861c 100644 --- a/packages/cypress/src/support.ts +++ b/packages/cypress/src/support.ts @@ -60,6 +60,7 @@ afterEach(() => { height: Cypress.config('viewportHeight'), width: Cypress.config('viewportWidth'), }, + outputDir: Cypress.config('downloadsFolder'), }, }); }); diff --git a/packages/cypress/tests/cypress.config.ts b/packages/cypress/tests/cypress.config.ts index 8d2e914f..12d85a86 100644 --- a/packages/cypress/tests/cypress.config.ts +++ b/packages/cypress/tests/cypress.config.ts @@ -1,7 +1,11 @@ import { defineConfig } from 'cypress'; import { installPlugin } from '../dist'; +import { existsSync } from 'node:fs'; export default defineConfig({ + // `downloadsFolder` cannot be overridden in tests, so we're setting + // this to a non-default value for asserting in the tests + downloadsFolder: 'cypress/test-downloads', // needed since we use common mock images between Cypress and Playwright fixturesFolder: '../../../test-server/fixtures', screenshotOnRunFailure: false, @@ -9,6 +13,11 @@ export default defineConfig({ baseUrl: 'http://localhost:3000', setupNodeEvents(on, config) { installPlugin(on, config); + on('task', { + directoryExists(directoryName) { + return existsSync(directoryName); + }, + }); }, }, }); diff --git a/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts new file mode 100644 index 00000000..9520770a --- /dev/null +++ b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts @@ -0,0 +1,13 @@ +// Snapshots are disabled because we're asserting on file system concerns, +// not testing anything visual +it( + 'downloads archives to the user-specified folder', + { env: { disableAutoSnapshot: true } }, + () => { + cy.visit('/asset-paths/query-params'); + const chromaticArchivesDir = `${Cypress.config('downloadsFolder')}/chromatic-archives`; + cy.task('directoryExists', chromaticArchivesDir).then((dirExists) => { + expect(dirExists).to.be.true; + }); + } +); diff --git a/packages/playwright/src/makeTest.ts b/packages/playwright/src/makeTest.ts index db734b19..5816852c 100644 --- a/packages/playwright/src/makeTest.ts +++ b/packages/playwright/src/makeTest.ts @@ -14,6 +14,7 @@ import { trackRun, DEFAULT_GLOBAL_RESOURCE_ARCHIVE_TIMEOUT_MS, } from '@chromatic-com/shared-e2e'; +import { join } from 'node:path'; import { chromaticSnapshots, takeSnapshot } from './takeSnapshot'; import { createResourceArchive } from './createResourceArchive'; @@ -72,8 +73,11 @@ export const performChromaticSnapshot = async ( ...(cropToViewport && { cropToViewport }), }; + // TestInfo.outputDir gives us the test-specific subfolder (https://playwright.dev/docs/api/class-testconfig#test-config-output-dir); + // we want to write one level above that + const outputDir = join(testInfo.outputDir, '..'); await writeTestResult( - { ...testInfo, pageUrl: page.url(), viewport: page.viewportSize() }, + { ...testInfo, outputDir, pageUrl: page.url(), viewport: page.viewportSize() }, Object.fromEntries(snapshots), resourceArchive, chromaticStorybookParams diff --git a/packages/shared/src/write-archive/index.test.ts b/packages/shared/src/write-archive/index.test.ts index 62423cbd..a94e14de 100644 --- a/packages/shared/src/write-archive/index.test.ts +++ b/packages/shared/src/write-archive/index.test.ts @@ -34,7 +34,7 @@ describe('writeTestResult', () => { // the default output directory in playwright { titlePath: ['file.spec.ts', 'Test Story'], - outputDir: resolve('test-results/test-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -90,7 +90,7 @@ describe('writeTestResult', () => { // the default output directory in playwright { titlePath: ['file.spec.ts', 'Toy Story'], - outputDir: resolve('test-results/toy-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -127,7 +127,7 @@ describe('writeTestResult', () => { { titlePath: ['file.spec.ts', 'Test Story'], // simulates setting a custom output directory in Playwright - outputDir: resolve('some-custom-directory/directory/test-story-chromium'), + outputDir: resolve('some-custom-directory/directory'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -151,7 +151,7 @@ describe('writeTestResult', () => { await writeTestResult( { titlePath: ['file.spec.ts', 'A grouping', 'Test Story'], - outputDir: resolve('test-results/test-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -177,7 +177,7 @@ describe('writeTestResult', () => { '.someFunction', '.someFunction() calls something', ], - outputDir: resolve('test-results/test-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -199,7 +199,7 @@ describe('writeTestResult', () => { await writeTestResult( { titlePath: ['some.file.spec.ts', 'Test Story'], - outputDir: resolve('test-results/test-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -221,7 +221,7 @@ describe('writeTestResult', () => { await writeTestResult( { titlePath: ['some.file.cy.ts', 'Test Story'], - outputDir: resolve('test-results/test-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, @@ -243,7 +243,7 @@ describe('writeTestResult', () => { await writeTestResult( { titlePath: ['file.ts', 'Test Story'], - outputDir: resolve('test-results/test-story-chromium'), + outputDir: resolve('test-results'), pageUrl: 'http://localhost:3000/', viewport: { height: 800, width: 800 }, }, diff --git a/packages/shared/src/write-archive/index.ts b/packages/shared/src/write-archive/index.ts index d5af9c10..002b3114 100644 --- a/packages/shared/src/write-archive/index.ts +++ b/packages/shared/src/write-archive/index.ts @@ -1,4 +1,4 @@ -import { join } from 'path'; +import { join } from 'node:path'; import { outputFile, ensureDir, outputJSONFile } from '../utils/filePaths'; import { logger } from '../utils/logger'; import { ArchiveFile } from './archive-file'; @@ -38,9 +38,7 @@ export async function writeTestResult( ); // in Storybook, `/` splits the title out into hierarchies (folders) const title = titlePathWithoutFileExtensions.join('/'); - // outputDir gives us the test-specific subfolder (https://playwright.dev/docs/api/class-testconfig#test-config-output-dir); - // we want to write one level above that - const finalOutputDir = join(outputDir, '..', 'chromatic-archives'); + const finalOutputDir = join(outputDir, 'chromatic-archives'); const archiveDir = join(finalOutputDir, 'archive');