From 72f2e159c4814754f32b6cc4cf3f879f151b4ac8 Mon Sep 17 00:00:00 2001 From: Cody Kaup Date: Wed, 16 Oct 2024 15:24:47 -0500 Subject: [PATCH] Add stories for snapshot task --- node-src/tasks/snapshot.ts | 8 +- node-src/ui/tasks/snapshot.stories.ts | 36 ++++---- node-src/ui/tasks/snapshot.ts | 40 ++++++--- node-src/ui/tasks/snapshotE2E.stories.ts | 84 +++++++++++++++++++ .../ui/workflows/uploadBuildE2E.stories.ts | 2 +- 5 files changed, 138 insertions(+), 32 deletions(-) create mode 100644 node-src/ui/tasks/snapshotE2E.stories.ts diff --git a/node-src/tasks/snapshot.ts b/node-src/tasks/snapshot.ts index 3f151418a..7c6bcb962 100644 --- a/node-src/tasks/snapshot.ts +++ b/node-src/tasks/snapshot.ts @@ -153,18 +153,18 @@ export const takeSnapshots = async (ctx: Context, task: Task) => { /** * Sets up the Listr task for snapshotting the Storybook. * - * @param _ The context set when executing the CLI. + * @param ctx The context set when executing the CLI. * * @returns A Listr task. */ -export default function main(_: Context) { +export default function main(ctx: Context) { return createTask({ name: 'snapshot', - title: initial.title, + title: initial(ctx).title, skip: (ctx: Context) => { if (ctx.skip) return true; if (ctx.skipSnapshots) return skipped(ctx).output; - if (ctx.options.dryRun) return dryRun().output; + if (ctx.options.dryRun) return dryRun(ctx).output; return false; }, steps: [transitionTo(pending), takeSnapshots], diff --git a/node-src/ui/tasks/snapshot.stories.ts b/node-src/ui/tasks/snapshot.stories.ts index 0ef65bea9..68cacec6b 100644 --- a/node-src/ui/tasks/snapshot.stories.ts +++ b/node-src/ui/tasks/snapshot.stories.ts @@ -28,51 +28,57 @@ const build = { specCount: 8, features: { uiTests: true }, }; -const options = {}; +const ctx = { options: {} } as any; const now = 0; const startedAt = -123_456; -export const Initial = () => initial; +export const Initial = () => initial(ctx); -export const DryRun = () => dryRun(); +export const DryRun = () => dryRun(ctx); export const Pending = () => - pending({ build, options } as any, { + pending({ ...ctx, build } as any, { cursor: 6, label: 'ComponentName › StoryName', }); export const PendingOnlyChanged = () => - pending({ build: { ...build, actualTestCount: 8 }, options, onlyStoryFiles: [] } as any, { + pending({ ...ctx, build: { ...build, actualTestCount: 8 }, onlyStoryFiles: [] } as any, { cursor: 6, }); export const PendingOnlyStoryNames = () => pending( - { build: { ...build, actualTestCount: 8 }, options: { onlyStoryNames: ['Pages/**'] } } as any, + { + ...ctx, + build: { ...build, actualTestCount: 8 }, + options: { ...ctx.options, onlyStoryNames: ['Pages/**'] }, + } as any, { cursor: 6 } ); -export const BuildPassed = () => buildPassed({ build, now, startedAt } as any); +export const BuildPassed = () => buildPassed({ ...ctx, build, now, startedAt } as any); -export const BuildComplete = () => buildComplete({ build, now, startedAt, exitCode: 1 } as any); +export const BuildComplete = () => + buildComplete({ ...ctx, build, now, startedAt, exitCode: 1 } as any); export const BuildAutoAccepted = () => - buildComplete({ build: { ...build, autoAcceptChanges: true }, now, startedAt } as any); + buildComplete({ ...ctx, build: { ...build, autoAcceptChanges: true }, now, startedAt } as any); export const BuildBroken = () => - buildBroken({ build, now, startedAt, exitCode: exitCodes.BUILD_HAS_ERRORS } as any); + buildBroken({ ...ctx, build, now, startedAt, exitCode: exitCodes.BUILD_HAS_ERRORS } as any); export const BuildFailed = () => - buildFailed({ build, now, startedAt, exitCode: exitCodes.BUILD_FAILED } as any); + buildFailed({ ...ctx, build, now, startedAt, exitCode: exitCodes.BUILD_FAILED } as any); export const BuildCanceled = () => - buildCanceled({ build, now, startedAt, exitCode: exitCodes.BUILD_WAS_CANCELED } as any); + buildCanceled({ ...ctx, build, now, startedAt, exitCode: exitCodes.BUILD_WAS_CANCELED } as any); -export const SkippedPublishOnly = () => skipped({ isPublishOnly: true } as any); +export const SkippedPublishOnly = () => skipped({ ...ctx, isPublishOnly: true } as any); -export const SkippedList = () => skipped({ options: { list: true } } as any); +export const SkippedList = () => + skipped({ ...ctx, options: { ...ctx.options, list: true } } as any); export const SkippedExitOnceUploaded = () => - skipped({ options: { exitOnceUploaded: true } } as any); + skipped({ ...ctx, options: { ...ctx.optionns, exitOnceUploaded: true } } as any); diff --git a/node-src/ui/tasks/snapshot.ts b/node-src/ui/tasks/snapshot.ts index b9ccbc611..ede1d99ce 100644 --- a/node-src/ui/tasks/snapshot.ts +++ b/node-src/ui/tasks/snapshot.ts @@ -1,17 +1,20 @@ import pluralize from 'pluralize'; +import { isE2EBuild } from '../../lib/e2eUtils'; import { getDuration } from '../../lib/tasks'; import { progressBar } from '../../lib/utils'; import { Context } from '../../types'; -export const initial = { +const testType = (ctx: Context) => (isE2EBuild(ctx.options) ? 'test suite' : 'stories'); + +export const initial = (ctx: Context) => ({ status: 'initial', - title: 'Test your stories', -}; + title: `Test your ${testType(ctx)}`, +}); -export const dryRun = () => ({ +export const dryRun = (ctx: Context) => ({ status: 'skipped', - title: 'Test your stories', + title: `Test your ${testType(ctx)}`, output: 'Skipped due to --dry-run', }); @@ -33,6 +36,7 @@ export const stats = ({ errors: pluralize('component error', build.errorCount, true), changes: pluralize('change', build.changeCount, true), stories: pluralize('story', build.specCount, true), + e2eTests: pluralize('test', build.specCount, true), components: pluralize('component', build.componentCount, true), skips: pluralize('test', build.testCount - build.actualTestCount, true), snapshots: pluralize('snapshot', build.actualCaptureCount, true), @@ -70,31 +74,43 @@ export const pending = (ctx: Context, { cursor = 0, label = '' } = {}) => { }; export const buildPassed = (ctx: Context) => { - const { snapshots, components, stories } = stats(ctx); + const { snapshots, components, stories, e2eTests } = stats(ctx); + const output = isE2EBuild(ctx.options) + ? `Tested ${e2eTests}; captured ${snapshots} in ${getDuration(ctx)}` + : `Tested ${stories} across ${components}; captured ${snapshots} in ${getDuration(ctx)}`; + return { status: 'success', title: `Build ${ctx.build.number} passed!`, - output: `Tested ${stories} across ${components}; captured ${snapshots} in ${getDuration(ctx)}`, + output, }; }; export const buildComplete = (ctx: Context) => { - const { snapshots, components, stories } = stats(ctx); + const { snapshots, components, stories, e2eTests } = stats(ctx); + const output = isE2EBuild(ctx.options) + ? `Tested ${e2eTests}; captured ${snapshots} in ${getDuration(ctx)}` + : `Tested ${stories} across ${components}; captured ${snapshots} in ${getDuration(ctx)}`; + return { status: 'success', title: ctx.build.autoAcceptChanges ? `Build ${ctx.build.number} auto-accepted` : `Build ${ctx.build.number} completed`, - output: `Tested ${stories} across ${components}; captured ${snapshots} in ${getDuration(ctx)}`, + output, }; }; export const buildBroken = (ctx: Context) => { - const { snapshots, components, stories, errors } = stats(ctx); + const { snapshots, components, stories, e2eTests, errors } = stats(ctx); + const output = isE2EBuild(ctx.options) + ? `Tested ${e2eTests}; captured ${snapshots} and found ${errors}` + : `Tested ${stories} across ${components}; captured ${snapshots} and found ${errors}`; + return { status: 'error', title: `Build ${ctx.build.number} failed after ${getDuration(ctx)}`, - output: `Tested ${stories} across ${components}; captured ${snapshots} and found ${errors}`, + output, }; }; @@ -117,7 +133,7 @@ export const buildCanceled = (ctx: Context) => { export const skipped = (ctx: Context) => { return { status: 'skipped', - title: 'Test your stories', + title: `Test your ${testType(ctx)}`, output: ctx.isPublishOnly ? `No UI tests or UI review enabled` : `Skipped due to ${ctx.options.list ? '--list' : '--exit-once-uploaded'}`, diff --git a/node-src/ui/tasks/snapshotE2E.stories.ts b/node-src/ui/tasks/snapshotE2E.stories.ts new file mode 100644 index 000000000..cc618d623 --- /dev/null +++ b/node-src/ui/tasks/snapshotE2E.stories.ts @@ -0,0 +1,84 @@ +import { exitCodes } from '../../lib/setExitCode'; +import task from '../components/task'; +import { + buildBroken, + buildCanceled, + buildComplete, + buildFailed, + buildPassed, + dryRun, + initial, + pending, + skipped, +} from './snapshot'; + +export default { + title: 'CLI/Tasks/Snapshot/E2E', + decorators: [(storyFunction) => task(storyFunction())], +}; + +const build = { + number: 42, + errorCount: 1, + changeCount: 2, + testCount: 10, + actualTestCount: 10, + actualCaptureCount: 20, + componentCount: 5, + specCount: 8, + features: { uiTests: true }, +}; +const ctx = { options: { playwright: true } } as any; + +const now = 0; +const startedAt = -123_456; + +export const Initial = () => initial(ctx); + +export const DryRun = () => dryRun(ctx); + +export const Pending = () => + pending({ ...ctx, build } as any, { + cursor: 6, + label: 'ComponentName › StoryName', + }); + +export const PendingOnlyChanged = () => + pending({ ...ctx, build: { ...build, actualTestCount: 8 }, onlyStoryFiles: [] } as any, { + cursor: 6, + }); + +export const PendingOnlyStoryNames = () => + pending( + { + ...ctx, + build: { ...build, actualTestCount: 8 }, + options: { ...ctx.options, onlyStoryNames: ['Pages/**'] }, + } as any, + { cursor: 6 } + ); + +export const BuildPassed = () => buildPassed({ ...ctx, build, now, startedAt } as any); + +export const BuildComplete = () => + buildComplete({ ...ctx, build, now, startedAt, exitCode: 1 } as any); + +export const BuildAutoAccepted = () => + buildComplete({ ...ctx, build: { ...build, autoAcceptChanges: true }, now, startedAt } as any); + +export const BuildBroken = () => + buildBroken({ ...ctx, build, now, startedAt, exitCode: exitCodes.BUILD_HAS_ERRORS } as any); + +export const BuildFailed = () => + buildFailed({ ...ctx, build, now, startedAt, exitCode: exitCodes.BUILD_FAILED } as any); + +export const BuildCanceled = () => + buildCanceled({ ...ctx, build, now, startedAt, exitCode: exitCodes.BUILD_WAS_CANCELED } as any); + +export const SkippedPublishOnly = () => skipped({ ...ctx, isPublishOnly: true } as any); + +export const SkippedList = () => + skipped({ ...ctx, options: { ...ctx.options, list: true } } as any); + +export const SkippedExitOnceUploaded = () => + skipped({ ...ctx, options: { ...ctx.options, exitOnceUploaded: true } } as any); diff --git a/node-src/ui/workflows/uploadBuildE2E.stories.ts b/node-src/ui/workflows/uploadBuildE2E.stories.ts index cfa8bffef..33dfe6eb7 100644 --- a/node-src/ui/workflows/uploadBuildE2E.stories.ts +++ b/node-src/ui/workflows/uploadBuildE2E.stories.ts @@ -7,7 +7,7 @@ import * as auth from '../tasks/auth.stories'; import * as build from '../tasks/buildE2E.stories'; import * as gitInfo from '../tasks/gitInfo.stories'; import * as initialize from '../tasks/initialize.stories'; -import * as snapshot from '../tasks/snapshot.stories'; +import * as snapshot from '../tasks/snapshotE2E.stories'; import * as storybookInfo from '../tasks/storybookInfoE2E.stories'; import * as upload from '../tasks/uploadE2E.stories'; import * as verify from '../tasks/verifyE2E.stories';