Created
October 18, 2019 09:40
-
-
Save mfolnovic/6da2b9aacd2e6e8aa27724e9bd44e0b2 to your computer and use it in GitHub Desktop.
Storybook + Jest (React specific)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { storiesOf, getStorybook } from '@storybook/react'; | |
import { startCase } from 'lodash'; | |
import { render } from '@testing-library/react'; | |
// from storybook/lib/core/src/client/preview/start.js | |
function matches(storyKey: string, arrayOrRegex: any) { | |
if (Array.isArray(arrayOrRegex)) { | |
return arrayOrRegex.includes(storyKey); | |
} | |
return storyKey.match(arrayOrRegex); | |
} | |
// from storybook/lib/core/src/client/preview/start.js | |
export function isExportStory( | |
key: string, | |
{ includeStories, excludeStories }: any | |
) { | |
return ( | |
// https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs | |
key !== '__esModule' && | |
(!includeStories || matches(key, includeStories)) && | |
(!excludeStories || !matches(key, excludeStories)) | |
); | |
} | |
// from storybook/lib/router/src/utils.ts | |
function storyNameFromExport(key: string) { | |
return startCase(key); | |
} | |
export default function describeStories(stories: any) { | |
// from storybook/lib/core/src/client/preview/start.js | |
const { default: meta, ...exports } = stories; | |
const { | |
title: kindName, | |
parameters: params, | |
decorators: decos, | |
component, | |
} = meta; | |
// filtering out all non-export stories | |
const storiesExports = Object.keys(exports).filter(key => | |
isExportStory(key, meta) | |
); | |
const kind = storiesOf(kindName, stories); | |
kind.addParameters({ | |
framework: 'react', // hardcoding React | |
component, | |
...params, | |
}); | |
(decos || []).forEach((decorator: any) => { | |
kind.addDecorator(decorator); | |
}); | |
storiesExports.forEach(key => { | |
// from storybook/lib/core/src/client/preview/start.js | |
const storyFn = exports[key]; | |
const { name, parameters, decorators } = storyFn.story || {}; | |
const decoratorParams = decorators ? { decorators } : null; | |
const displayNameParams = name ? { displayName: name } : {}; | |
const storyName = storyNameFromExport(key); | |
kind.add(storyName, storyFn, { | |
...parameters, | |
...decoratorParams, | |
...displayNameParams, | |
}); | |
}); | |
const storybook = getStorybook(); | |
describe(meta.title, () => { | |
const section = storybook.find(x => x.kind === kindName) || { stories: [] }; | |
test.each(storiesExports)('%s', async key => { | |
// Given | |
const story = section.stories.find( | |
story => story.name === storyNameFromExport(key) | |
); | |
// When | |
if (story) { | |
render(<div data-testid="root">{story.render()}</div>); | |
} else { | |
fail('Story not found'); | |
} | |
// Then | |
await expect('[data-testid=root]').toMatchScreenshot(); | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment