Introduce run over play in portable stories, and revert back play changes of 8.2

This commit is contained in:
Kasper Peulen 2024-07-31 13:32:15 +02:00
parent 8bccacece2
commit 653324dca7
17 changed files with 42857 additions and 158 deletions

View File

@ -89,25 +89,8 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
normalizedComponentAnnotations
);
// TODO: Remove this in 9.0
// We can only use the renderToCanvas definition of the default config when testingLibraryRender is set
// This makes sure, that when the user doesn't do this, and doesn't provide its own renderToCanvas definition,
// we fall back to the < 8.1 behavior of the play function.
const fallback =
defaultConfig &&
!globalProjectAnnotations?.testingLibraryRender &&
!projectAnnotations?.testingLibraryRender;
const normalizedProjectAnnotations = normalizeProjectAnnotations<TRenderer>(
composeConfigs([
{
...defaultConfig,
renderToCanvas: fallback ? undefined : defaultConfig?.renderToCanvas,
},
globalProjectAnnotations,
projectAnnotations ?? {},
])
composeConfigs([defaultConfig ?? {}, globalProjectAnnotations, projectAnnotations ?? {}])
);
const story = prepareStory<TRenderer>(
@ -130,7 +113,7 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
loaded: {},
abortSignal: new AbortController().signal,
step: (label, play) => story.runStep(label, play, context),
canvasElement: globalThis?.document?.body,
canvasElement: null!,
canvas: {} as Canvas,
...story,
context: null!,
@ -149,6 +132,7 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
id: story.id,
name: story.name,
tags: story.tags,
showMain: () => {},
showError: (error) => {},
showException: (error) => {},
forceRemount: true,
@ -171,28 +155,23 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
let loadedContext: StoryContext<TRenderer> | undefined;
// TODO: Remove in 9.0
const backwardsCompatiblePlay = async (
extraContext?: Partial<StoryContext<TRenderer, Partial<TArgs>>>
) => {
const play = async (extraContext?: Partial<StoryContext<TRenderer, Partial<TArgs>>>) => {
const context = initializeContext();
context.canvasElement ??= globalThis.document.body;
if (loadedContext) {
context.loaded = loadedContext.loaded;
}
Object.assign(context, extraContext);
return story.playFunction!(context);
};
const newPlay = (extraContext?: Partial<StoryContext<TRenderer, Partial<TArgs>>>) => {
const run = (extraContext?: Partial<StoryContext<TRenderer, Partial<TArgs>>>) => {
const context = initializeContext();
Object.assign(context, extraContext);
return playStory(story, context);
return runStory(story, context);
};
const playFunction =
!story.renderToCanvas && story.playFunction
? backwardsCompatiblePlay
: !story.renderToCanvas && !story.playFunction
? undefined
: newPlay;
const playFunction = story.playFunction ? play : undefined;
const composedStory: ComposedStoryFn<TRenderer, Partial<TArgs>> = Object.assign(
function storyFn(extraArgs?: Partial<TArgs>) {
@ -226,6 +205,7 @@ export function composeStory<TRenderer extends Renderer = Renderer, TArgs extend
parameters: story.parameters as Parameters,
argTypes: story.argTypes as StrictArgTypes<TArgs>,
play: playFunction!,
run,
tags: story.tags,
}
);
@ -325,13 +305,24 @@ export function createPlaywrightTest<TFixture extends { extend: any }>(
// TODO At some point this function should live in prepareStory and become the core of StoryRender.render as well.
// Will make a follow up PR for that
async function playStory<TRenderer extends Renderer>(
async function runStory<TRenderer extends Renderer>(
story: PreparedStory<TRenderer>,
context: StoryContext<TRenderer>
) {
for (const callback of [...cleanups].reverse()) await callback();
cleanups.length = 0;
if (!context.canvasElement) {
const container = document.createElement('div');
globalThis?.document?.body?.appendChild(container);
context.canvasElement = container;
cleanups.push(() => {
if (globalThis?.document?.body?.contains(container)) {
globalThis?.document?.body?.removeChild(container);
}
});
}
context.loaded = await story.applyLoaders(context);
if (context.abortSignal.aborted) return;

View File

@ -44,7 +44,8 @@ export type ComposedStoryFn<
> = PartialArgsStoryFn<TRenderer, TArgs> & {
args: TArgs;
id: StoryId;
play: (context?: Partial<StoryContext<TRenderer, Partial<TArgs>>>) => Promise<void>;
play?: (context?: Partial<StoryContext<TRenderer, Partial<TArgs>>>) => Promise<void>;
run: (context?: Partial<StoryContext<TRenderer, Partial<TArgs>>>) => Promise<void>;
load: () => Promise<void>;
storyName: string;
parameters: Parameters;

View File

@ -53,7 +53,7 @@ describe('renders', () => {
});
it('should render component mounted in play function', async () => {
await MountInPlayFunction.play();
await MountInPlayFunction.run();
expect(screen.getByTestId('spy-data').textContent).toEqual('mockFn return value');
expect(screen.getByTestId('loaded-data').textContent).toEqual('loaded data');
@ -65,7 +65,7 @@ describe('renders', () => {
expect(getByTestId('spy-data').textContent).toEqual('mockFn return value');
expect(getByTestId('loaded-data').textContent).toEqual('loaded data');
// spy assertions happen in the play function and should work
await LoaderStory.play!();
await LoaderStory.run!();
});
});
@ -125,7 +125,7 @@ describe('CSF3', () => {
it('renders with play function without canvas element', async () => {
const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default);
await CSF3InputFieldFilled.play();
await CSF3InputFieldFilled.run();
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -138,7 +138,7 @@ describe('CSF3', () => {
console.log(div.tagName);
document.body.appendChild(div);
await CSF3InputFieldFilled.play({ canvasElement: div });
await CSF3InputFieldFilled.run({ canvasElement: div });
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -185,6 +185,6 @@ const testCases = Object.values(composeStories(stories)).map(
);
it.each(testCases)('Renders %s story', async (_storyName, Story) => {
if (_storyName === 'CSF2StoryWithLocale') return;
await Story.play();
await Story.run();
expect(document.body).toMatchSnapshot();
});

View File

@ -45,11 +45,16 @@ export function setProjectAnnotations(
// This will not be necessary once we have auto preset loading
export const INTERNAL_DEFAULT_PROJECT_ANNOTATIONS: ProjectAnnotations<ReactRenderer> = {
...reactProjectAnnotations,
renderToCanvas: ({
storyContext: { context, unboundStoryFn: Story, testingLibraryRender: render, canvasElement },
}) => {
if (render == null) throw new TestingLibraryMustBeConfiguredError();
const { unmount } = render(<Story {...context} />, { baseElement: context.canvasElement });
renderToCanvas: (renderContext, canvasElement) => {
if (renderContext.storyContext.testingLibraryRender == null) {
throw new TestingLibraryMustBeConfiguredError();
// Enable for 8.3
// return reactProjectAnnotations.renderToCanvas(renderContext, canvasElement);
}
const {
storyContext: { context, unboundStoryFn: Story, testingLibraryRender: render },
} = renderContext;
const { unmount } = render(<Story {...context} />, { container: context.canvasElement });
return unmount;
},
};

View File

@ -70,7 +70,7 @@ describe('renders', () => {
expect(getByTestId('spy-data').textContent).toEqual('mockFn return value');
expect(getByTestId('loaded-data').textContent).toEqual('loaded data');
// spy assertions happen in the play function and should work
await LoaderStory.play!();
await LoaderStory.run!();
});
});
@ -120,7 +120,7 @@ describe('CSF3', () => {
it('renders with play function without canvas element', async () => {
const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default);
await CSF3InputFieldFilled.play();
await CSF3InputFieldFilled.run();
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -132,7 +132,7 @@ describe('CSF3', () => {
const div = document.createElement('div');
document.body.appendChild(div);
await CSF3InputFieldFilled.play({ canvasElement: div });
await CSF3InputFieldFilled.run({ canvasElement: div });
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -171,6 +171,6 @@ const testCases = Object.values(composeStories(stories)).map(
);
it.each(testCases)('Renders %s story', async (_storyName, Story) => {
if (_storyName === 'CSF2StoryWithLocale') return;
await Story.play();
await Story.run();
expect(document.body).toMatchSnapshot();
});

View File

@ -63,8 +63,16 @@ export function setProjectAnnotations(
// This will not be necessary once we have auto preset loading
export const INTERNAL_DEFAULT_PROJECT_ANNOTATIONS: ProjectAnnotations<SvelteRenderer> = {
...svelteProjectAnnotations,
renderToCanvas: ({ storyFn, storyContext: { testingLibraryRender: render, canvasElement } }) => {
if (render == null) throw new TestingLibraryMustBeConfiguredError();
renderToCanvas: (renderContext, canvasElement) => {
if (renderContext.storyContext.testingLibraryRender == null) {
throw new TestingLibraryMustBeConfiguredError();
// Enable for 8.3
// return svelteProjectAnnotations.renderToCanvas(renderContext, canvasElement);
}
const {
storyFn,
storyContext: { testingLibraryRender: render },
} = renderContext;
const { Component, props } = storyFn();
const { unmount } = render(Component, { props, target: canvasElement });
return unmount;

View File

@ -52,7 +52,7 @@ describe('renders', () => {
expect(getByTestId('spy-data').textContent).toEqual('mockFn return value');
expect(getByTestId('loaded-data').textContent).toEqual('loaded data');
// spy assertions happen in the play function and should work
await LoaderStory.play!();
await LoaderStory.run!();
});
});
@ -103,7 +103,7 @@ describe('CSF3', () => {
it('renders with play function', async () => {
const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default);
await CSF3InputFieldFilled.play();
await CSF3InputFieldFilled.run();
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -145,7 +145,7 @@ describe('ComposeStories types', () => {
const testCases = Object.values(composeStories(stories)).map((Story) => [Story.storyName, Story]);
it.each(testCases)('Renders %s story', async (_storyName, Story) => {
if (typeof Story === 'string' || _storyName === 'CSF2StoryWithLocale') return;
await Story.play();
await Story.run();
await new Promise((resolve) => setTimeout(resolve, 0));
expect(document.body).toMatchSnapshot();
});

View File

@ -53,9 +53,17 @@ export function setProjectAnnotations(
// This will not be necessary once we have auto preset loading
export const vueProjectAnnotations: ProjectAnnotations<VueRenderer> = {
...defaultProjectAnnotations,
renderToCanvas: ({ storyFn, storyContext: { testingLibraryRender: render, canvasElement } }) => {
if (render == null) throw new TestingLibraryMustBeConfiguredError();
const { unmount } = render(storyFn(), { baseElement: canvasElement });
renderToCanvas: (renderContext, canvasElement) => {
if (renderContext.storyContext.testingLibraryRender == null) {
throw new TestingLibraryMustBeConfiguredError();
// Enable for 8.3
// return defaultProjectAnnotations.renderToCanvas(renderContext, canvasElement);
}
const {
storyFn,
storyContext: { testingLibraryRender: render },
} = renderContext;
const { unmount } = render(storyFn(), { container: canvasElement });
return unmount;
},
};

View File

@ -2184,12 +2184,12 @@ __metadata:
linkType: hard
"@babel/runtime-corejs3@npm:^7.10.2":
version: 7.23.1
resolution: "@babel/runtime-corejs3@npm:7.23.1"
version: 7.25.0
resolution: "@babel/runtime-corejs3@npm:7.25.0"
dependencies:
core-js-pure: "npm:^3.30.2"
regenerator-runtime: "npm:^0.14.0"
checksum: 10c0/6e2c2b11779ff56c88b1f3a8742498640f7271ad4fcf9cfd24052bbb236a5e7c4c7c8d81cda751da3b4effa678736303deb78441c5752e63bfb90d6453fd870f
checksum: 10c0/7c9e7896749b5968bc6a7638cf1735e5d2dc791780f4f46daf15a45777780cd0485d1357e92f54b03f815269064dc84d771e83486d49e18b847ffa8cfb6a6afa
languageName: node
linkType: hard
@ -2220,7 +2220,16 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.15, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.24.4, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
"@babel/runtime@npm:^7.10.2":
version: 7.25.0
resolution: "@babel/runtime@npm:7.25.0"
dependencies:
regenerator-runtime: "npm:^0.14.0"
checksum: 10c0/bd3faf246170826cef2071a94d7b47b49d532351360ecd17722d03f6713fd93a3eb3dbd9518faa778d5e8ccad7392a7a604e56bd37aaad3f3aa68d619ccd983d
languageName: node
linkType: hard
"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.15, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.24.4, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
version: 7.24.7
resolution: "@babel/runtime@npm:7.24.7"
dependencies:
@ -7615,7 +7624,14 @@ __metadata:
languageName: node
linkType: hard
"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1":
"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0":
version: 2.0.6
resolution: "@types/istanbul-lib-coverage@npm:2.0.6"
checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7
languageName: node
linkType: hard
"@types/istanbul-lib-coverage@npm:^2.0.1":
version: 2.0.4
resolution: "@types/istanbul-lib-coverage@npm:2.0.4"
checksum: 10c0/af5f6b64e788331ed3f7b2e2613cb6ca659c58b8500be94bbda8c995ad3da9216c006f1cfe6f66b321c39392b1bda18b16e63cef090a77d24a00b4bd5ba3b018
@ -7623,20 +7639,20 @@ __metadata:
linkType: hard
"@types/istanbul-lib-report@npm:*":
version: 3.0.1
resolution: "@types/istanbul-lib-report@npm:3.0.1"
version: 3.0.3
resolution: "@types/istanbul-lib-report@npm:3.0.3"
dependencies:
"@types/istanbul-lib-coverage": "npm:*"
checksum: 10c0/a2a002ee7ecd9079a2c06235d28d1bc77089c3d834eec7e6dac38986203634936f2a017812624acfbedabec4bddd933942f14ac93eba2dc57f581ad4f35bbf1d
checksum: 10c0/247e477bbc1a77248f3c6de5dadaae85ff86ac2d76c5fc6ab1776f54512a745ff2a5f791d22b942e3990ddbd40f3ef5289317c4fca5741bedfaa4f01df89051c
languageName: node
linkType: hard
"@types/istanbul-reports@npm:^3.0.0":
version: 3.0.2
resolution: "@types/istanbul-reports@npm:3.0.2"
version: 3.0.4
resolution: "@types/istanbul-reports@npm:3.0.4"
dependencies:
"@types/istanbul-lib-report": "npm:*"
checksum: 10c0/df6c9e6865006be06bae29f63d5240b96bc7041b18a8c6d66be5b5d92ef5c95675c7a605a603029065f4f8aece7dba7360349e9d0543f512417e64a707a3c4fa
checksum: 10c0/1647fd402aced5b6edac87274af14ebd6b3a85447ef9ad11853a70fd92a98d35f81a5d3ea9fcb5dbb5834e800c6e35b64475e33fcae6bfa9acc70d61497c54ee
languageName: node
linkType: hard
@ -8143,18 +8159,18 @@ __metadata:
linkType: hard
"@types/yargs-parser@npm:*":
version: 21.0.1
resolution: "@types/yargs-parser@npm:21.0.1"
checksum: 10c0/f1d723a4c4383a9c53b975820b7490186ca127237ca58eb2ee8f5eacdcdb195a81aeabd1d75560abdf22fc29f70e8bb103d7ab34c5ec49bc19196195a7bf3189
version: 21.0.3
resolution: "@types/yargs-parser@npm:21.0.3"
checksum: 10c0/e71c3bd9d0b73ca82e10bee2064c384ab70f61034bbfb78e74f5206283fc16a6d85267b606b5c22cb2a3338373586786fed595b2009825d6a9115afba36560a0
languageName: node
linkType: hard
"@types/yargs@npm:^15.0.0":
version: 15.0.16
resolution: "@types/yargs@npm:15.0.16"
version: 15.0.19
resolution: "@types/yargs@npm:15.0.19"
dependencies:
"@types/yargs-parser": "npm:*"
checksum: 10c0/07f0960062e66226ae602fccd62e351143291d778e1f4dd645c51111e62fbedafe2a976c223dcfa7ae052e989407b62e97a7472fc1d73536110cd05502c204a5
checksum: 10c0/9fe9b8645304a628006cbba2d1990fb015e2727274d0e3853f321a379a1242d1da2c15d2f56cff0d4313ae94f0383ccf834c3bded9fb3589608aefb3432fcf00
languageName: node
linkType: hard

View File

@ -20,7 +20,7 @@ const runTests = (name: string, storiesModule: any) => {
const composedStories = composeStories(storiesModule);
Object.entries(composedStories).forEach(([name, Story]: [any, any]) => {
it(`renders ${name}`, async () => {
await Story.play?.();
await Story.run?.();
expect(document.body).toMatchSnapshot();
});
});

File diff suppressed because it is too large Load Diff

View File

@ -92,7 +92,7 @@ describe('CSF3', () => {
it('renders with play function', async () => {
const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default);
await CSF3InputFieldFilled.play();
await CSF3InputFieldFilled.run();
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -117,6 +117,6 @@ it('should pass with decorators that need addons channel', () => {
// Batch snapshot testing
const testCases = Object.values(composeStories(stories)).map((Story) => [Story.storyName, Story]);
it.each(testCases)('Renders %s story', async (_storyName, Story) => {
await Story.play();
await Story.run();
expect(document.body).toMatchSnapshot();
});

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ describe('renders', () => {
expect(getByTestId('spy-data').textContent).toEqual('mockFn return value');
expect(getByTestId('loaded-data').textContent).toEqual('loaded data');
// spy assertions happen in the play function and should work
await LoaderStory.play!();
await LoaderStory.run!();
});
});
@ -114,7 +114,7 @@ describe('CSF3', () => {
it('renders with play function without canvas element', async () => {
const CSF3InputFieldFilled = composeStory(stories.CSF3InputFieldFilled, stories.default);
await CSF3InputFieldFilled.play();
await CSF3InputFieldFilled.run();
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -126,7 +126,7 @@ describe('CSF3', () => {
const div = document.createElement('div');
document.body.appendChild(div);
await CSF3InputFieldFilled.play({ canvasElement: div });
await CSF3InputFieldFilled.run({ canvasElement: div });
const input = screen.getByTestId('input') as HTMLInputElement;
expect(input.value).toEqual('Hello world!');
@ -141,6 +141,20 @@ const testCases = Object.values(composeStories(stories)).map(
);
it.each(testCases)('Renders %s story', async (_storyName, Story) => {
if (_storyName === 'CSF2StoryWithLocale') return;
await Story.play();
await Story.run();
expect(document.body).toMatchSnapshot();
});
const meta = {
decorators: [BrowserRouter]
}
const bla = defineStory({
play: () => {}
});
const bla2 = {
render: () => {
return <div><bla.OriginalComponent/></div>
},
play: () => {}
};

View File

@ -2,22 +2,44 @@
exports[`Renders CSF2Secondary story 1`] = `
<body>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
type="button"
>
label coming from story args!
</button>
<div>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
type="button"
>
label coming from story args!
</button>
</div>
</body>
`;
exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
<body>
<div
style="margin: 3em;"
>
<div>
<div
style="margin: 3em;"
>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
type="button"
>
foo
</button>
</div>
</div>
</body>
`;
exports[`Renders CSF3Button story 1`] = `
<body>
<div>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
@ -26,91 +48,46 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
foo
</button>
</div>
</body>
`;
exports[`Renders CSF3Button story 1`] = `
<body>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
type="button"
>
foo
</button>
</body>
`;
exports[`Renders CSF3ButtonWithRender story 1`] = `
<body>
<div>
<p
data-testid="custom-render"
>
I am a custom render function
</p>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
type="button"
>
foo
<div>
<p
data-testid="custom-render"
>
I am a custom render function
</p>
</button>
<button
class="storybook-button storybook-button--medium storybook-button--secondary"
style=""
type="button"
>
foo
</button>
</div>
</div>
</body>
`;
exports[`Renders CSF3InputFieldFilled story 1`] = `
<body>
<input
data-testid="input"
/>
<div>
<input
data-testid="input"
/>
</div>
</body>
`;
exports[`Renders CSF3Primary story 1`] = `
<body>
<button
class="storybook-button storybook-button--large storybook-button--primary"
style=""
type="button"
>
foo
</button>
</body>
`;
exports[`Renders LoaderStory story 1`] = `
<body>
<div>
<div
data-testid="loaded-data"
>
loaded data
</div>
<div
data-testid="spy-data"
>
mockFn return value
</div>
</div>
</body>
`;
exports[`Renders NewStory story 1`] = `
<body>
<div
style="margin: 3em;"
>
<button
class="storybook-button storybook-button--large storybook-button--primary"
style=""
@ -119,9 +96,48 @@ exports[`Renders NewStory story 1`] = `
foo
</button>
</div>
</body>
`;
exports[`Renders LoaderStory story 1`] = `
<body>
<div>
<div>
<div
data-testid="loaded-data"
>
loaded data
</div>
<div
data-testid="spy-data"
>
mockFn return value
</div>
</div>
</div>
</body>
`;
exports[`Renders NewStory story 1`] = `
<body>
<div>
<div
style="margin: 3em;"
>
<button
class="storybook-button storybook-button--large storybook-button--primary"
style=""
type="button"
>
foo
</button>
</div>
</div>
</body>
`;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff