Skip to content

Commit

Permalink
add stories and autodocs for resolved react in addon-docs templates
Browse files Browse the repository at this point in the history
  • Loading branch information
JReinhold committed Mar 20, 2024
1 parent 7290a2c commit 8699394
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { version as reactVersion } from 'react';
import { version as reactDomVersion } from 'react-dom';
import { version as reactDomServerVersion } from 'react-dom/server';

export const ResolvedReactVersion = () => {
export const ResolvedReact = () => {
return (
<>
<p>
Expand Down
19 changes: 16 additions & 3 deletions code/addons/docs/template/stories/docs2/ResolvedReact.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { Meta } from '@storybook/blocks';
import { version as reactVersion } from 'react';
import { version as reactDomVersion } from 'react-dom';
import { version as reactDomServerVersion } from 'react-dom/server';
import { ResolvedReactVersion } from './ResolvedReactVersion';
import * as ResolvedReactStories from './resolved-react.stories';
import { ResolvedReact } from './ResolvedReact';

<Meta of={ResolvedReactStories} name="MDX"/>

This doc is used to display the resolved version of React and its related packages.
As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should be available to import from and should resolve to the same version.

The MDX here ensures that it works in an MDX file.

- See the [autodocs](/docs/addons-docs-docs2-resolvedreact--docs) for how it resolves in MDX.
- See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story.


## In MDX

Expand All @@ -11,6 +24,6 @@ import { ResolvedReactVersion } from './ResolvedReactVersion';

<code>react-dom/server</code>: <code data-testid="mdx-react-dom-server">{reactDomServerVersion}</code>

## In `ResolvedReactVersion` component
## In `ResolvedReact` component

<ResolvedReactVersion />
<ResolvedReact />
58 changes: 58 additions & 0 deletions code/addons/docs/template/stories/docs2/resolved-react.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { within, expect } from '@storybook/test';
import { version as reactVersion } from 'react';
import { version as reactDomVersion } from 'react-dom';
import { version as reactDomServerVersion } from 'react-dom/server';

/**
* This component is used to display the resolved version of React and its related packages.
* As long as `@storybook/addon-docs` is installed, `react` and `react-dom` should be available to import from and should resolve to the same version.
*
* The autodocs here ensures that it also works in the generated documentation.
*
* - See the [MDX docs](/docs/addons-docs-docs2-resolvedreact--mdx) for how it resolves in MDX.
* - See the [Story](/story/addons-docs-docs2-resolvedreact--story) for how it resolves in the actual story.
*/
export default {
title: 'Docs2/ResolvedReact',
component: globalThis.Components.Html,
tags: ['autodocs'],
argTypes: {
content: { table: { disable: true } },
},
args: {
content: `
<p>
<code>react</code>: <code data-testid="react">${reactVersion}</code>
</p>
<p>
<code>react-dom</code>: <code data-testid="react-dom">${reactDomVersion}</code>
</p>
<p>
<code>react-dom/server</code>: <code data-testid="react-dom-server">${reactDomServerVersion}</code>
</p>
`,
},
parameters: {
docs: {
name: 'ResolvedReact',
},
},
};

export const Story = {
// This test is more or less the same as the E2E test we have for MDX and autodocs entries in addon-docs.spec.ts
play: async ({ canvasElement, step }: any) => {
const canvas = await within(canvasElement);

const actualReactVersion = (await canvas.findByTestId('react')).textContent;
const actualReactDomVersion = (await canvas.findByTestId('react-dom')).textContent;
const actualReactDomServerVersion = await (
await canvas.findByTestId('react-dom-server')
).textContent;

step('Expect React packages to all resolve to the same version', () => {
expect(actualReactVersion).toBe(actualReactDomVersion);
expect(actualReactVersion).toBe(actualReactDomServerVersion);
});
},
};
32 changes: 29 additions & 3 deletions code/e2e-tests/addon-docs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ test.describe('addon-docs', () => {
});

test('should resolve react to the correct version', async ({ page }) => {
// Arrange - Navigate to MDX docs and setup expectations
const sbPage = new SbPage(page);
await sbPage.navigateToUnattachedDocs('addons/docs/docs2', 'ResolvedReact');
await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'mdx', 'docs');
const root = sbPage.previewRoot();

let expectedReactVersionRange = /^18/;
Expand All @@ -200,23 +201,48 @@ test.describe('addon-docs', () => {
expectedReactVersionRange = /^16/;
}

// Arrange - Get the actual versions
const mdxReactVersion = await root.getByTestId('mdx-react');
const mdxReactDomVersion = await root.getByTestId('mdx-react-dom');
const mdxReactDomServerVersion = await root.getByTestId('mdx-react-dom-server');
const componentReactVersion = await root.getByTestId('component-react');
const componentReactDomVersion = await root.getByTestId('component-react-dom');
const componentReactDomServerVersion = await root.getByTestId('component-react-dom-server');

// Assert that the versions are in the expected range
// Assert - Tthe versions are in the expected range
await expect(mdxReactVersion).toHaveText(expectedReactVersionRange);

const actualReactVersion = (await mdxReactVersion.textContent())!;
// ... then assert that the versions are all the same
// Assert - The versions are all the same
await expect(mdxReactDomVersion).toHaveText(actualReactVersion);
await expect(mdxReactDomServerVersion).toHaveText(actualReactVersion);
await expect(componentReactVersion).toHaveText(actualReactVersion);
await expect(componentReactDomVersion).toHaveText(actualReactVersion);
await expect(componentReactDomServerVersion).toHaveText(actualReactVersion);

// Arrange - Navigate to autodocs
await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'docs');

// Arrange - Get the actual versions
const autodocsReactVersion = await root.getByTestId('react');
const autodocsReactDomVersion = await root.getByTestId('react-dom');
const autodocsReactDomServerVersion = await root.getByTestId('react-dom-server');

await expect(autodocsReactVersion).toHaveText(actualReactVersion);
await expect(autodocsReactDomVersion).toHaveText(actualReactVersion);
await expect(autodocsReactDomServerVersion).toHaveText(actualReactVersion);

// Arrange - Navigate to story
await sbPage.navigateToStory('addons/docs/docs2/resolvedreact', 'story');

// Arrange - Get the actual versions
const storyReactVersion = await root.getByTestId('react');
const storyReactDomVersion = await root.getByTestId('react-dom');
const storyReactDomServerVersion = await root.getByTestId('react-dom-server');

await expect(storyReactVersion).toHaveText(actualReactVersion);
await expect(storyReactDomVersion).toHaveText(actualReactVersion);
await expect(storyReactDomServerVersion).toHaveText(actualReactVersion);
});

test('should have stories from multiple CSF files in autodocs', async ({ page }) => {
Expand Down
9 changes: 4 additions & 5 deletions code/e2e-tests/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class SbPage {
/**
* Visit a story by selecting it from the sidebar.
*/
async navigateToStory(title: string, name: string) {
async navigateToStory(title: string, name: string, viewMode?: 'docs' | 'story') {
await this.openComponent(title);

const titleId = toId(title);
Expand All @@ -50,11 +50,10 @@ export class SbPage {
const storyLink = this.page.locator('*', { has: this.page.locator(`> ${storyLinkId}`) });
await storyLink.click({ force: true });

// assert url changes
const viewMode = name === 'docs' ? 'docs' : 'story';

await this.page.waitForURL((url) =>
url.search.includes(`path=/${viewMode}/${titleId}--${storyId}`)
url.search.includes(
`path=/${viewMode ?? name === 'docs' ? 'docs' : 'story'}/${titleId}--${storyId}`
)
);

const selected = await storyLink.getAttribute('data-selected');
Expand Down

0 comments on commit 8699394

Please sign in to comment.