Skip to content

Commit

Permalink
Merge pull request #28534 from storybookjs/docs-8-2-updates-latest
Browse files Browse the repository at this point in the history
Docs: Updates for 8.2 features
  • Loading branch information
kylegach authored Jul 10, 2024
2 parents 9c3d891 + 858f1b6 commit 23882fe
Show file tree
Hide file tree
Showing 44 changed files with 963 additions and 931 deletions.
28 changes: 12 additions & 16 deletions code/core/src/preview-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,27 +210,23 @@ export class StoryStoreAccessedBeforeInitializationError extends StorybookError

export class MountMustBeDestructuredError extends StorybookError {
constructor(public data: { playFunction: string }) {
const transpiled =
/function\s*\*|regeneratorRuntime|asyncToGenerator|_ref|param|_0|__async/.test(
data.playFunction
);

super({
category: Category.PREVIEW_API,
code: 12,
message: dedent`
To use mount in the play function, you must use object destructuring, e.g. play: ({ mount }) => {}.
${
!transpiled
? ''
: dedent`
It seems that your builder is configured to transpile destructuring.
To use the mount prop of the story context, you must configure your builder to transpile to no earlier than ES2017.
`
}
More info: https://storybook.js.org/docs/writing-tests/interaction-testing#run-code-before-each-test
To use mount in the play function, you must satisfy the following two requirements:
1. You *must* destructure the mount property from the \`context\` (the argument passed to your play function).
This makes sure that Storybook does not start rendering the story before the play function begins.
2. Your Storybook framework or builder must be configured to transpile to ES2017 or newer.
This is because destructuring statements and async/await usages are otherwise transpiled away,
which prevents Storybook from recognizing your usage of \`mount\`.
Note that Angular is not supported. As async/await is transpiled to support the zone.js polyfill.
More info: https://storybook.js.org/docs/writing-tests/interaction-testing#run-code-before-the-component-gets-rendered
Received the following play function:
${data.playFunction}`,
Expand Down
Binary file removed docs/_assets/api/story-pipeline-playwright-ct.png
Binary file not shown.
Binary file added docs/_assets/api/story-pipeline-playwright.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/_assets/api/story-pipeline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions docs/_snippets/before-all-in-preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
```js filename=".storybook/preview.js" renderer="common" language="js"
import { init } from '../project-bootstrap';

export default {
async beforeAll() {
await init();
},
};
```

```ts filename=".storybook/preview.ts" renderer="common" language="ts"
// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import { Preview } from '@storybook/your-renderer';

import { init } from '../project-bootstrap';

const preview: Preview = {
async beforeAll() {
await init();
},
};

export default preview;
```
24 changes: 24 additions & 0 deletions docs/_snippets/before-each-in-preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
```js filename=".storybook/preview.js" renderer="common" language="js"
import MockDate from 'mockdate';

export default {
async beforeEach() {
MockDate.reset()
}
};
```

```ts filename=".storybook/preview.ts" renderer="common" language="ts"
// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import { Preview } from '@storybook/your-renderer';
import MockDate from 'mockdate';

const preview: Preview = {
async beforeEach() {
MockDate.reset()
}
};

export default preview;
```

33 changes: 21 additions & 12 deletions docs/_snippets/button-snapshot-test-portable-stories.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
```js filename="test/Button.test.js|ts" renderer="react" language="js" tabTitle="jest"
import { render } from '@testing-library/react';

import { composeStories } from '@storybook/react';

import * as stories from '../stories/Button.stories';

const { Primary } = composeStories(stories);
test('Button snapshot', async () => {
const mounted = render(<Primary />);
expect(mounted.container).toMatchSnapshot();
await Primary.play();
expect(document.body.firstChild).toMatchSnapshot();
});
```

Expand All @@ -17,16 +15,14 @@ test('Button snapshot', async () => {

import { expect, test } from 'vitest';

import { render } from '@testing-library/react';

import { composeStories } from '@storybook/react';

import * as stories from '../stories/Button.stories';

const { Primary } = composeStories(stories);
test('Button snapshot', async () => {
const mounted = render(Primary());
expect(mounted.container).toMatchSnapshot();
await Primary.play();
expect(document.body.firstChild).toMatchSnapshot();
});
```

Expand All @@ -35,16 +31,29 @@ test('Button snapshot', async () => {

import { expect, test } from 'vitest';

import { render } from '@testing-library/vue';

import { composeStories } from '@storybook/vue3';

import * as stories from '../stories/Button.stories';

const { Primary } = composeStories(stories);
test('Button snapshot', async () => {
const mounted = render(Primary());
expect(mounted.container).toMatchSnapshot();
await Primary.play();
expect(document.body.firstChild).toMatchSnapshot();
});
```

```js filename="__tests__/Button.spec.js|ts" renderer="svelte" language="js"
// @vitest-environment jsdom

import { expect, test } from 'vitest';

import { composeStories } from '@storybook/svelte';

import * as stories from '../stories/Button.stories';

const { Primary } = composeStories(stories);
test('Button snapshot', async () => {
await Primary.play();
expect(document.body.firstChild).toMatchSnapshot();
});
```
66 changes: 35 additions & 31 deletions docs/_snippets/component-test-with-testing-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { render, fireEvent } from '@testing-library/preact';

import { InvalidForm } from './LoginForm.stories'; //👈 Our stories imported here.

it('Checks if the form is valid', () => {
it('Checks if the form is valid', async () => {
const { getByTestId, getByText } = render(<InvalidForm {...InvalidForm.args} />);

fireEvent.click(getByText('Submit'));
Expand All @@ -39,14 +39,15 @@ it('Checks if the form is valid', () => {
```js filename="Form.test.js|jsx" renderer="react" language="js"
import { fireEvent, render, screen } from '@testing-library/react';

import { composeStory } from '@storybook/react';
import { composeStories } from '@storybook/react';

import Meta, { InvalidForm as InvalidFormStory } from './LoginForm.stories'; //👈 Our stories imported here.
import * as stories from './LoginForm.stories'; // 👈 Our stories imported here.

const FormError = composeStory(InvalidFormStory, Meta);
const { InvalidForm } = composeStories(stories);

test('Checks if the form is valid', () => {
render(<FormError />);
test('Checks if the form is valid', async () => {
// Renders the composed story
await InvalidForm.play();

const buttonElement = screen.getByRole('button', {
name: 'Submit',
Expand All @@ -62,14 +63,15 @@ test('Checks if the form is valid', () => {
```ts filename="Form.test.ts|tsx" renderer="react" language="ts"
import { fireEvent, render, screen } from '@testing-library/react';

import { composeStory } from '@storybook/react';
import { composeStories } from '@storybook/react';

import Meta, { InvalidForm as InvalidFormStory } from './LoginForm.stories'; //👈 Our stories imported here.
import * as stories from './LoginForm.stories'; // 👈 Our stories imported here.

const FormError = composeStory(InvalidFormStory, Meta);
const { InvalidForm } = composeStories(stories);

test('Checks if the form is valid', () => {
render(<FormError />);
test('Checks if the form is valid', async () => {
// Renders the composed story
await InvalidForm.play();

const buttonElement = screen.getByRole('button', {
name: 'Submit',
Expand All @@ -82,36 +84,38 @@ test('Checks if the form is valid', () => {
});
```

```js filename="Form.test.js|ts" renderer="svelte" language="js"
import { render, fireEvent } from '@testing-library/svelte';
```js filename="Form.test.js" renderer="svelte" language="js"
import { fireEvent, render, screen } from '@testing-library/svelte';

import LoginForm from './LoginForm.svelte';
import { composeStories } from '@storybook/svelte';

import { InvalidForm } from './LoginForm.stories'; //👈 Our stories imported here.
import * as stories from './LoginForm.stories'; // 👈 Our stories imported here.

const { InvalidForm } = composeStories(stories);

it('Checks if the form is valid', async () => {
const { getByTestId, getByText } = render(LoginForm, {
props: InvalidForm.args,
});
// Renders the composed story
await InvalidForm.play();

await fireEvent.click(getByText('Submit'));
await fireEvent.click(screen.getByText('Submit'));

const isFormValid = getByTestId('invalid-form');
const isFormValid = screen.getByTestId('invalid-form');
expect(isFormValid).toBeInTheDocument();
});
```

```js filename="tests/Form.test.js" renderer="vue" language="js" tabTitle="3"
import { fireEvent, render, screen } from '@testing-library/vue';

import { composeStory } from '@storybook/vue3';
import { composeStories } from '@storybook/vue3';

import Meta, { InvalidForm as InvalidFormStory } from './LoginForm.stories'; //👈 Our stories imported here.
import * as stories from './LoginForm.stories'; // 👈 Our stories imported here.

const FormError = composeStory(InvalidFormStory, Meta);
const { InvalidForm } = composeStories(stories);

test('Checks if the form is valid', () => {
render(FormError());
test('Checks if the form is valid', async () => {
// Renders the composed story
await InvalidForm.play();

const buttonElement = screen.getByRole('button', {
name: 'Submit',
Expand All @@ -127,14 +131,15 @@ test('Checks if the form is valid', () => {
```ts filename="tests/Form.test.ts" renderer="vue" language="ts" tabTitle="3"
import { fireEvent, render, screen } from '@testing-library/vue';

import { composeStory } from '@storybook/vue3';
import { composeStories } from '@storybook/vue3';

import Meta, { InvalidForm as InvalidFormStory } from './LoginForm.stories'; //👈 Our stories imported here.
import * as stories from './LoginForm.stories'; // 👈 Our stories imported here.

const FormError = composeStory(InvalidFormStory, Meta);
const { InvalidForm } = composeStories(stories);

test('Checks if the form is valid', () => {
render(FormError());
test('Checks if the form is valid', async () => {
// Renders the composed story
await InvalidForm.play();

const buttonElement = screen.getByRole('button', {
name: 'Submit',
Expand All @@ -146,4 +151,3 @@ test('Checks if the form is valid', () => {
expect(isFormValid).toBeInTheDocument();
});
```

Loading

0 comments on commit 23882fe

Please sign in to comment.