From 0153e633f7e782062005ed56b2915d6998ec6150 Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Fri, 21 Jun 2024 16:08:37 -0700 Subject: [PATCH 01/15] modify playwright outputDir in the correct place Co-authored-by: Andrew Ortwein --- packages/playwright/src/makeTest.ts | 6 +++++- packages/shared/src/write-archive/index.test.ts | 16 ++++++++-------- packages/shared/src/write-archive/index.ts | 4 +--- 3 files changed, 14 insertions(+), 12 deletions(-) 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..60218f25 100644 --- a/packages/shared/src/write-archive/index.ts +++ b/packages/shared/src/write-archive/index.ts @@ -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'); From a53ace5249c31d8418b7cc72c05a927190e84ed8 Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Fri, 21 Jun 2024 16:09:24 -0700 Subject: [PATCH 02/15] use the configured downloadsFolder as outputDir for cypress Co-authored-by: Andrew Ortwein --- packages/cypress/src/index.ts | 6 +++--- packages/cypress/src/support.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) 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'), }, }); }); From 614434049b31bd3ebf4e32165526790aa251ced8 Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Fri, 21 Jun 2024 16:13:33 -0700 Subject: [PATCH 03/15] add changeset --- .changeset/slimy-cups-protect.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/slimy-cups-protect.md diff --git a/.changeset/slimy-cups-protect.md b/.changeset/slimy-cups-protect.md new file mode 100644 index 00000000..130ac27f --- /dev/null +++ b/.changeset/slimy-cups-protect.md @@ -0,0 +1,6 @@ +--- +'@chromatic-com/playwright': patch +'@chromatic-com/cypress': patch +--- + +Use the configured `downloadsFolder` in Cypress as the output dir for archives From 835f9d82a4d0b742d395fb0896a828db52c60861 Mon Sep 17 00:00:00 2001 From: Steven Kitterman Date: Tue, 25 Jun 2024 10:50:11 -0700 Subject: [PATCH 04/15] Task for ensuring a downloads folder is created where we intend --- packages/cypress/tests/cypress.config.ts | 5 +++++ .../tests/cypress/e2e/custom-downloads-directory.cy.ts | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts diff --git a/packages/cypress/tests/cypress.config.ts b/packages/cypress/tests/cypress.config.ts index 8d2e914f..dbb4b06e 100644 --- a/packages/cypress/tests/cypress.config.ts +++ b/packages/cypress/tests/cypress.config.ts @@ -9,6 +9,11 @@ export default defineConfig({ baseUrl: 'http://localhost:3000', setupNodeEvents(on, config) { installPlugin(on, config); + on('task', { + directoryExists(directoryName) { + return true; + }, + }); }, }, }); 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..ffd7b690 --- /dev/null +++ b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts @@ -0,0 +1,7 @@ +context('using Cypress.config', () => { + it('Downloads archives to the user-specified folder', () => { + cy.visit('/viewports'); + const dirExists = cy.task('directoryExists', '/some-dir'); + console.log('DIRECTORY EXISTS', dirExists); + }); +}); From 03de4158dd730609ee3ccc13144ffc1c0fc731ab Mon Sep 17 00:00:00 2001 From: Steven Kitterman Date: Mon, 1 Jul 2024 16:09:01 -0700 Subject: [PATCH 05/15] Clarifying comment, unused code removed --- packages/cypress/src/support.ts | 4 ---- packages/shared/src/resource-archiver/index.ts | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/cypress/src/support.ts b/packages/cypress/src/support.ts index 1f39a3c3..4fb5bcc0 100644 --- a/packages/cypress/src/support.ts +++ b/packages/cypress/src/support.ts @@ -5,10 +5,6 @@ const generateTestId = () => { return Cypress.currentTest.title; }; -const shouldTakeSnapshot = () => { - return !Cypress.env('disableAutoSnapshot') && !Cypress.config('isInteractive'); -}; - // these client-side lifecycle hooks will be added to the user's Cypress suite beforeEach(() => { // don't take snapshots when running `cypress open` diff --git a/packages/shared/src/resource-archiver/index.ts b/packages/shared/src/resource-archiver/index.ts index 0f11ddcd..bfc3db02 100644 --- a/packages/shared/src/resource-archiver/index.ts +++ b/packages/shared/src/resource-archiver/index.ts @@ -56,6 +56,7 @@ export class ResourceArchiver { } async close() { + // Playwright's client uses detach(), Cypress' uses close() if (this.client.close) { await this.client.close(); } else if (this.client.detach) { From 27ce9f6b717251f841dcc00a1bd91da6e4902ebc Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Tue, 2 Jul 2024 16:54:30 -0700 Subject: [PATCH 06/15] add test verifying that the correct cypress dir is used --- .gitignore | 1 + package.json | 4 ++-- packages/cypress/tests/cypress.config.ts | 6 +++++- .../tests/cypress/e2e/custom-downloads-directory.cy.ts | 6 ++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e8e3064e..63989f73 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/new-downloads/ packages/*/coverage/ diff --git a/package.json b/package.json index 1cb36ac8..d6c476f3 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/new-downloads packages/cypress/dist/bin/archive-storybook.js", + "build-archive-storybook:cypress": "CHROMATIC_ARCHIVE_LOCATION=packages/cypress/tests/cypress/new-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/tests/cypress.config.ts b/packages/cypress/tests/cypress.config.ts index dbb4b06e..c612060c 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/new-downloads', // needed since we use common mock images between Cypress and Playwright fixturesFolder: '../../../test-server/fixtures', screenshotOnRunFailure: false, @@ -11,7 +15,7 @@ export default defineConfig({ installPlugin(on, config); on('task', { directoryExists(directoryName) { - return true; + 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 index ffd7b690..e9c13992 100644 --- a/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts +++ b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts @@ -1,7 +1,9 @@ context('using Cypress.config', () => { it('Downloads archives to the user-specified folder', () => { cy.visit('/viewports'); - const dirExists = cy.task('directoryExists', '/some-dir'); - console.log('DIRECTORY EXISTS', dirExists); + const chromaticArchivesDir = `${Cypress.config('downloadsFolder')}/chromatic-archives`; + cy.task('directoryExists', chromaticArchivesDir).then((dirExists) => { + expect(dirExists).true; + }); }); }); From d69ccb97a7cc49c03ec5b23eba1400a2dfccd7f8 Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Tue, 2 Jul 2024 17:29:55 -0700 Subject: [PATCH 07/15] update for consistency --- packages/shared/src/write-archive/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/write-archive/index.ts b/packages/shared/src/write-archive/index.ts index 60218f25..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'; From ebbb13d4d704106ed37e9e1e4b54645669126025 Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Tue, 2 Jul 2024 17:51:25 -0700 Subject: [PATCH 08/15] tweak test --- .../cypress/e2e/custom-downloads-directory.cy.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts index e9c13992..64897014 100644 --- a/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts +++ b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts @@ -1,9 +1,11 @@ -context('using Cypress.config', () => { - it('Downloads archives to the user-specified folder', () => { - cy.visit('/viewports'); +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).true; }); - }); -}); + } +); From b4c214d56cf66a8a9e0ef4fcfa30445baabb9620 Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Wed, 3 Jul 2024 08:04:42 -0700 Subject: [PATCH 09/15] rename dir --- .gitignore | 2 +- package.json | 4 ++-- packages/cypress/tests/cypress.config.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 63989f73..5a91a658 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,5 @@ test-archives **/playwright/.cache/ packages/playwright/test-results/ packages/cypress/tests/cypress/downloads/ -packages/cypress/tests/cypress/new-downloads/ +packages/cypress/tests/cypress/test-downloads/ packages/*/coverage/ diff --git a/package.json b/package.json index d6c476f3..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/new-downloads packages/cypress/dist/bin/archive-storybook.js", - "build-archive-storybook:cypress": "CHROMATIC_ARCHIVE_LOCATION=packages/cypress/tests/cypress/new-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/tests/cypress.config.ts b/packages/cypress/tests/cypress.config.ts index c612060c..12d85a86 100644 --- a/packages/cypress/tests/cypress.config.ts +++ b/packages/cypress/tests/cypress.config.ts @@ -5,7 +5,7 @@ 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/new-downloads', + downloadsFolder: 'cypress/test-downloads', // needed since we use common mock images between Cypress and Playwright fixturesFolder: '../../../test-server/fixtures', screenshotOnRunFailure: false, From f74bde795646780bdbf4fe76b331102439c7ab5d Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Wed, 3 Jul 2024 13:11:09 -0700 Subject: [PATCH 10/15] tweak assertion and add comment --- .../tests/cypress/e2e/custom-downloads-directory.cy.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts index 64897014..9520770a 100644 --- a/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts +++ b/packages/cypress/tests/cypress/e2e/custom-downloads-directory.cy.ts @@ -1,3 +1,5 @@ +// 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 } }, @@ -5,7 +7,7 @@ it( cy.visit('/asset-paths/query-params'); const chromaticArchivesDir = `${Cypress.config('downloadsFolder')}/chromatic-archives`; cy.task('directoryExists', chromaticArchivesDir).then((dirExists) => { - expect(dirExists).true; + expect(dirExists).to.be.true; }); } ); From a4cd9c49ab30c0253bf654a3956c92b29b4c294e Mon Sep 17 00:00:00 2001 From: Todd Evanoff Date: Wed, 3 Jul 2024 13:14:56 -0700 Subject: [PATCH 11/15] update changeset copy --- .changeset/slimy-cups-protect.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/slimy-cups-protect.md b/.changeset/slimy-cups-protect.md index 130ac27f..c72ca495 100644 --- a/.changeset/slimy-cups-protect.md +++ b/.changeset/slimy-cups-protect.md @@ -3,4 +3,5 @@ '@chromatic-com/cypress': patch --- -Use the configured `downloadsFolder` in Cypress as the output dir for archives +- 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 From b205dff6c596ed4aea420d8599c62a0fd694dad7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 5 Jul 2024 16:19:23 +0000 Subject: [PATCH 12/15] Version Packages --- .changeset/slimy-cups-protect.md | 7 ------- packages/cypress/CHANGELOG.md | 7 +++++++ packages/cypress/package.json | 2 +- packages/playwright/CHANGELOG.md | 7 +++++++ packages/playwright/package.json | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) delete mode 100644 .changeset/slimy-cups-protect.md diff --git a/.changeset/slimy-cups-protect.md b/.changeset/slimy-cups-protect.md deleted file mode 100644 index c72ca495..00000000 --- a/.changeset/slimy-cups-protect.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@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/packages/cypress/CHANGELOG.md b/packages/cypress/CHANGELOG.md index da4136ea..837d6935 100644 --- a/packages/cypress/CHANGELOG.md +++ b/packages/cypress/CHANGELOG.md @@ -1,5 +1,12 @@ # chromatic-cypress +## 0.6.15 + +### Patch Changes + +- 6144340: - 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 + ## 0.6.14 ### Patch Changes diff --git a/packages/cypress/package.json b/packages/cypress/package.json index a0cfe33f..22d903d5 100644 --- a/packages/cypress/package.json +++ b/packages/cypress/package.json @@ -1,6 +1,6 @@ { "name": "@chromatic-com/cypress", - "version": "0.6.14", + "version": "0.6.15", "description": "Chromatic Visual Regression Testing for Cypress", "repository": { "type": "git", diff --git a/packages/playwright/CHANGELOG.md b/packages/playwright/CHANGELOG.md index d32001f5..122b17ad 100644 --- a/packages/playwright/CHANGELOG.md +++ b/packages/playwright/CHANGELOG.md @@ -1,5 +1,12 @@ # chromatic-playwright +## 0.6.16 + +### Patch Changes + +- 6144340: - 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 + ## 0.6.15 ### Patch Changes diff --git a/packages/playwright/package.json b/packages/playwright/package.json index ba6d71d9..bb0e715e 100644 --- a/packages/playwright/package.json +++ b/packages/playwright/package.json @@ -1,6 +1,6 @@ { "name": "@chromatic-com/playwright", - "version": "0.6.15", + "version": "0.6.16", "description": "Chromatic Visual Regression Testing for Playwright", "repository": { "type": "git", From f322d1fd00f17e58827e73f25af91eed4dc28eb2 Mon Sep 17 00:00:00 2001 From: Steven Kitterman Date: Fri, 5 Jul 2024 09:52:23 -0700 Subject: [PATCH 13/15] Lint fixes --- packages/cypress/src/index.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/cypress/src/index.ts b/packages/cypress/src/index.ts index c936c199..c9269b45 100644 --- a/packages/cypress/src/index.ts +++ b/packages/cypress/src/index.ts @@ -97,7 +97,7 @@ const setupNetworkListener = async ({ }; const saveArchives = (archiveInfo: WriteParams & { testId: string }) => { - return new Promise(async (resolve) => { + return new Promise((resolve) => { const { testId, ...rest } = archiveInfo; if (!resourceArchivers[testId]) { console.error('Unable to archive results for test'); @@ -108,13 +108,14 @@ const saveArchives = (archiveInfo: WriteParams & { testId: string }) => { // that's because in Cypress, cy.visit() waits until all resources have loaded before finishing // so at this point (after the test) we're confident that the resources are all there already without having to wait more - const archive = resourceArchivers[testId].archive; + const { archive } = resourceArchivers[testId]; // clean up the CDP instance - await resourceArchivers[testId].close(); - // remove archives off of object after write them - delete resourceArchivers[testId]; - return writeArchives({ ...rest, resourceArchive: archive }).then(() => { - resolve(null); + return resourceArchivers[testId].close().then(() => { + // remove archives off of object after write them + delete resourceArchivers[testId]; + return writeArchives({ ...rest, resourceArchive: archive }).then(() => { + resolve(null); + }); }); }); }; From 610ac6aabb57b97688b81af77d8b3c61d23b161f Mon Sep 17 00:00:00 2001 From: Steven Kitterman Date: Fri, 5 Jul 2024 10:09:17 -0700 Subject: [PATCH 14/15] Network idle watcher for Cypress --- .../cypress/src/network-idle-watcher.test.ts | 76 +++++++++++++++++++ packages/cypress/src/network-idle-watcher.ts | 39 ++++++++++ 2 files changed, 115 insertions(+) create mode 100644 packages/cypress/src/network-idle-watcher.test.ts create mode 100644 packages/cypress/src/network-idle-watcher.ts diff --git a/packages/cypress/src/network-idle-watcher.test.ts b/packages/cypress/src/network-idle-watcher.test.ts new file mode 100644 index 00000000..c77b9dad --- /dev/null +++ b/packages/cypress/src/network-idle-watcher.test.ts @@ -0,0 +1,76 @@ +import { NetworkIdleWatcher } from './network-idle-watcher'; + +jest.useFakeTimers(); + +it('Resolves when there is no network activity', async () => { + const watcher = new NetworkIdleWatcher(); + await expect(watcher.idle()).resolves.toBeDefined(); +}); + +it('Resolves when there is a single request and response', async () => { + const watcher = new NetworkIdleWatcher(); + + watcher.onRequest(); + watcher.onResponse(); + + await expect(watcher.idle()).resolves.toBeDefined(); +}); + +it('Resolves when there are an equal amount of requests and responses', async () => { + const watcher = new NetworkIdleWatcher(); + // in total 4 requests, and 4 responses + watcher.onRequest(); + watcher.onResponse(); + + watcher.onRequest(); + watcher.onResponse(); + + watcher.onRequest(); + watcher.onRequest(); + + watcher.onResponse(); + watcher.onResponse(); + + await expect(watcher.idle()).resolves.toBeDefined(); +}); + +it('Rejects if response never sent for request', async () => { + const watcher = new NetworkIdleWatcher(); + // fire off request + watcher.onRequest(); + const promise = watcher.idle(); + jest.runAllTimers(); + // no response fired off + await expect(promise).rejects.toBeDefined(); +}); + +it("Resolves if response hasn't happened at time of idle(), but comes back before timeout", async () => { + const watcher = new NetworkIdleWatcher(); + // fire off request + watcher.onRequest(); + + const promise = watcher.idle(); + + watcher.onResponse(); + // makes sure we finish the idle watcher as soon as the reponse comes back, and not waiting the full timeout duration + jest.advanceTimersByTime(1); + + await expect(promise).resolves.toBeDefined(); +}); + +it("Rejects if response hasn't happened at time of idle(), and doesn't come back before timeout", async () => { + const watcher = new NetworkIdleWatcher(); + // fire off request + watcher.onRequest(); + + const promise = watcher.idle(); + + // response returns after idle() has been called, but will take too long + setTimeout(() => { + watcher.onResponse(); + }, 10000); + + jest.runAllTimers(); + + await expect(promise).rejects.toBeDefined(); +}); diff --git a/packages/cypress/src/network-idle-watcher.ts b/packages/cypress/src/network-idle-watcher.ts new file mode 100644 index 00000000..b27b50d2 --- /dev/null +++ b/packages/cypress/src/network-idle-watcher.ts @@ -0,0 +1,39 @@ +const TOTAL_TIMEOUT_DURATION = 3000; + +export class NetworkIdleWatcher { + private numInFlightRequests = 0; + + private idleTimer: NodeJS.Timeout | null = null; + + private exitIdleOnResponse: () => void | null = null; + + async idle() { + return new Promise((resolve, reject) => { + if (this.numInFlightRequests === 0) { + resolve(true); + } else { + this.idleTimer = setTimeout(() => { + reject(new Error('some responses have not returned')); + }, TOTAL_TIMEOUT_DURATION); + + // assign a function that resolves... and it can be used... + this.exitIdleOnResponse = () => { + resolve(true); + }; + } + }); + } + + onRequest() { + this.numInFlightRequests += 1; + } + + onResponse() { + this.numInFlightRequests -= 1; + // resolve if the in-flight request amount is now zero + if (this.numInFlightRequests === 0) { + clearTimeout(this.idleTimer); + this.exitIdleOnResponse?.(); + } + } +} From 604ef926dd5c3271149f5f56954c95be90b2e9c7 Mon Sep 17 00:00:00 2001 From: Steven Kitterman Date: Fri, 5 Jul 2024 10:18:00 -0700 Subject: [PATCH 15/15] Clarifying comments --- packages/cypress/src/network-idle-watcher.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/cypress/src/network-idle-watcher.ts b/packages/cypress/src/network-idle-watcher.ts index b27b50d2..1c2b9387 100644 --- a/packages/cypress/src/network-idle-watcher.ts +++ b/packages/cypress/src/network-idle-watcher.ts @@ -1,5 +1,8 @@ const TOTAL_TIMEOUT_DURATION = 3000; +// A Cypress equivalent of Playwright's `page.waitForLoadState()` (https://playwright.dev/docs/api/class-page#page-wait-for-load-state). +// Intentionally simplistic since in Cypress this is just used to make sure there aren't any pending requests hanging around +// after the test has finished. export class NetworkIdleWatcher { private numInFlightRequests = 0; @@ -16,7 +19,7 @@ export class NetworkIdleWatcher { reject(new Error('some responses have not returned')); }, TOTAL_TIMEOUT_DURATION); - // assign a function that resolves... and it can be used... + // assign a function that'll be called as soon as responses are all back this.exitIdleOnResponse = () => { resolve(true); }; @@ -30,7 +33,7 @@ export class NetworkIdleWatcher { onResponse() { this.numInFlightRequests -= 1; - // resolve if the in-flight request amount is now zero + // resolve immediately if the in-flight request amount is now zero if (this.numInFlightRequests === 0) { clearTimeout(this.idleTimer); this.exitIdleOnResponse?.();