diff --git a/.jestrc.json b/.jestrc.json index 9d5dd48c424..3a03d8bf857 100644 --- a/.jestrc.json +++ b/.jestrc.json @@ -3,7 +3,8 @@ "clearMocks": true, "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/__mocks__/fileMock.js", - "\\.(css|scss)$": "/__mocks__/styleMock.js" + "\\.(css|scss)$": "/__mocks__/styleMock.js", + "@storybook/addons": "/lib/addons/dist/index.js" }, "projects": [ "/packages/*", diff --git a/addons/storyshots/package.json b/addons/storyshots/package.json index 9ccb7b36fc1..eb4cbf2bcba 100644 --- a/addons/storyshots/package.json +++ b/addons/storyshots/package.json @@ -10,6 +10,7 @@ "main": "dist/index.js", "scripts": { "prepublish": "babel ./src --out-dir ./dist", + "test": "jest --config ./.jestrc", "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook" }, @@ -19,7 +20,8 @@ "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "react": "^15.5.4", - "react-dom": "^15.5.4" + "react-dom": "^15.5.4", + "react-test-renderer": "^15.5.4" }, "dependencies": { "@storybook/addon-actions": "^3.0.0-alpha.0", diff --git a/addons/storyshots/src/index.js b/addons/storyshots/src/index.js index ae7ab2f1051..d93fd16852b 100644 --- a/addons/storyshots/src/index.js +++ b/addons/storyshots/src/index.js @@ -11,13 +11,18 @@ let configPath; const babel = require('babel-core'); +function hasDependency(pkg, dependency) { + return ( + (pkg.devDependencies && pkg.devDependencies[dependency]) || + (pkg.dependencies && pkg.dependencies[dependency]) || + pkg.name === dependency + ); +} + const pkg = readPkgUp.sync().pkg; -const isStorybook = - (pkg.devDependencies && pkg.devDependencies['@storybook/react']) || - (pkg.dependencies && pkg.dependencies['@storybook/react']); -const isRNStorybook = - (pkg.devDependencies && pkg.devDependencies['@storybook/react-native']) || - (pkg.dependencies && pkg.dependencies['@storybook/react-native']); + +const isStorybook = hasDependency(pkg, '@storybook/react') || pkg.name === 'storybook'; +const isRNStorybook = hasDependency(pkg, '@storybook/react-native'); export default function testStorySnapshots(options = {}) { addons.setChannel(createChannel()); @@ -69,7 +74,7 @@ export default function testStorySnapshots(options = {}) { it(story.name, () => { const context = { kind: group.kind, story: story.name }; const renderedStory = story.render(context); - const tree = renderer.create(renderedStory).toJSON(); + const tree = renderer.create(renderedStory, options.rendererOptions).toJSON(); expect(tree).toMatchSnapshot(); }); } diff --git a/addons/storyshots/stories/__test__/__snapshots__/storyshots.test.js.snap b/addons/storyshots/stories/__test__/__snapshots__/storyshots.test.js.snap new file mode 100644 index 00000000000..10f71324c7d --- /dev/null +++ b/addons/storyshots/stories/__test__/__snapshots__/storyshots.test.js.snap @@ -0,0 +1,238 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Another Button with some emoji 1`] = ` + +`; + +exports[`Storyshots Another Button with text 1`] = ` + +`; + +exports[`Storyshots Button with some emoji 1`] = ` + +`; + +exports[`Storyshots Button with text 1`] = ` + +`; + +exports[`Storyshots Component with ref on mount 1`] = ` + +`; + +exports[`Storyshots Welcome to Storybook 1`] = ` +
+

+ Welcome to STORYBOOK +

+

+ This is a UI component dev environment for your app. +

+

+ We've added some basic stories inside the + + + src/stories + + + directory. +
+ A story is a single state of one or more UI components. You can have as many stories as you want. +
+ (Basically a story is like a visual test case.) +

+

+ See these sample + + + stories + + + for a component called + + + Button + + . +

+

+ Just like that, you can add your own components as stories. +
+ You can also edit those components and see changes right away. +
+ (Try editing the + + Button + + component located at + + stories/Button.js + + .) +

+

+ This is just one thing you can do with Storybook. +
+ Have a look at the + + + Storybook for React + + + repo for more information. +

+
+`; diff --git a/addons/storyshots/stories/__test__/storyshots.test.js b/addons/storyshots/stories/__test__/storyshots.test.js new file mode 100644 index 00000000000..6df135ef033 --- /dev/null +++ b/addons/storyshots/stories/__test__/storyshots.test.js @@ -0,0 +1,14 @@ +import initStoryshots from '../../src'; +import path from 'path'; + +function createNodeMock(element) { + if (element.type === 'input') { + return { scrollWidth: 123 }; + } + return null; +} + +initStoryshots({ + rendererOptions: { createNodeMock }, + configPath: path.resolve(__dirname, '../../.storybook'), +}); diff --git a/addons/storyshots/stories/required_with_context/ComponentWithRef.js b/addons/storyshots/stories/required_with_context/ComponentWithRef.js new file mode 100644 index 00000000000..54b7b109c73 --- /dev/null +++ b/addons/storyshots/stories/required_with_context/ComponentWithRef.js @@ -0,0 +1,37 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +const inputStyles = { + border: '1px solid #eee', + borderRadius: 3, + backgroundColor: '#FFFFFF', + fontSize: 15, + padding: '3px 10px', + margin: 10, + width: '400px', +}; + +class ComponentWithRef extends React.Component { + componentDidMount() { + this.props.onLoad(`scrollWidth: ${this.ref.scrollWidth}`); + } + setRef(ref) { + this.ref = ref; + } + render() { + return ( + this.setRef(r)} + style={inputStyles} + /> + ); + } +} + +ComponentWithRef.propTypes = { + onLoad: PropTypes.func, +}; + +export default ComponentWithRef; diff --git a/addons/storyshots/stories/required_with_context/ComponentWithRef.stories.js b/addons/storyshots/stories/required_with_context/ComponentWithRef.stories.js new file mode 100644 index 00000000000..51b8051c790 --- /dev/null +++ b/addons/storyshots/stories/required_with_context/ComponentWithRef.stories.js @@ -0,0 +1,7 @@ +import React from 'react'; +import { storiesOf, action } from '@storybook/react'; +import ComponentWithRef from './ComponentWithRef'; + +storiesOf('Component with ref', module).add('on mount', () => ( + +));