Skip to content

Commit

Permalink
refactor: Update various files
Browse files Browse the repository at this point in the history
- Update test snapshots and test files in the `csf` and `playwright` directories.
- Update `hooks.ts`, `index.ts`, `transformPlaywright.test.ts`, `transformPlaywright.ts`, `transformPlaywrightJson.test.ts`, `transformPlaywrightJson.ts`, `setup-page.ts`, `test-storybook.ts`, `getCliOptions.test.ts`, `getCliOptions.ts`, `getParsedCliOptions.test.ts`, `getStorybookMain.ts`, `getStorybookMetadata.ts`, `getTestRunnerConfig.test.ts`, `getTestRunnerConfig.ts`, and `tsconfig.json`.
- These changes were made to improve the codebase and ensure compatibility with the latest dependencies and standards.
  • Loading branch information
bryanjtc committed Nov 10, 2023
1 parent 44bae0d commit dc692b4
Show file tree
Hide file tree
Showing 19 changed files with 113 additions and 95 deletions.
9 changes: 9 additions & 0 deletions src/csf/__snapshots__/transformCsf.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1314,3 +1314,12 @@ if (!require.main) {
});
}"
`;
exports[`transformCsf returns empty result if there are no stories 1`] = `
"
export default {
title: 'Button',
};
"
`;
12 changes: 12 additions & 0 deletions src/csf/transformCsf.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ describe('transformCsf', () => {
expect(result).toEqual(expectedCode);
});

it('returns empty result if there are no stories', () => {
const csfCode = `
export default {
title: 'Button',
};
`;

const result = transformCsf(csfCode, {});

expect(result).toMatchSnapshot();
});

it('calls the testPrefixer function for each test', () => {
const csfCode = `
export default {
Expand Down
7 changes: 3 additions & 4 deletions src/csf/transformCsf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const makePlayTest = (
return [
t.expressionStatement(
t.callExpression(t.identifier('it'), [
t.stringLiteral(!!metaOrStoryPlay ? 'play-test' : 'smoke-test'),
t.stringLiteral(metaOrStoryPlay ? 'play-test' : 'smoke-test'),
prefixFunction(key, title, metaOrStoryPlay as t.Expression, testPrefix),
])
),
Expand Down Expand Up @@ -100,9 +100,9 @@ export const transformCsf = (
beforeEachPrefixer,
insertTestIfEmpty,
makeTitle,
}: TransformOptions = {}
}: TransformOptions
) => {
const csf = loadCsf(code, { makeTitle: makeTitle || ((userTitle: string) => userTitle) });
const csf = loadCsf(code, { makeTitle: makeTitle ?? ((userTitle: string) => userTitle) });
csf.parse();

const storyExports = Object.keys(csf._stories);
Expand All @@ -125,7 +125,6 @@ export const transformCsf = (
if (tests.length) {
return makeDescribe(key, tests);
}
return null;
})
.filter(Boolean) as babel.types.Statement[];

Expand Down
2 changes: 1 addition & 1 deletion src/playwright/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type PrepareContext = {
};

export type TestHook = (page: Page, context: TestContext) => Promise<void>;
export type HttpHeaderSetter = (url: string) => Promise<Record<string, any>>;
export type HttpHeaderSetter = (url: string) => Promise<Record<string, string>>;
export type PrepareSetter = (context: PrepareContext) => Promise<void>;

export interface TestRunnerConfig {
Expand Down
2 changes: 1 addition & 1 deletion src/playwright/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { transformSync as swcTransform } from '@swc/core';
import { transformPlaywright } from './transformPlaywright';

export const process = (src: string, filename: string, config: any) => {
export const process = (src: string, filename: string) => {
const csfTest = transformPlaywright(src, filename);

const result = swcTransform(csfTest, {
Expand Down
4 changes: 2 additions & 2 deletions src/playwright/transformPlaywright.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ jest.mock('@storybook/core-common', () => ({
}));

expect.addSnapshotSerializer({
print: (val: any) => val.trim(),
test: (val: any) => true,
print: (val: unknown) => (typeof val === 'string' ? val.trim() : String(val)),
test: () => true,
});

describe('Playwright', () => {
Expand Down
21 changes: 14 additions & 7 deletions src/playwright/transformPlaywright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ const coverageErrorMessage = dedent`
More info: https://github.com/storybookjs/test-runner#setting-up-code-coverage
`;

export const testPrefixer = template(
`
export const testPrefixer: TestPrefixer = (context) => {
return template(
`
console.log({ id: %%id%%, title: %%title%%, name: %%name%%, storyExport: %%storyExport%% });
async () => {
const testFn = async() => {
Expand Down Expand Up @@ -62,14 +63,20 @@ export const testPrefixer = template(
}
}
`,
{
plugins: ['jsx'],
}
) as any as TestPrefixer;
{
plugins: ['jsx'],
}
)({
id: context.id,
title: context.title,
name: context.name,
storyExport: context.storyExport,
});
};

const makeTitleFactory = (filename: string) => {
const { workingDir, normalizedStoriesEntries } = getStorybookMetadata();
const filePath = './' + relative(workingDir, filename);
const filePath = `./${relative(workingDir, filename)}`;

return (userTitle: string) =>
userOrAutoTitle(filePath, normalizedStoriesEntries, userTitle) as string;
Expand Down
44 changes: 19 additions & 25 deletions src/playwright/transformPlaywrightJson.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { transformPlaywrightJson } from './transformPlaywrightJson';
import {
UnsupportedVersion,
V3StoriesIndex,
V4Index,
transformPlaywrightJson,
} from './transformPlaywrightJson';

describe('Playwright Json', () => {
describe('v4 indexes', () => {
Expand All @@ -10,22 +15,19 @@ describe('Playwright Json', () => {
id: 'example-header--logged-in',
title: 'Example/Header',
name: 'Logged In',
importPath: './stories/basic/Header.stories.js',
},
'example-header--logged-out': {
id: 'example-header--logged-out',
title: 'Example/Header',
name: 'Logged Out',
importPath: './stories/basic/Header.stories.js',
},
'example-page--logged-in': {
id: 'example-page--logged-in',
title: 'Example/Page',
name: 'Logged In',
importPath: './stories/basic/Page.stories.js',
},
},
};
} satisfies V4Index;
expect(transformPlaywrightJson(input)).toMatchInlineSnapshot(`
{
"example-header": "describe("Example/Header", () => {
Expand Down Expand Up @@ -207,16 +209,14 @@ describe('Playwright Json', () => {
id: 'example-introduction--page',
title: 'Example/Introduction',
name: 'Page',
importPath: './stories/basic/Introduction.stories.mdx',
},
'example-page--logged-in': {
id: 'example-page--logged-in',
title: 'Example/Page',
name: 'Logged In',
importPath: './stories/basic/Page.stories.js',
},
},
};
} satisfies V4Index;
expect(transformPlaywrightJson(input)).toMatchInlineSnapshot(`
{
"example-page": "describe("Example/Page", () => {
Expand Down Expand Up @@ -289,9 +289,6 @@ describe('Playwright Json', () => {
id: 'example-header--logged-in',
title: 'Example/Header',
name: 'Logged In',
importPath: './stories/basic/Header.stories.js',
kind: 'Example/Header',
story: 'Logged In',
parameters: {
__id: 'example-header--logged-in',
docsOnly: false,
Expand All @@ -302,9 +299,6 @@ describe('Playwright Json', () => {
id: 'example-header--logged-out',
title: 'Example/Header',
name: 'Logged Out',
importPath: './stories/basic/Header.stories.js',
kind: 'Example/Header',
story: 'Logged Out',
parameters: {
__id: 'example-header--logged-out',
docsOnly: false,
Expand All @@ -315,17 +309,14 @@ describe('Playwright Json', () => {
id: 'example-page--logged-in',
title: 'Example/Page',
name: 'Logged In',
importPath: './stories/basic/Page.stories.js',
kind: 'Example/Page',
story: 'Logged In',
parameters: {
__id: 'example-page--logged-in',
docsOnly: false,
fileName: './stories/basic/Page.stories.js',
},
},
},
};
} satisfies V3StoriesIndex;
expect(transformPlaywrightJson(input)).toMatchInlineSnapshot(`
{
"example-header": "describe("Example/Header", () => {
Expand Down Expand Up @@ -506,9 +497,6 @@ describe('Playwright Json', () => {
id: 'example-introduction--page',
title: 'Example/Introduction',
name: 'Page',
importPath: './stories/basic/Introduction.stories.mdx',
kind: 'Example/Introduction',
story: 'Page',
parameters: {
__id: 'example-introduction--page',
docsOnly: true,
Expand All @@ -519,17 +507,14 @@ describe('Playwright Json', () => {
id: 'example-page--logged-in',
title: 'Example/Page',
name: 'Logged In',
importPath: './stories/basic/Page.stories.js',
kind: 'Example/Page',
story: 'Logged In',
parameters: {
__id: 'example-page--logged-in',
docsOnly: false,
fileName: './stories/basic/Page.stories.js',
},
},
},
};
} satisfies V3StoriesIndex;
expect(transformPlaywrightJson(input)).toMatchInlineSnapshot(`
{
"example-page": "describe("Example/Page", () => {
Expand Down Expand Up @@ -593,3 +578,12 @@ describe('Playwright Json', () => {
});
});
});

describe('unsupported index', () => {
it('throws an error for unsupported versions', () => {
const unsupportedVersion = { v: 1 } satisfies UnsupportedVersion;
expect(() => transformPlaywrightJson(unsupportedVersion)).toThrowError(
`Unsupported version ${unsupportedVersion.v}`
);
});
});
21 changes: 14 additions & 7 deletions src/playwright/transformPlaywrightJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { ComponentTitle, StoryId, StoryName, toId } from '@storybook/csf';
import { testPrefixer } from './transformPlaywright';

const makeTest = (entry: V4Entry): t.Statement => {
const result: any = testPrefixer({
const result = testPrefixer({
name: t.stringLiteral(entry.name),
title: t.stringLiteral(entry.title),
id: t.stringLiteral(entry.id),
// FIXME
storyExport: t.identifier(entry.id),
});
const stmt = result[1] as t.ExpressionStatement;
const stmt = (result as Array<t.ExpressionStatement>)[1];
return t.expressionStatement(
t.callExpression(t.identifier('it'), [t.stringLiteral('test'), stmt.expression])
);
Expand All @@ -28,16 +28,23 @@ const makeDescribe = (title: string, stmts: t.Statement[]) => {
};

type V4Entry = { type?: 'story' | 'docs'; id: StoryId; name: StoryName; title: ComponentTitle };
type V4Index = {
export type V4Index = {
v: 4;
entries: Record<StoryId, V4Entry>;
};

type V3Story = Omit<V4Entry, 'type'> & { parameters?: Record<string, any> };
type V3StoriesIndex = {
type StoryParameters = {
__id: StoryId;
docsOnly?: boolean;
fileName?: string;
};

type V3Story = Omit<V4Entry, 'type'> & { parameters?: StoryParameters };
export type V3StoriesIndex = {
v: 3;
stories: Record<StoryId, V3Story>;
};
export type UnsupportedVersion = { v: number };
const isV3DocsOnly = (stories: V3Story[]) => stories.length === 1 && stories[0].name === 'Page';

function v3TitleMapToV4TitleMap(titleIdToStories: Record<string, V3Story[]>) {
Expand All @@ -49,7 +56,7 @@ function v3TitleMapToV4TitleMap(titleIdToStories: Record<string, V3Story[]>) {
({
type: isV3DocsOnly(stories) ? 'docs' : 'story',
...story,
} as V4Entry)
} satisfies V4Entry)
),
])
);
Expand All @@ -68,7 +75,7 @@ function groupByTitleId<T extends { title: ComponentTitle }>(entries: T[]) {
* Generate one test file per component so that Jest can
* run them in parallel.
*/
export const transformPlaywrightJson = (index: Record<string, any>) => {
export const transformPlaywrightJson = (index: V3StoriesIndex | V4Index | UnsupportedVersion) => {
let titleIdToEntries: Record<string, V4Entry[]>;
if (index.v === 3) {
const titleIdToStories = groupByTitleId<V3Story>(
Expand Down
14 changes: 6 additions & 8 deletions src/setup-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const sanitizeURL = (url: string) => {
let finalURL = url;
// prepend URL protocol if not there
if (finalURL.indexOf('http://') === -1 && finalURL.indexOf('https://') === -1) {
finalURL = 'http://' + finalURL;
finalURL = `http://${finalURL}`;
}

// remove iframe.html if present
Expand All @@ -42,8 +42,8 @@ const sanitizeURL = (url: string) => {
finalURL = finalURL.replace(/index.html\s*$/, '');

// add forward slash at the end if not there
if (finalURL.slice(-1) !== '/') {
finalURL = finalURL + '/';
if (!finalURL.endsWith('/')) {
finalURL = `${finalURL}/`;
}

return finalURL;
Expand All @@ -53,7 +53,7 @@ export const setupPage = async (page: Page, browserContext: BrowserContext) => {
const targetURL = process.env.TARGET_URL;
const failOnConsole = process.env.TEST_CHECK_CONSOLE;

const viewMode = process.env.VIEW_MODE || 'story';
const viewMode = process.env.VIEW_MODE ?? 'story';
const renderedEvent = viewMode === 'docs' ? 'docsRendered' : 'storyRendered';
const { packageJson } = (await readPackageUp()) as NormalizedReadResult;
const { version: testRunnerVersion } = packageJson;
Expand All @@ -72,9 +72,7 @@ export const setupPage = async (page: Page, browserContext: BrowserContext) => {
const testRunnerConfig = getTestRunnerConfig();
if (testRunnerConfig?.prepare) {
await testRunnerConfig.prepare({ page, browserContext, testRunnerConfig });
} else {
if (testRunnerConfig) await defaultPrepare({ page, browserContext, testRunnerConfig });
}
} else if (testRunnerConfig) await defaultPrepare({ page, browserContext, testRunnerConfig });

// if we ever want to log something from the browser to node
await page.exposeBinding('logToPage', (_, message) => console.log(message));
Expand Down Expand Up @@ -247,7 +245,7 @@ export const setupPage = async (page: Page, browserContext: BrowserContext) => {
constructor(storyId, errorMessage, logs = []) {
super(errorMessage);
this.name = 'StorybookTestRunnerError';
const storyUrl = \`${referenceURL || targetURL}?path=/story/\${storyId}\`;
const storyUrl = \`${referenceURL ?? targetURL}?path=/story/\${storyId}\`;
const finalStoryUrl = \`\${storyUrl}&addonPanel=storybook/interactions/panel\`;
const separator = '\\n\\n--------------------------------------------------';
const extraLogs = logs.length > 0 ? separator + "\\n\\nBrowser logs:\\n\\n"+ logs.join('\\n\\n') : '';
Expand Down
Loading

0 comments on commit dc692b4

Please sign in to comment.