From a25f74714b74114592f55c1fe17e3265a60ea113 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:40:47 +1000 Subject: [PATCH 1/8] Step `ctx.task` in each task --- node-src/lib/tasks.ts | 13 ++++++++++++- node-src/tasks/auth.ts | 1 + node-src/tasks/build.ts | 1 + node-src/tasks/gitInfo.ts | 1 + node-src/tasks/initialize.ts | 1 + node-src/tasks/prepareWorkspace.ts | 1 + node-src/tasks/report.ts | 1 + node-src/tasks/restoreWorkspace.ts | 1 + node-src/tasks/snapshot.ts | 1 + node-src/tasks/storybookInfo.ts | 1 + node-src/tasks/upload.ts | 1 + node-src/tasks/verify.ts | 1 + node-src/types.ts | 1 + 13 files changed, 24 insertions(+), 1 deletion(-) diff --git a/node-src/lib/tasks.ts b/node-src/lib/tasks.ts index 26679a03d..affb7c530 100644 --- a/node-src/lib/tasks.ts +++ b/node-src/lib/tasks.ts @@ -5,9 +5,20 @@ import { Context, Task } from '../types'; type ValueFn = string | ((ctx: Context, task: Task) => string); -export const createTask = ({ title, steps, ...config }): Listr.ListrTask => ({ +type TaskInput = Omit, 'task'> & { + name: string; + steps: ((ctx: Context, task: Listr.ListrTaskWrapper | Task) => void | Promise)[]; +}; + +export const createTask = ({ + name, + title, + steps, + ...config +}: TaskInput): Listr.ListrTask => ({ title, task: async (ctx: Context, task: Listr.ListrTaskWrapper) => { + ctx.task = name; ctx.title = title; ctx.startedAt = Number.isInteger(ctx.now) ? ctx.now : new Date().getTime(); // eslint-disable-next-line no-restricted-syntax diff --git a/node-src/tasks/auth.ts b/node-src/tasks/auth.ts index e92b3b8e2..cd4481f8d 100644 --- a/node-src/tasks/auth.ts +++ b/node-src/tasks/auth.ts @@ -32,6 +32,7 @@ export const setAuthorizationToken = async (ctx: Context) => { }; export default createTask({ + name: 'auth', title: initial.title, steps: [transitionTo(authenticating), setAuthorizationToken, transitionTo(authenticated, true)], }); diff --git a/node-src/tasks/build.ts b/node-src/tasks/build.ts index 9ba0ecf13..74862a854 100644 --- a/node-src/tasks/build.ts +++ b/node-src/tasks/build.ts @@ -87,6 +87,7 @@ export const buildStorybook = async (ctx: Context) => { }; export default createTask({ + name: 'build', title: initial.title, skip: async (ctx) => { if (ctx.skip) return true; diff --git a/node-src/tasks/gitInfo.ts b/node-src/tasks/gitInfo.ts index f8a2eb5a3..b94fa6ff9 100644 --- a/node-src/tasks/gitInfo.ts +++ b/node-src/tasks/gitInfo.ts @@ -244,6 +244,7 @@ export const setGitInfo = async (ctx: Context, task: Task) => { }; export default createTask({ + name: 'gitInfo', title: initial.title, steps: [transitionTo(pending), setGitInfo], }); diff --git a/node-src/tasks/initialize.ts b/node-src/tasks/initialize.ts index 45f43524f..3ea952c61 100644 --- a/node-src/tasks/initialize.ts +++ b/node-src/tasks/initialize.ts @@ -94,6 +94,7 @@ export const announceBuild = async (ctx: Context) => { }; export default createTask({ + name: 'initialize', title: initial.title, skip: (ctx: Context) => ctx.skip, steps: [transitionTo(pending), setEnvironment, announceBuild, transitionTo(success, true)], diff --git a/node-src/tasks/prepareWorkspace.ts b/node-src/tasks/prepareWorkspace.ts index a6511b4fa..1077068b2 100644 --- a/node-src/tasks/prepareWorkspace.ts +++ b/node-src/tasks/prepareWorkspace.ts @@ -59,6 +59,7 @@ export const runPrepareWorkspace = async (ctx: Context, task: Task) => { }; export default createTask({ + name: 'prepareWorkspace', title: initial.title, steps: [transitionTo(pending), runPrepareWorkspace, transitionTo(success, true)], }); diff --git a/node-src/tasks/report.ts b/node-src/tasks/report.ts index 588621b0b..d6777b216 100644 --- a/node-src/tasks/report.ts +++ b/node-src/tasks/report.ts @@ -131,6 +131,7 @@ export const generateReport = async (ctx: Context) => { }; export default createTask({ + name: 'report', title: initial.title, skip: (ctx: Context) => ctx.skip, steps: [transitionTo(pending), generateReport, transitionTo(success, true)], diff --git a/node-src/tasks/restoreWorkspace.ts b/node-src/tasks/restoreWorkspace.ts index d1a0adbe2..6326699f3 100644 --- a/node-src/tasks/restoreWorkspace.ts +++ b/node-src/tasks/restoreWorkspace.ts @@ -11,6 +11,7 @@ export const runRestoreWorkspace = async () => { }; export default createTask({ + name: 'restoreWorkspace', title: initial.title, steps: [transitionTo(pending), runRestoreWorkspace, transitionTo(success, true)], }); diff --git a/node-src/tasks/snapshot.ts b/node-src/tasks/snapshot.ts index 5f540d972..01c5e2977 100644 --- a/node-src/tasks/snapshot.ts +++ b/node-src/tasks/snapshot.ts @@ -145,6 +145,7 @@ export const takeSnapshots = async (ctx: Context, task: Task) => { }; export default createTask({ + name: 'snapshot', title: initial.title, skip: (ctx: Context) => { if (ctx.skip) return true; diff --git a/node-src/tasks/storybookInfo.ts b/node-src/tasks/storybookInfo.ts index 0444f13d1..31e9191e8 100644 --- a/node-src/tasks/storybookInfo.ts +++ b/node-src/tasks/storybookInfo.ts @@ -8,6 +8,7 @@ export const setStorybookInfo = async (ctx: Context) => { }; export default createTask({ + name: 'storybookInfo', title: initial.title, skip: (ctx: Context) => ctx.skip, steps: [transitionTo(pending), setStorybookInfo, transitionTo(success, true)], diff --git a/node-src/tasks/upload.ts b/node-src/tasks/upload.ts index 552b4c84f..99436b89b 100644 --- a/node-src/tasks/upload.ts +++ b/node-src/tasks/upload.ts @@ -307,6 +307,7 @@ export const uploadStorybook = async (ctx: Context, task: Task) => { }; export default createTask({ + name: 'upload', title: initial.title, skip: (ctx: Context) => { if (ctx.skip) return true; diff --git a/node-src/tasks/verify.ts b/node-src/tasks/verify.ts index 1e7bb2bf7..f52581713 100644 --- a/node-src/tasks/verify.ts +++ b/node-src/tasks/verify.ts @@ -249,6 +249,7 @@ export const verifyBuild = async (ctx: Context, task: Task) => { }; export default createTask({ + name: 'verify', title: initial.title, skip: (ctx: Context) => { if (ctx.skip) return true; diff --git a/node-src/types.ts b/node-src/types.ts index 582685871..2595cd00f 100644 --- a/node-src/types.ts +++ b/node-src/types.ts @@ -115,6 +115,7 @@ export interface Context { argv: string[]; flags: Flags; options: Options; + task: string; title: string; skip?: boolean; skipSnapshots?: boolean; From 12e73a073731767e8f9a19f77662c19ce1427841 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:43:14 +1000 Subject: [PATCH 2/8] 7.1.0-canary.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4745fb30b..846397d3a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromatic", - "version": "7.0.0-next.0", + "version": "7.1.0-canary.0", "description": "Automate visual testing across browsers. Gather UI feedback. Versioned documentation.", "keywords": [ "storybook-addon", From 973e6db2befe72b95bada415c48672ab7c851efc Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:44:04 +1000 Subject: [PATCH 3/8] 7.1.0-canary.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 846397d3a..be9545380 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromatic", - "version": "7.1.0-canary.0", + "version": "7.1.0-canary.1", "description": "Automate visual testing across browsers. Gather UI feedback. Versioned documentation.", "keywords": [ "storybook-addon", From 3e019d1b4851686b12cfb5f9a4df7154c644d695 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:47:36 +1000 Subject: [PATCH 4/8] Add an `onTaskStart` callback --- node-src/lib/tasks.ts | 3 +++ node-src/types.ts | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/node-src/lib/tasks.ts b/node-src/lib/tasks.ts index affb7c530..be66526f5 100644 --- a/node-src/lib/tasks.ts +++ b/node-src/lib/tasks.ts @@ -21,6 +21,9 @@ export const createTask = ({ ctx.task = name; ctx.title = title; ctx.startedAt = Number.isInteger(ctx.now) ? ctx.now : new Date().getTime(); + + ctx.options.onTaskStart?.({ ...ctx }); + // eslint-disable-next-line no-restricted-syntax for (const step of steps) { // eslint-disable-next-line no-await-in-loop diff --git a/node-src/types.ts b/node-src/types.ts index 2595cd00f..b3a201b3a 100644 --- a/node-src/types.ts +++ b/node-src/types.ts @@ -88,14 +88,17 @@ export interface Options { patchHeadRef: string; patchBaseRef: string; - /** A callback that is called at the completion of each task */ - onTaskComplete?: (ctx: Context) => void; + /** A callback that is called at the start of each task */ + onTaskStart?: (ctx: Context) => void; /** A callback that is called during tasks that have incremental progress */ onTaskProgress?: ( ctx: Context, status: { progress: number; total: number; unit: string } ) => void; + + /** A callback that is called at the completion of each task */ + onTaskComplete?: (ctx: Context) => void; } export interface Context { From 50cbe8f6aff19d8ea8f69fd8eec9a95355d3ae92 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:47:53 +1000 Subject: [PATCH 5/8] 7.1.0-canary.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be9545380..4813cfb79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromatic", - "version": "7.1.0-canary.1", + "version": "7.1.0-canary.2", "description": "Automate visual testing across browsers. Gather UI feedback. Versioned documentation.", "keywords": [ "storybook-addon", From 51f0c8674ca633c80b89ca830bc6239d01f0f8de Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:52:51 +1000 Subject: [PATCH 6/8] Type task name and export --- node-src/index.ts | 2 ++ node-src/lib/tasks.ts | 4 ++-- node-src/types.ts | 15 ++++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/node-src/index.ts b/node-src/index.ts index b85cf0a58..529787ee4 100644 --- a/node-src/index.ts +++ b/node-src/index.ts @@ -38,6 +38,8 @@ interface Output { inheritedCaptureCount: number; } +export type { Flags, Options, TaskName, Context } from './types'; + export async function run({ argv = [], flags, diff --git a/node-src/lib/tasks.ts b/node-src/lib/tasks.ts index be66526f5..5c90b3b35 100644 --- a/node-src/lib/tasks.ts +++ b/node-src/lib/tasks.ts @@ -1,12 +1,12 @@ import chalk from 'chalk'; import Listr from 'listr'; import pluralize from 'pluralize'; -import { Context, Task } from '../types'; +import { Context, Task, TaskName } from '../types'; type ValueFn = string | ((ctx: Context, task: Task) => string); type TaskInput = Omit, 'task'> & { - name: string; + name: TaskName; steps: ((ctx: Context, task: Listr.ListrTaskWrapper | Task) => void | Promise)[]; }; diff --git a/node-src/types.ts b/node-src/types.ts index b3a201b3a..9f3156442 100644 --- a/node-src/types.ts +++ b/node-src/types.ts @@ -101,6 +101,19 @@ export interface Options { onTaskComplete?: (ctx: Context) => void; } +export type TaskName = + | 'auth' + | 'gitInfo' + | 'storybookInfo' + | 'initialize' + | 'build' + | 'upload' + | 'verify' + | 'snapshot' + | 'report' + | 'prepareWorkspace' + | 'restoreWorkspace'; + export interface Context { env: Env; log: Logger; @@ -118,7 +131,7 @@ export interface Context { argv: string[]; flags: Flags; options: Options; - task: string; + task: TaskName; title: string; skip?: boolean; skipSnapshots?: boolean; From d19e6aa8ea713e34fcd238f7d2a2678d8c597acc Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Mon, 4 Sep 2023 11:53:03 +1000 Subject: [PATCH 7/8] 7.1.0-canary.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4813cfb79..776c9a550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromatic", - "version": "7.1.0-canary.2", + "version": "7.1.0-canary.3", "description": "Automate visual testing across browsers. Gather UI feedback. Versioned documentation.", "keywords": [ "storybook-addon", From 93898342a824198788ea3ad8a4159ad49a90739f Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 6 Sep 2023 23:16:20 +1000 Subject: [PATCH 8/8] Change `onTaskX` options to be experimental --- node-src/lib/tasks.ts | 4 ++-- node-src/tasks/snapshot.test.ts | 10 +++++----- node-src/tasks/snapshot.ts | 2 +- node-src/tasks/upload.test.ts | 14 +++++++------- node-src/tasks/upload.ts | 2 +- node-src/types.ts | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/node-src/lib/tasks.ts b/node-src/lib/tasks.ts index 5c90b3b35..62164a19e 100644 --- a/node-src/lib/tasks.ts +++ b/node-src/lib/tasks.ts @@ -22,7 +22,7 @@ export const createTask = ({ ctx.title = title; ctx.startedAt = Number.isInteger(ctx.now) ? ctx.now : new Date().getTime(); - ctx.options.onTaskStart?.({ ...ctx }); + ctx.options.experimental_onTaskStart?.({ ...ctx }); // eslint-disable-next-line no-restricted-syntax for (const step of steps) { @@ -30,7 +30,7 @@ export const createTask = ({ await step(ctx, task); } - ctx.options.onTaskComplete?.({ ...ctx }); + ctx.options.experimental_onTaskComplete?.({ ...ctx }); }, ...config, }); diff --git a/node-src/tasks/snapshot.test.ts b/node-src/tasks/snapshot.test.ts index d7cfb263a..fe3eb8d5c 100644 --- a/node-src/tasks/snapshot.test.ts +++ b/node-src/tasks/snapshot.test.ts @@ -107,7 +107,7 @@ describe('takeSnapshots', () => { expect(ctx.exitCode).toBe(3); }); - it('calls onTaskProgress with progress', async () => { + it('calls experimental_onTaskProgress with progress', async () => { const client = { runQuery: jest.fn(), setAuthorization: jest.fn() }; const build = { app: { repository: { provider: 'github' } }, @@ -122,7 +122,7 @@ describe('takeSnapshots', () => { env, git: { matchesBranch }, log, - options: { onTaskProgress: jest.fn() }, + options: { experimental_onTaskProgress: jest.fn() }, build, } as any; @@ -138,13 +138,13 @@ describe('takeSnapshots', () => { await takeSnapshots(ctx, {} as any); - expect(ctx.options.onTaskProgress).toHaveBeenCalledTimes(2); - expect(ctx.options.onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledTimes(2); + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { progress: 1, total: 5, unit: 'snapshots', }); - expect(ctx.options.onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { progress: 3, total: 5, unit: 'snapshots', diff --git a/node-src/tasks/snapshot.ts b/node-src/tasks/snapshot.ts index 01c5e2977..5d98cb72a 100644 --- a/node-src/tasks/snapshot.ts +++ b/node-src/tasks/snapshot.ts @@ -70,7 +70,7 @@ export const takeSnapshots = async (ctx: Context, task: Task) => { const updateProgress = throttle( ({ cursor, label }) => { task.output = pending(ctx, { cursor, label }).output; - ctx.options.onTaskProgress?.( + ctx.options.experimental_onTaskProgress?.( { ...ctx }, { progress: cursor, total: actualTestCount, unit: 'snapshots' } ); diff --git a/node-src/tasks/upload.test.ts b/node-src/tasks/upload.test.ts index ec2407416..945a8957b 100644 --- a/node-src/tasks/upload.test.ts +++ b/node-src/tasks/upload.test.ts @@ -243,7 +243,7 @@ describe('uploadStorybook', () => { expect(ctx.isolatorUrl).toBe('https://asdqwe.chromatic.com/iframe.html'); }); - it('calls onTaskProgress with progress', async () => { + it('calls experimental_onTaskProgress with progress', async () => { const client = { runQuery: jest.fn() }; client.runQuery.mockReturnValue({ getUploadUrls: { @@ -294,29 +294,29 @@ describe('uploadStorybook', () => { log, http, sourceDir: '/static/', - options: { onTaskProgress: jest.fn() }, + options: { experimental_onTaskProgress: jest.fn() }, fileInfo, announcedBuild: { id: '1' }, } as any; await uploadStorybook(ctx, {} as any); - expect(ctx.options.onTaskProgress).toHaveBeenCalledTimes(4); - expect(ctx.options.onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledTimes(4); + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { progress: 21, total: 84, unit: 'bytes', }); - expect(ctx.options.onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { progress: 42, total: 84, unit: 'bytes', }); - expect(ctx.options.onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { progress: 63, total: 84, unit: 'bytes', }); - expect(ctx.options.onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { + expect(ctx.options.experimental_onTaskProgress).toHaveBeenCalledWith(expect.any(Object), { progress: 84, total: 84, unit: 'bytes', diff --git a/node-src/tasks/upload.ts b/node-src/tasks/upload.ts index 99436b89b..979c3c567 100644 --- a/node-src/tasks/upload.ts +++ b/node-src/tasks/upload.ts @@ -288,7 +288,7 @@ export const uploadStorybook = async (ctx: Context, task: Task) => { const percentage = Math.round((progress / total) * 100); task.output = uploading({ percentage }).output; - ctx.options.onTaskProgress?.({ ...ctx }, { progress, total, unit: 'bytes' }); + ctx.options.experimental_onTaskProgress?.({ ...ctx }, { progress, total, unit: 'bytes' }); }, // Avoid spamming the logs with progress updates in non-interactive mode ctx.options.interactive ? 100 : ctx.env.CHROMATIC_OUTPUT_INTERVAL diff --git a/node-src/types.ts b/node-src/types.ts index 9f3156442..9eddd48bf 100644 --- a/node-src/types.ts +++ b/node-src/types.ts @@ -89,16 +89,16 @@ export interface Options { patchBaseRef: string; /** A callback that is called at the start of each task */ - onTaskStart?: (ctx: Context) => void; + experimental_onTaskStart?: (ctx: Context) => void; /** A callback that is called during tasks that have incremental progress */ - onTaskProgress?: ( + experimental_onTaskProgress?: ( ctx: Context, status: { progress: number; total: number; unit: string } ) => void; /** A callback that is called at the completion of each task */ - onTaskComplete?: (ctx: Context) => void; + experimental_onTaskComplete?: (ctx: Context) => void; } export type TaskName =