add beforeAllHook to portable stories

This commit is contained in:
Yann Braga 2024-06-18 13:40:38 +02:00
parent 1f6c1832f9
commit ee0653d65d
6 changed files with 55 additions and 12 deletions

View File

@ -10,6 +10,7 @@ import type {
StoryAnnotationsOrFn,
Store_CSFExports,
StoriesWithPartialProps,
NamedOrDefaultProjectAnnotations,
} from '@storybook/types';
// ! ATTENTION: This needs to be a relative import so it gets prebundled. This is to avoid ESM issues in Nextjs + Jest setups
@ -34,9 +35,11 @@ import type { ReactRenderer, Meta } from '@storybook/react';
* @param projectAnnotations - e.g. (import projectAnnotations from '../.storybook/preview')
*/
export function setProjectAnnotations(
projectAnnotations: ProjectAnnotations<ReactRenderer> | ProjectAnnotations<ReactRenderer>[]
) {
originalSetProjectAnnotations<ReactRenderer>(projectAnnotations);
projectAnnotations:
| NamedOrDefaultProjectAnnotations<ReactRenderer>
| NamedOrDefaultProjectAnnotations<ReactRenderer>[]
): ProjectAnnotations<ReactRenderer> {
return originalSetProjectAnnotations<ReactRenderer>(projectAnnotations);
}
// This will not be necessary once we have auto preset loading

View File

@ -26,6 +26,39 @@ describe('composeStory', () => {
tags: ['metaTag'],
};
it('should return beforeAll as part of project annotations', async () => {
const spy = vi.fn();
const annotations = {
beforeAll: async () => {
spy();
},
};
const finalAnnotations = setProjectAnnotations(annotations);
await finalAnnotations.beforeAll?.();
expect(spy).toHaveBeenCalled();
});
it('should return composed project annotations via setProjectAnnotations', () => {
const firstAnnotations = {
parameters: { foo: 'bar' },
tags: ['autodocs'],
};
const secondAnnotations = {
args: {
foo: 'bar',
},
};
const finalAnnotations = setProjectAnnotations([firstAnnotations, secondAnnotations]);
expect(finalAnnotations).toEqual(
expect.objectContaining({
parameters: { foo: 'bar' },
args: { foo: 'bar' },
tags: ['autodocs'],
})
);
});
it('should compose project annotations in all module formats', () => {
setProjectAnnotations([defaultExportAnnotations, namedExportAnnotations]);

View File

@ -35,8 +35,10 @@ const DEFAULT_STORY_NAME = 'Unnamed Story';
function extractAnnotation<TRenderer extends Renderer = Renderer>(
annotation: NamedOrDefaultProjectAnnotations<TRenderer>
) {
if (!annotation) return {};
// support imports such as
// import * as annotations from '.storybook/preview'
// import annotations from '.storybook/preview'
// in both cases: 1 - the file has a default export; 2 - named exports only
return 'default' in annotation ? annotation.default : annotation;
}
@ -45,9 +47,11 @@ export function setProjectAnnotations<TRenderer extends Renderer = Renderer>(
projectAnnotations:
| NamedOrDefaultProjectAnnotations<TRenderer>
| NamedOrDefaultProjectAnnotations<TRenderer>[]
) {
): ProjectAnnotations<TRenderer> {
const annotations = Array.isArray(projectAnnotations) ? projectAnnotations : [projectAnnotations];
globalProjectAnnotations = composeConfigs(annotations.map(extractAnnotation));
return globalProjectAnnotations;
}
const cleanups: { storyName: string; callback: CleanupCallback }[] = [];
@ -165,7 +169,7 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
cleanups.push(
...(await story.applyBeforeEach(context))
.filter(Boolean)
.map((callback) => ({ storyName, callback }))
.map((callback: () => void) => ({ storyName, callback }))
);
},
args: story.initialArgs as Partial<TArgs>,

View File

@ -35,8 +35,8 @@ export function setProjectAnnotations(
projectAnnotations:
| NamedOrDefaultProjectAnnotations<ReactRenderer>
| NamedOrDefaultProjectAnnotations<ReactRenderer>[]
) {
originalSetProjectAnnotations<ReactRenderer>(projectAnnotations);
): ProjectAnnotations<ReactRenderer> {
return originalSetProjectAnnotations<ReactRenderer>(projectAnnotations);
}
// This will not be necessary once we have auto preset loading

View File

@ -10,6 +10,7 @@ import type {
Store_CSFExports,
StoriesWithPartialProps,
ComposedStoryFn,
NamedOrDefaultProjectAnnotations,
} from '@storybook/types';
import * as svelteProjectAnnotations from './entry-preview';
@ -51,9 +52,11 @@ type MapToComposed<TModule> = {
* @param projectAnnotations - e.g. (import projectAnnotations from '../.storybook/preview')
*/
export function setProjectAnnotations(
projectAnnotations: ProjectAnnotations<SvelteRenderer> | ProjectAnnotations<SvelteRenderer>[]
) {
originalSetProjectAnnotations<SvelteRenderer>(projectAnnotations);
projectAnnotations:
| NamedOrDefaultProjectAnnotations<SvelteRenderer>
| NamedOrDefaultProjectAnnotations<SvelteRenderer>[]
): ProjectAnnotations<SvelteRenderer> {
return originalSetProjectAnnotations<SvelteRenderer>(projectAnnotations);
}
// This will not be necessary once we have auto preset loading

View File

@ -44,8 +44,8 @@ export function setProjectAnnotations(
projectAnnotations:
| NamedOrDefaultProjectAnnotations<VueRenderer>
| NamedOrDefaultProjectAnnotations<VueRenderer>[]
) {
originalSetProjectAnnotations<VueRenderer>(projectAnnotations);
): ProjectAnnotations<VueRenderer> {
return originalSetProjectAnnotations<VueRenderer>(projectAnnotations);
}
/**