Created
October 18, 2019 09:40
-
-
Save mfolnovic/915c7194bd8249bc6699547ca998aff6 to your computer and use it in GitHub Desktop.
Storybook + Jest (React specific)
This file contains 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