Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions action-src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ async function run() {
const traceChanged = getInput('traceChanged');
const untraced = getMultilineInput('untraced');
const uploadMetadata = getInput('uploadMetadata');
const vitest = getInput('vitest');
const workingDir = getInput('workingDir') || getInput('workingDirectory');
const zip = getInput('zip');
const junitReport = getInput('junitReport');
Expand Down Expand Up @@ -195,6 +196,7 @@ async function run() {
traceChanged: maybe(traceChanged),
untraced: maybe(untraced),
uploadMetadata: maybe(uploadMetadata, false),
vitest: maybe(vitest),
zip: maybe(zip, false),
junitReport: maybe(junitReport),
},
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ inputs:
uploadMetadata:
description: 'Upload Chromatic metadata files as part of the published Storybook'
required: false
vitest:
description: 'Run build against `@chromatic-com/vitest` test archives'
required: false
workingDir:
description: 'Working directory for the package.json file'
required: false
Expand Down
11 changes: 11 additions & 0 deletions bin-src/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ describe('installArchiveDependencies', () => {
expect(execa).toHaveBeenCalledWith(cmd, args, { shell: true });
});

it('successfully installs list of dependencies for Vitest if SB package is not found and Essentials is not found', async () => {
await installArchiveDependencies({} as NormalizedPackageJson, 'vitest');

const installCommand =
'yarn add -D chromatic @chromatic-com/vitest storybook@latest @storybook/addon-essentials@latest @storybook/server-webpack5@latest';
const [cmd, ...args] = parseCommandString(installCommand);

expect(execa).toHaveBeenCalledOnce();
expect(execa).toHaveBeenCalledWith(cmd, args, { shell: true });
});

it('successfully installs list of dependencies if SB package is found and Essentials is not found', async () => {
await installArchiveDependencies(
// @ts-expect-error Ignore the intentionally missing properties
Expand Down
5 changes: 5 additions & 0 deletions bin-src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const TestFramework = {
STORYBOOK: 'storybook',
PLAYWRIGHT: 'playwright',
CYPRESS: 'cypress',
VITEST: 'vitest',
};
type TestFrameworkType = (typeof TestFramework)[keyof typeof TestFramework];

Expand Down Expand Up @@ -109,6 +110,9 @@ const intializeChromatic = async ({
case TestFramework.PLAYWRIGHT:
await installArchiveDependencies(packageJson, TestFramework.PLAYWRIGHT);
break;
case TestFramework.VITEST:
await installArchiveDependencies(packageJson, TestFramework.VITEST);
break;

default:
break;
Expand Down Expand Up @@ -171,6 +175,7 @@ export async function main(argv: string[]) {
{ title: 'Storybook', value: TestFramework.STORYBOOK },
{ title: 'Playwright', value: TestFramework.PLAYWRIGHT },
{ title: 'Cypress', value: TestFramework.CYPRESS },
{ title: 'Vitest', value: TestFramework.VITEST },
],
initial: 0,
},
Expand Down
2 changes: 1 addition & 1 deletion node-src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ it('skips building and uploads directly with storybook-build-dir', async () => {
);
});

it.each(['playwright', 'cypress'])('builds with $0 with --%s', async (e2ePackage) => {
it.each(['playwright', 'cypress', 'vitest'])('builds with $0 with --%s', async (e2ePackage) => {
const binPath = `path/to/@chromatic-com/${e2ePackage}/bin/build-archive-storybook`;
const revertPatch = patchModulePath(
`@chromatic-com/${e2ePackage}/bin/build-archive-storybook`,
Expand Down
2 changes: 1 addition & 1 deletion node-src/lib/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const parseNexec = ((agent, args) => {
*/
export async function getE2EBuildCommand(
ctx: Context,
flag: 'playwright' | 'cypress',
flag: 'playwright' | 'cypress' | 'vitest',
buildCommandOptions: string[]
) {
// The action cannot "peer depend" on or import anything. So instead, we must attempt to exec
Expand Down
2 changes: 1 addition & 1 deletion node-src/lib/e2eUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import { Options } from '../types';
* @returns true if the build is an E2E build.
*/
export function isE2EBuild(options: Options) {
return options.playwright || options.cypress;
return options.playwright || options.cypress || options.vitest;
}
1 change: 1 addition & 0 deletions node-src/lib/getConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const configurationSchema = z
buildCommand: z.string(),
playwright: z.boolean(),
cypress: z.boolean(),
vitest: z.boolean(),
outputDir: z.string(),
skip: z.union([z.string(), z.boolean()]),
skipUpdateCheck: z.boolean(),
Expand Down
6 changes: 3 additions & 3 deletions node-src/lib/getOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe('getOptions', () => {
});
});

it.each(['playwright', 'cypress'])(
it.each(['playwright', 'cypress', 'vitest'])(
'sets storybookLogFile to default e2e when %s is set',
async (e2eIntegration) => {
expect(getOptions(getContext([`--${e2eIntegration}`]))).toMatchObject({
Expand All @@ -87,9 +87,9 @@ describe('getOptions', () => {

it('throws when multiple e2e integrations are set at once', async () => {
expect(() =>
getOptions(getContext(['--projectToken', 'example', '--playwright', '--cypress']))
getOptions(getContext(['--projectToken', 'example', '--playwright', '--cypress', '--vitest']))
).toThrowErrorMatchingInlineSnapshot(
`[Error: ✖ You can only use one of --playwright, --cypress]`
`[Error: ✖ You can only use one of --playwright, --cypress, --vitest]`
);
});

Expand Down
5 changes: 4 additions & 1 deletion node-src/lib/getOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export default function getOptions(ctx: InitialContext): Options {
buildCommand: undefined,
playwright: undefined,
cypress: undefined,
vitest: undefined,
outputDir: undefined,
storybookBuildDir: undefined,
storybookBaseDir: undefined,
Expand Down Expand Up @@ -155,13 +156,14 @@ export default function getOptions(ctx: InitialContext): Options {
buildCommand: flags.buildCommand,
playwright: trueIfSet(flags.playwright),
cypress: trueIfSet(flags.cypress),
vitest: trueIfSet(flags.vitest),
outputDir: takeLast(flags.outputDir),
storybookBuildDir: takeLast(flags.storybookBuildDir),
storybookBaseDir: flags.storybookBaseDir,
storybookConfigDir: flags.storybookConfigDir,
// We should rename this flag so it makes more sense in E2E contexts
storybookLogFile:
flags.playwright || flags.cypress
flags.playwright || flags.cypress || flags.vitest
? defaultUnlessSet(flags.storybookLogFile, DEFAULT_E2E_LOG_FILE)
: defaultUnlessSet(flags.storybookLogFile, DEFAULT_STORYBOOK_LOG_FILE),

Expand Down Expand Up @@ -247,6 +249,7 @@ export default function getOptions(ctx: InitialContext): Options {
storybookBuildDir: '--storybook-build-dir',
playwright: '--playwright',
cypress: '--cypress',
vitest: '--vitest',
};
const foundSingularOptions = Object.keys(singularOptions).filter(
(name) => !!potentialOptions[name]
Expand Down
2 changes: 1 addition & 1 deletion node-src/tasks/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ describe('setBuildCommand', () => {
expect(ctx.buildCommand).toEqual('npm run build:storybook');
});

it.each(['playwright', 'cypress'])(
it.each(['playwright', 'cypress', 'vitest'])(
'resolves to the E2E build command when using %s',
async (e2ePackage) => {
const revertPatch = patchModulePath(
Expand Down
21 changes: 14 additions & 7 deletions node-src/tasks/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ const getStatsFlag = (ctx: Context) => {
: '--webpack-stats-json';
};

// eslint-disable-next-line complexity
export const setBuildCommand = async (ctx: Context) => {
// We don't currently support building React Native Storybook so we'll skip this for now
if (ctx.isReactNativeApp) {
Expand Down Expand Up @@ -81,11 +80,7 @@ export const setBuildCommand = async (ctx: Context) => {
}

if (isE2EBuild(ctx.options)) {
ctx.buildCommand = await getE2EBuildCommand(
ctx,
ctx.options.playwright ? 'playwright' : 'cypress',
buildCommandOptions
);
ctx.buildCommand = await getE2EBuildCommand(ctx, resolveE2EFramework(ctx), buildCommandOptions);
return;
}

Expand Down Expand Up @@ -123,7 +118,7 @@ function e2eBuildErrorMessage(
workingDirectory: string,
ctx: Context
): { exitCode: number; message: string } {
const flag = ctx.options.playwright ? 'playwright' : 'cypress';
const flag = resolveE2EFramework(ctx);
const errorMessage = err.message;

// If we tried to run the E2E package's bin directly (due to being in the action)
Expand Down Expand Up @@ -260,3 +255,15 @@ export default function main(ctx: Context) {
],
});
}

function resolveE2EFramework(ctx: Context) {
if (ctx.options.playwright) {
return 'playwright';
}

if (ctx.options.vitest) {
return 'vitest';
}

return 'cypress';
}
2 changes: 2 additions & 0 deletions node-src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface Flags {
// E2E options
playwright?: boolean;
cypress?: boolean;
vitest?: boolean;

// Chromatic options
autoAcceptChanges?: string;
Expand Down Expand Up @@ -102,6 +103,7 @@ export interface Options extends Configuration {
buildCommand: Flags['buildCommand'];
playwright: Flags['playwright'];
cypress: Flags['cypress'];
vitest: Flags['vitest'];
outputDir: string;
url?: string;
storybookBuildDir: string;
Expand Down
4 changes: 4 additions & 0 deletions node-src/ui/tasks/storybookInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const e2eMessage = (ctx: Context) => {
return 'Cypress for E2E';
}

if (ctx.options.vitest) {
return 'Vitest for E2E';
}

return 'E2E';
};

Expand Down
7 changes: 7 additions & 0 deletions node-src/ui/tasks/storybookInfoE2E.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ export const SuccessCypress = () =>
options: { ...ctx.options, playwright: false, cypress: true },
storybook,
} as any);

export const SuccessVitest = () =>
success({
...ctx,
options: { ...ctx.options, playwright: false, vitest: true },
storybook,
} as any);
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,18 @@
},
"peerDependencies": {
"@chromatic-com/cypress": "^0.*.* || ^1.0.0",
"@chromatic-com/playwright": "^0.*.* || ^1.0.0"
"@chromatic-com/playwright": "^0.*.* || ^1.0.0",
"@chromatic-com/vitest": "^0.*.* || ^1.0.0"
},
"peerDependenciesMeta": {
"@chromatic-com/cypress": {
"optional": true
},
"@chromatic-com/playwright": {
"optional": true
},
"@chromatic-com/vitest": {
"optional": true
}
},
"publishConfig": {
Expand Down
3 changes: 3 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8046,11 +8046,14 @@ __metadata:
peerDependencies:
"@chromatic-com/cypress": ^0.*.* || ^1.0.0
"@chromatic-com/playwright": ^0.*.* || ^1.0.0
"@chromatic-com/vitest": ^0.*.* || ^1.0.0
peerDependenciesMeta:
"@chromatic-com/cypress":
optional: true
"@chromatic-com/playwright":
optional: true
"@chromatic-com/vitest":
optional: true
bin:
chroma: dist/bin.js
chromatic: dist/bin.js
Expand Down
Loading