Skip to content

Commit

Permalink
fix conflicts and add various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
yannbf committed Nov 21, 2023
1 parent d58470d commit ef775c1
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 1,213 deletions.
1 change: 1 addition & 0 deletions src/config/jest-playwright.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('getJestConfig', () => {
'jest-playwright': {
browsers: undefined,
collectCoverage: false,
exitOnPageError: false,
},
},
watchPlugins: [
Expand Down
1,141 changes: 28 additions & 1,113 deletions src/csf/__snapshots__/transformCsf.test.ts.snap

Large diffs are not rendered by default.

36 changes: 6 additions & 30 deletions src/csf/transformCsf.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { prefixFunction, transformCsf } from './transformCsf';
import { TestPrefixer, TransformOptions, transformCsf } from './transformCsf';
import { testPrefixer } from '../playwright/transformPlaywright';
import template from '@babel/template';
import * as t from '@babel/types';

describe('transformCsf', () => {
it('inserts a no-op test if there are no stories', () => {
Expand All @@ -12,7 +11,7 @@ describe('transformCsf', () => {
`;
const expectedCode = `describe.skip('Button', () => { it('no-op', () => {}) });`;

const result = transformCsf(csfCode, { insertTestIfEmpty: true });
const result = transformCsf(csfCode, { insertTestIfEmpty: true } as TransformOptions);

expect(result).toEqual(expectedCode);
});
Expand Down Expand Up @@ -99,35 +98,12 @@ describe('transformCsf', () => {
const beforeEachBlock = template.statement`beforeEach(() => { ${logStatement()} })`;
return beforeEachBlock();
};
const result = transformCsf(code, { beforeEachPrefixer });
const testPrefixer = template(`
console.log({ id: %%id%%, title: %%title%%, name: %%name%%, storyExport: %%storyExport%% });
async () => {}`) as unknown as TestPrefixer;

expect(result).toMatchSnapshot();
});
});
const result = transformCsf(code, { beforeEachPrefixer, testPrefixer } as TransformOptions);

describe('prefixFunction', () => {
it('returns input expression if testPrefixer is not provided', () => {
const key = 'key';
const title = 'title';
const input = t.identifier('input');
const result = prefixFunction(key, title, input);
expect(result).toEqual(input);
});

it('returns null literal if testPrefixer returns undefined', () => {
const key = 'key';
const title = 'title';
const input = t.identifier('input');
const result = prefixFunction(key, title, input, testPrefixer);
expect(result).toMatchSnapshot();
});

it('returns expression from testPrefixer if it returns a valid expression', () => {
const key = 'key';
const title = 'title';
const input = t.identifier('input');
const testPrefixer = () => t.expressionStatement(t.identifier('prefix'));
const result = prefixFunction(key, title, input, testPrefixer);
expect(result).toEqual(t.identifier('input'));
});
});
39 changes: 12 additions & 27 deletions src/csf/transformCsf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as t from '@babel/types';
import generate from '@babel/generator';
import { toId, storyNameFromExport } from '@storybook/csf';
import dedent from 'ts-dedent';

import { getTagOptions } from '../util/getTagOptions';

export interface TestContext {
Expand All @@ -16,23 +17,18 @@ type TemplateResult = t.Statement | t.Statement[];
type FilePrefixer = () => TemplateResult;
export type TestPrefixer = (context: TestContext) => TemplateResult;

interface TransformOptions {
export interface TransformOptions {
clearBody?: boolean;
beforeEachPrefixer?: FilePrefixer;
testPrefixer?: TestPrefixer;
testPrefixer: TestPrefixer;
insertTestIfEmpty?: boolean;
makeTitle?: (userTitle: string) => string;
includeTags?: string[];
excludeTags?: string[];
skipTags?: string[];
}

export const prefixFunction = (
key: string,
title: string,
input: t.Expression,
testPrefixer?: TestPrefixer
) => {
export const prefixFunction = (key: string, title: string, testPrefixer: TestPrefixer) => {
const name = storyNameFromExport(key);
const context: TestContext = {
storyExport: t.identifier(key),
Expand All @@ -41,20 +37,9 @@ export const prefixFunction = (
id: t.stringLiteral(toId(title, name)),
};

let result = input;
if (testPrefixer) {
const prefixResult = makeArray(testPrefixer(context));
const stmt = prefixResult[1] as t.ExpressionStatement;
if (stmt) {
result = stmt.expression;
}
}

if (!result) {
result = t.nullLiteral();
}

return result;
const result = makeArray(testPrefixer(context));
const stmt = result[1] as t.ExpressionStatement;
return stmt.expression;
};

const makePlayTest = ({
Expand All @@ -66,15 +51,15 @@ const makePlayTest = ({
}: {
key: string;
title: string;
metaOrStoryPlay?: t.Node;
testPrefix?: TestPrefixer;
metaOrStoryPlay?: boolean;
testPrefix: TestPrefixer;
shouldSkip?: boolean;
}): t.Statement[] => {
return [
t.expressionStatement(
t.callExpression(shouldSkip ? t.identifier('it.skip') : t.identifier('it'), [
t.stringLiteral(!!metaOrStoryPlay ? 'play-test' : 'smoke-test'),
prefixFunction(key, title, metaOrStoryPlay as t.Expression, testPrefix),
prefixFunction(key, title, testPrefix),
])
),
];
Expand Down Expand Up @@ -111,7 +96,7 @@ export const transformCsf = (
beforeEachPrefixer,
insertTestIfEmpty,
makeTitle,
}: TransformOptions = {}
}: TransformOptions
) => {
const { includeTags, excludeTags, skipTags } = getTagOptions();

Expand Down Expand Up @@ -153,7 +138,7 @@ export const transformCsf = (
...makePlayTest({
key,
title,
metaOrStoryPlay: storyAnnotations[key]?.play,
metaOrStoryPlay: !!storyAnnotations[key]?.play,
testPrefix: testPrefixer,
shouldSkip,
}),
Expand Down
24 changes: 12 additions & 12 deletions src/playwright/hooks.test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { Page } from 'playwright-core';
import {
getStoryContext,
setPreRender,
setPostRender,
setPreVisit,
setPostVisit,
TestRunnerConfig,
waitForPageReady,
} from './hooks';

type MockPage = Page & { evaluate: jest.Mock };

describe('test-runner', () => {
describe('setPreRender', () => {
it('sets the preRender function', () => {
const preRender = jest.fn();
setPreRender(preRender);
expect(globalThis.__sbPreRender).toBe(preRender);
describe('setPreVisit', () => {
it('sets the preVisit function', () => {
const preVisit = jest.fn();
setPreVisit(preVisit);
expect(globalThis.__sbPreVisit).toBe(preVisit);
});
});

describe('setPostRender', () => {
it('sets the postRender function', () => {
const postRender = jest.fn();
setPostRender(postRender);
expect(globalThis.__sbPostRender).toBe(postRender);
describe('setPostVisit', () => {
it('sets the postVisit function', () => {
const postVisit = jest.fn();
setPostVisit(postVisit);
expect(globalThis.__sbPostVisit).toBe(postVisit);
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/playwright/transformPlaywright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const testPrefixer = template(
{
plugins: ['jsx'],
}
) as any as TestPrefixer;
) as unknown as TestPrefixer;

const makeTitleFactory = (filename: string) => {
const { workingDir, normalizedStoriesEntries } = getStorybookMetadata();
Expand Down
2 changes: 1 addition & 1 deletion src/playwright/transformPlaywrightJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const makeTest = ({
shouldSkip: boolean;
metaOrStoryPlay: boolean;
}): t.Statement => {
const result: any = testPrefixer({
const result = testPrefixer({
name: t.stringLiteral(entry.name),
title: t.stringLiteral(entry.title),
id: t.stringLiteral(entry.id),
Expand Down
4 changes: 2 additions & 2 deletions src/setup-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ export const setupPage = async (page: Page, browserContext: BrowserContext) => {
);
}

const testRunnerConfig = getTestRunnerConfig();
const testRunnerConfig = getTestRunnerConfig() || {};
if (testRunnerConfig?.prepare) {
await testRunnerConfig.prepare({ page, browserContext, testRunnerConfig });
} else {
if (testRunnerConfig) await defaultPrepare({ page, browserContext, testRunnerConfig });
await defaultPrepare({ page, browserContext, testRunnerConfig });
}

// if we ever want to log something from the browser to node
Expand Down
2 changes: 1 addition & 1 deletion src/test-storybook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async function executeJestPlaywright(args: JestOptions) {
await jest.run(argv);
}

async function checkStorybook(url: any) {
async function checkStorybook(url: string) {
try {
const headers = await getHttpHeaders(url);
const res = await fetch(url, { method: 'GET', headers });
Expand Down
6 changes: 3 additions & 3 deletions src/util/__snapshots__/getStorybookMain.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getStorybookMain no stories should throw an error if no stories are defined 1`] = `
"Could not find stories in main.js in .storybook.
"Could not find stories in main.js in ".storybook".
If you are using a mono-repository, please run the test-runner only against your sub-package, which contains a .storybook folder with "stories" defined in main.js.
You can change the config directory by using --config-dir <path-to-dir>"
`;
exports[`getStorybookMain no stories should throw an error if stories list is empty 1`] = `
"Could not find stories in main.js in .storybook.
"Could not find stories in main.js in ".storybook".
If you are using a mono-repository, please run the test-runner only against your sub-package, which contains a .storybook folder with "stories" defined in main.js.
You can change the config directory by using --config-dir <path-to-dir>"
`;
exports[`getStorybookMain should throw an error if no configuration is found 1`] = `"Could not load main.js in .storybook. Is the config directory correct? You can change it by using --config-dir <path-to-dir>"`;
exports[`getStorybookMain should throw an error if no configuration is found 1`] = `"Could not load main.js in .storybook. Is the ".storybook" config directory correct? You can change it by using --config-dir <path-to-dir>"`;
5 changes: 3 additions & 2 deletions src/util/getCliOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ describe('getCliOptions', () => {

it('handles extra arguments correctly', () => {
jest.spyOn(cliHelper, 'getParsedCliOptions').mockReturnValue({
options: { version: true, cache: false, env: 'node' },
options: { version: true, cache: false, env: 'node' } as any,
extraArgs: ['--watch', '--coverage'],
});
const opts = getCliOptions();
expect(opts.jestOptions).toEqual([
'--version',
'--no-cache',
'--env="node"',
'--env',
'node',
'--watch',
'--coverage',
]);
Expand Down
19 changes: 9 additions & 10 deletions src/util/getCliOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,19 @@ export const getCliOptions = (): CliOptions => {
jestOptions: process.argv.splice(0, 2),
};

const finalOptions = Object.keys(allOptions).reduce((acc: CliOptions, key: string) => {
if (STORYBOOK_RUNNER_COMMANDS.includes(key as StorybookRunnerCommand)) {
copyOption(
acc.runnerOptions,
key as StorybookRunnerCommand,
allOptions[key as StorybookRunnerCommand]
);
const finalOptions = Object.keys(allOptions).reduce((acc: CliOptions, _key: string) => {
let key = _key as StorybookRunnerCommand;
let optionValue = allOptions[key];

if (STORYBOOK_RUNNER_COMMANDS.includes(key)) {
copyOption(acc.runnerOptions, key, optionValue);
} else {
if (allOptions[key as StorybookRunnerCommand] === true) {
if (optionValue === true) {
acc.jestOptions.push(`--${key}`);
} else if (allOptions[key as StorybookRunnerCommand] === false) {
} else if (optionValue === false) {
acc.jestOptions.push(`--no-${key}`);
} else {
acc.jestOptions.push(`--${key}="${allOptions[key as StorybookRunnerCommand]}"`);
acc.jestOptions.push(`--${key}`, `${optionValue}`);
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/util/getStorybookMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import dedent from 'ts-dedent';

let storybookMainConfig = new Map<string, StorybookConfig>();

export const getStorybookMain = (configDir: string) => {
export const getStorybookMain = (configDir = '.storybook') => {
if (storybookMainConfig.has(configDir)) {
return storybookMainConfig.get(configDir);
return storybookMainConfig.get(configDir) as StorybookConfig;
} else {
storybookMainConfig.set(configDir, serverRequire(join(resolve(configDir), 'main')));
}
Expand All @@ -16,14 +16,14 @@ export const getStorybookMain = (configDir: string) => {

if (!mainConfig) {
throw new Error(
`Could not load main.js in ${configDir}. Is the config directory correct? You can change it by using --config-dir <path-to-dir>`
`Could not load main.js in ${configDir}. Is the "${configDir}" config directory correct? You can change it by using --config-dir <path-to-dir>`
);
}

if (!mainConfig.stories || mainConfig.stories.length === 0) {
throw new Error(
dedent`
Could not find stories in main.js in ${configDir}.
Could not find stories in main.js in "${configDir}".
If you are using a mono-repository, please run the test-runner only against your sub-package, which contains a .storybook folder with "stories" defined in main.js.
You can change the config directory by using --config-dir <path-to-dir>
`
Expand Down
6 changes: 3 additions & 3 deletions src/util/getStorybookMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { StoriesEntry } from '@storybook/types';

export const getStorybookMetadata = () => {
const workingDir = getProjectRoot();
const configDir = process.env.STORYBOOK_CONFIG_DIR || '';
const configDir = process.env.STORYBOOK_CONFIG_DIR || '.storybook';

const main = getStorybookMain(configDir);
const normalizedStoriesEntries = normalizeStories(main?.stories as StoriesEntry[], {
const normalizedStoriesEntries = normalizeStories(main.stories as StoriesEntry[], {
configDir,
workingDir,
}).map((specifier) => ({
Expand All @@ -22,7 +22,7 @@ export const getStorybookMetadata = () => {
.join(';');

// @ts-ignore -- this is added in @storybook/core-common@6.5, which we don't depend on
const lazyCompilation = !!main?.core?.builder?.options?.lazyCompilation;
const lazyCompilation = !!main.core?.builder?.options?.lazyCompilation;

return {
configDir,
Expand Down
4 changes: 1 addition & 3 deletions src/util/getTestRunnerConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { serverRequire } from '@storybook/core-common';
import { TestRunnerConfig } from '../playwright/hooks';
import { getTestRunnerConfig, loaded } from './getTestRunnerConfig';
import { getTestRunnerConfig } from './getTestRunnerConfig';
import { join, resolve } from 'path';

const testRunnerConfig: TestRunnerConfig = {
Expand Down Expand Up @@ -43,7 +42,6 @@ describe('getTestRunnerConfig', () => {
);

const result = getTestRunnerConfig(configDir);
console.log(result);

expect(result).toEqual(testRunnerConfig);
expect(require('@storybook/core-common').serverRequire).toHaveBeenCalledWith(
Expand Down
2 changes: 1 addition & 1 deletion src/util/getTestRunnerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ let testRunnerConfig: TestRunnerConfig;
let loaded = false;

export const getTestRunnerConfig = (
configDir = process.env.STORYBOOK_CONFIG_DIR || ''
configDir = process.env.STORYBOOK_CONFIG_DIR || '.storybook'
): TestRunnerConfig | undefined => {
// testRunnerConfig can be undefined
if (loaded) {
Expand Down

0 comments on commit ef775c1

Please sign in to comment.