├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── README.md
├── example
├── .storybook
│ ├── addons.js
│ └── config.js
├── MyComponent.js
├── MyComponent.story.js
├── MyComponent.test.js
├── list
│ ├── index.js
│ ├── index.story.js
│ └── index.test.js
├── private-card
│ ├── index.js
│ ├── index.story.js
│ └── index.test.js
└── withTests.js
├── package.json
├── register.js
├── src
├── colors.js
├── components
│ ├── Indicator.js
│ ├── TestsPanel.js
│ └── TestsPanelTitle.js
├── hoc
│ └── provideTests.js
├── index.js
├── register.js
├── styles.js
└── withTests.js
├── storybook-addon-jest.gif
├── styles.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "targets": {
5 | "browsers": ["last 3 versions", "IE >= 11"]
6 | }
7 | }],
8 | "react"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "extends": ["airbnb", "prettier"],
3 | plugins: ["react"],
4 | rules: {
5 | "arrow-parens": ['error', 'as-needed'],
6 | "comma-dangle": [1, {
7 | "arrays": 'always-multiline',
8 | "objects": 'always-multiline',
9 | "imports": 'always-multiline',
10 | "exports": 'always-multiline',
11 | "functions": "ignore",
12 | }],
13 | "import/prefer-default-export": 0,
14 | "react/forbid-prop-types": 0,
15 | "react/no-danger": 0,
16 | "react/jsx-no-target-blank": 0,
17 | "react/require-default-props": 0,
18 | "import/no-extraneous-dependencies": 2,
19 | "react/jsx-filename-extension": 0,
20 | "jsx-a11y/href-no-hash": 0,
21 | },
22 | "env": {
23 | "browser": true,
24 | "es6": true,
25 | "commonjs": true,
26 | "node": true,
27 | "jest": true,
28 | },
29 | "settings": {
30 | "import/resolver": {
31 | "webpack": {
32 | config: 'webpack-development.config.js'
33 | },
34 | },
35 | },
36 | };
37 |
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | .jest-test-results.json
5 | build
6 | package-lock.json
7 |
8 | coverage
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Storybook Addon Actions
2 | This contents of this repo was moved to the Storybook monorepo and the NPM package name has been changed.
3 |
4 | The location of the code is: storybooks/storybook:addons/jest@master
5 | The repo you're looking at now is out of date and no longer maintained.
6 |
--------------------------------------------------------------------------------
/example/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addon-options/register';
2 | // --> import 'storybook-addon-jest/register'
3 | import '../../register';
4 | // --> import 'storybook-addon-jest/styles'
5 | import '../../dist/styles';
6 |
7 |
--------------------------------------------------------------------------------
/example/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure, addDecorator } from '@storybook/react';
2 | import { setOptions } from '@storybook/addon-options';
3 | // --> import { setupJestAddon } from 'storybook-addon-jest';
4 |
5 |
6 | setOptions({
7 | name: 'JEST ADDON',
8 | url: 'https://github.com/renaudtertrais/storybook-addon-jest',
9 | downPanelInRight: true,
10 | showLeftPanel: true,
11 | });
12 |
13 | function loadStories() {
14 | require('../foo/index.story');
15 | require('../list/index.story');
16 | require('../MyComponent.story');
17 | }
18 |
19 | configure(loadStories, module);
20 |
--------------------------------------------------------------------------------
/example/MyComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const MyComponent = () => (
4 |
Hello world
5 | );
6 |
7 | export default MyComponent;
8 |
--------------------------------------------------------------------------------
/example/MyComponent.story.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import { storiesOf } from '@storybook/react';
4 |
5 | import withTests from './withTests';
6 | import MyComponent from './MyComponent';
7 |
8 | storiesOf('MyComponent', module)
9 | .addDecorator(withTests('MyComponent'))
10 | .add('classic render', () => (
11 |
12 | ));
13 |
--------------------------------------------------------------------------------
/example/MyComponent.test.js:
--------------------------------------------------------------------------------
1 | describe('Description: ', () => {
2 | it('should contain 3 items', () => {
3 | expect(3).toBe(3);
4 | });
5 |
6 | it('should work fine', () => {
7 | expect(true).toBe(true);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/example/list/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const List = ({ items }) => {items.map(item => - {item}
)}
;
4 |
5 | List.defaultProps = {
6 | items: [],
7 | };
8 |
9 | export default List;
10 |
--------------------------------------------------------------------------------
/example/list/index.story.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import { storiesOf } from '@storybook/react';
4 |
5 | import withTests from '../withTests';
6 | import List from './index';
7 |
8 | storiesOf('List', module)
9 | .addDecorator(withTests('list/index'))
10 | .add('3 items', () => (
11 |
12 | ));
13 |
--------------------------------------------------------------------------------
/example/list/index.test.js:
--------------------------------------------------------------------------------
1 | describe('Description: ', () => {
2 | it('should contain 3 items', () => {
3 | expect(3).toBe(3);
4 | });
5 |
6 | it('should work fine', () => {
7 | expect(true).toBe(true);
8 | });
9 | });
10 |
11 | test('Failing test',() => {
12 | expect(['foo', 'bar', 89]).toEqual(['foo', 'bar']);
13 | })
14 |
--------------------------------------------------------------------------------
/example/private-card/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const PrivateCard = ({ firstname, lastname, age, job }) => {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 | - { firstname }
11 | - { lastname }
12 | - { job }
13 |
14 | { age >= 18 && Can drive
}
15 | { age < 18 && Can't drive
}
16 |
17 | )
18 | }
19 |
20 | export default PrivateCard;
21 |
--------------------------------------------------------------------------------
/example/private-card/index.story.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-extraneous-dependencies */
2 | import React from 'react';
3 | import { storiesOf } from '@storybook/react';
4 |
5 | import withTests from '../withTests';
6 | import PrivateCard from './index';
7 |
8 | storiesOf('PrivateCard', module)
9 | .addDecorator(withTests('private-card/index'))
10 | .add('Minor', () => (
11 |
12 | ));
13 |
--------------------------------------------------------------------------------
/example/private-card/index.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import PrivateCard from './index'
5 |
6 |
7 | describe(' rendering', () => {
8 | it('renders without crashing', () => {
9 | const div = document.createElement('div');
10 |
11 | ReactDOM.render(, div);
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/example/withTests.js:
--------------------------------------------------------------------------------
1 | // ---> import { withTests } from 'storybook-addon-jest';
2 | import withTests from '../dist';
3 |
4 | import jestTestResuls from './.jest-test-results.json';
5 |
6 |
7 | export default withTests(jestTestResuls, {
8 | filesExt: '.test.js',
9 | });
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "storybook-addon-jest",
3 | "version": "0.0.1",
4 | "description": "React storybook addon that show component jest report",
5 | "main": "dist/index.js",
6 | "homepage": "https://github.com/renaudtertrais/storybook-addon-jest",
7 | "bugs": "https://github.com/renaudtertrais/storybook-addon-jest/issues",
8 | "keywords": [],
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/renaudtertrais/storybook-addon-jest"
12 | },
13 | "author": "",
14 | "files": [
15 | "dist",
16 | "styles.js",
17 | "register.js"
18 | ],
19 | "scripts": {
20 | "test:example": "jest example --json --outputFile=example/.jest-test-results.json",
21 | "clean:storybook": "rm -rf build",
22 | "prebuild:storybook": "npm run clean:storybook",
23 | "build:storybook": "build-storybook -c example/.storybook -o build/",
24 | "storybook": "cross-env NODE_ENV=development start-storybook -p 3001 -c example/.storybook",
25 | "prebuild": "npm run clear",
26 | "build": "cross-env NODE_ENV=production babel -d ./dist ./src",
27 | "start": "./node_modules/.bin/cross-env NODE_ENV=production babel -d ./dist ./src && npm run test:example || true && npm run build:storybook && ./node_modules/.bin/serve ./build -p $PORT",
28 | "prepublish": "npm run build",
29 | "clear": "rm -rf ./dist"
30 | },
31 | "dependencies": {},
32 | "devDependencies": {
33 | "@storybook/addon-options": "^3.2.14",
34 | "@storybook/react": "^3.2.14",
35 | "babel-cli": "^6.26.0",
36 | "babel-core": "^6.26.0",
37 | "babel-preset-env": "^1.6.1",
38 | "babel-preset-react": "^6.24.1",
39 | "cross-env": "^5.1.4",
40 | "css-loader": "^0.28.7",
41 | "enzyme": "^3.1.1",
42 | "eslint": "^4.10.0",
43 | "eslint-config-airbnb": "^16.1.0",
44 | "eslint-config-prettier": "^2.7.0",
45 | "eslint-import-resolver-webpack": "^0.8.3",
46 | "eslint-plugin-import": "^2.8.0",
47 | "eslint-plugin-jsx-a11y": "^6.0.2",
48 | "eslint-plugin-react": "^7.4.0",
49 | "jest": "^21.2.1",
50 | "react": "^16.1.0",
51 | "react-dom": "^16.1.0",
52 | "serve": "^6.4.1",
53 | "style-loader": "^0.19.0",
54 | "upath": "^1.0.4"
55 | },
56 | "peerDependencies": {
57 | "@storybook/addons": "^3.2.14",
58 | "prop-types": "^15.6.0",
59 | "react": "^16.0.0",
60 | "react-dom": "^16.0.0"
61 | },
62 | "license": "MIT"
63 | }
64 |
--------------------------------------------------------------------------------
/register.js:
--------------------------------------------------------------------------------
1 | require('./dist/register');
2 |
--------------------------------------------------------------------------------
/src/colors.js:
--------------------------------------------------------------------------------
1 | export default {
2 | success: 'LIGHTSEAGREEN',
3 | error: 'CRIMSON',
4 | warning: 'DARKORANGE',
5 | grey: 'LIGHTSLATEGRAY',
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/Indicator.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Indicator = ({ color, size, children = '', right }) => (
4 |
20 | {children}
21 |
22 | );
23 |
24 | export default Indicator;
25 |
--------------------------------------------------------------------------------
/src/components/TestsPanel.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Indicator from './Indicator';
4 | import provideTests from '../hoc/provideTests';
5 | import colors from '../colors';
6 |
7 | const TestsPanel = ({ tests }) => {
8 | const style = {
9 | padding: '10px 20px',
10 | flex: 1,
11 | };
12 |
13 | if (!tests) {
14 | return (
15 |
16 |
No tests added.
17 |
18 | );
19 | }
20 |
21 | return (
22 |
23 | {tests.map(({ name, result }) => {
24 | if (!result) {
25 | return (
26 |
27 |
28 |
29 |
{name}
30 |
31 | File not found
32 |
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | const successNumber = result.assertionResults.filter(({ status }) => status === 'passed')
40 | .length;
41 | const failedNumber = result.assertionResults.length - successNumber;
42 |
43 | return (
44 |
45 |
53 |
54 |
{name}
55 |
60 | {result.status}
61 |
62 |
63 |
71 | {successNumber > 0 && (
72 |
73 | {successNumber} passed
74 |
75 | )}
76 | {failedNumber > 0 && (
77 |
{failedNumber} failed
78 | )}
79 |
{result.assertionResults.length} total
80 |
{result.endTime - result.startTime}ms
81 |
82 |
83 |
106 |
107 |
147 |
148 | );
149 | })}
150 |
151 | );
152 | };
153 |
154 | export default provideTests(TestsPanel);
155 |
--------------------------------------------------------------------------------
/src/components/TestsPanelTitle.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | import provideTests from '../hoc/provideTests';
5 | import Indicator from './Indicator';
6 | import colors from '../colors';
7 |
8 | const TestPanelTitle = ({ tests }) => {
9 | if (!tests) {
10 | return (
11 |
15 | );
16 | }
17 |
18 | const results = tests.map(report => report.result).filter(report => !!report);
19 | const success = results.reduce((acc, result) => acc & (result.status === 'passed'), true);
20 | const color = success ? colors.success : colors.error;
21 |
22 | return (
23 |
27 | );
28 | };
29 |
30 | export default provideTests(TestPanelTitle);
31 |
--------------------------------------------------------------------------------
/src/hoc/provideTests.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const provideTests = Component => {
4 | class TestProvider extends React.Component {
5 | constructor(props) {
6 | super(props);
7 |
8 | this.state = {};
9 | this.onAddTests = this.onAddTests.bind(this);
10 | }
11 |
12 | componentDidMount() {
13 | this.stopListeningOnStory = this.props.api.onStory((kind, storyName) => {
14 | this.onAddTests({});
15 | });
16 |
17 | this.props.channel.on('storybook/tests/add_tests', this.onAddTests);
18 | }
19 |
20 | onAddTests({ kind, storyName, tests }) {
21 | this.setState({ kind, storyName, tests });
22 | }
23 |
24 | componentWillUnmount() {
25 | if (this.stopListeningOnStory) {
26 | this.stopListeningOnStory();
27 | }
28 | this.props.channel.removeListener('storybook/tests/add_tests', this.onAddTests);
29 | }
30 |
31 | render() {
32 | return ;
33 | }
34 | }
35 |
36 | return TestProvider;
37 | };
38 |
39 | export default provideTests;
40 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './withTests';
2 |
--------------------------------------------------------------------------------
/src/register.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/no-danger */
2 | import React from 'react';
3 | import addons from '@storybook/addons';
4 |
5 | import TestPanelTitle from './components/TestsPanelTitle';
6 | import TestsPanel from './components/TestsPanel';
7 |
8 | // Register the addon with a unique name.
9 | addons.register('storybook/tests', api => {
10 | // Also need to set a unique name to the panel.
11 | addons.addPanel('storybook/tests/panel', {
12 | title: ,
13 | render: () => ,
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/src/styles.js:
--------------------------------------------------------------------------------
1 | const styles = `
2 | @font-face {
3 | font-family: octicons-link;
4 | src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
5 | }
6 | .markdown-body {
7 | -ms-text-size-adjust: 100%;
8 | -webkit-text-size-adjust: 100%;
9 | line-height: 1.5;
10 | color: #333;
11 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
12 | font-size: 16px;
13 | line-height: 1.5;
14 | word-wrap: break-word;
15 | }
16 | .markdown-body .pl-c {
17 | color: #969896;
18 | }
19 | .markdown-body .pl-c1,
20 | .markdown-body .pl-s .pl-v {
21 | color: #0086b3;
22 | }
23 | .markdown-body .pl-e,
24 | .markdown-body .pl-en {
25 | color: #795da3;
26 | }
27 | .markdown-body .pl-smi,
28 | .markdown-body .pl-s .pl-s1 {
29 | color: #333;
30 | }
31 | .markdown-body .pl-ent {
32 | color: #63a35c;
33 | }
34 | .markdown-body .pl-k {
35 | color: #a71d5d;
36 | }
37 | .markdown-body .pl-s,
38 | .markdown-body .pl-pds,
39 | .markdown-body .pl-s .pl-pse .pl-s1,
40 | .markdown-body .pl-sr,
41 | .markdown-body .pl-sr .pl-cce,
42 | .markdown-body .pl-sr .pl-sre,
43 | .markdown-body .pl-sr .pl-sra {
44 | color: #183691;
45 | }
46 | .markdown-body .pl-v {
47 | color: #ed6a43;
48 | }
49 | .markdown-body .pl-id {
50 | color: #b52a1d;
51 | }
52 | .markdown-body .pl-ii {
53 | color: #f8f8f8;
54 | background-color: #b52a1d;
55 | }
56 | .markdown-body .pl-sr .pl-cce {
57 | font-weight: bold;
58 | color: #63a35c;
59 | }
60 | .markdown-body .pl-ml {
61 | color: #693a17;
62 | }
63 | .markdown-body .pl-mh,
64 | .markdown-body .pl-mh .pl-en,
65 | .markdown-body .pl-ms {
66 | font-weight: bold;
67 | color: #1d3e81;
68 | }
69 | .markdown-body .pl-mq {
70 | color: #008080;
71 | }
72 | .markdown-body .pl-mi {
73 | font-style: italic;
74 | color: #333;
75 | }
76 | .markdown-body .pl-mb {
77 | font-weight: bold;
78 | color: #333;
79 | }
80 | .markdown-body .pl-md {
81 | color: #bd2c00;
82 | background-color: #ffecec;
83 | }
84 | .markdown-body .pl-mi1 {
85 | color: #55a532;
86 | background-color: #eaffea;
87 | }
88 | .markdown-body .pl-mdr {
89 | font-weight: bold;
90 | color: #795da3;
91 | }
92 | .markdown-body .pl-mo {
93 | color: #1d3e81;
94 | }
95 | .markdown-body .octicon {
96 | display: inline-block;
97 | vertical-align: text-top;
98 | fill: currentColor;
99 | }
100 | .markdown-body a {
101 | background-color: transparent;
102 | -webkit-text-decoration-skip: objects;
103 | }
104 | .markdown-body a:active,
105 | .markdown-body a:hover {
106 | outline-width: 0;
107 | }
108 | .markdown-body strong {
109 | font-weight: inherit;
110 | }
111 | .markdown-body strong {
112 | font-weight: bolder;
113 | }
114 | .markdown-body h1 {
115 | font-size: 2em;
116 | margin: 0.67em 0;
117 | }
118 | .markdown-body img {
119 | border-style: none;
120 | }
121 | .markdown-body svg:not(:root) {
122 | overflow: hidden;
123 | }
124 | .markdown-body code,
125 | .markdown-body kbd,
126 | .markdown-body pre {
127 | font-family: monospace, monospace;
128 | font-size: 1em;
129 | }
130 | .markdown-body hr {
131 | box-sizing: content-box;
132 | height: 0;
133 | overflow: visible;
134 | }
135 | .markdown-body input {
136 | font: inherit;
137 | margin: 0;
138 | }
139 | .markdown-body input {
140 | overflow: visible;
141 | }
142 | .markdown-body [type="checkbox"] {
143 | box-sizing: border-box;
144 | padding: 0;
145 | }
146 | .markdown-body * {
147 | box-sizing: border-box;
148 | }
149 | .markdown-body input {
150 | font-family: inherit;
151 | font-size: inherit;
152 | line-height: inherit;
153 | }
154 | .markdown-body a {
155 | color: #4078c0;
156 | text-decoration: none;
157 | }
158 | .markdown-body a:hover,
159 | .markdown-body a:active {
160 | text-decoration: underline;
161 | }
162 | .markdown-body strong {
163 | font-weight: 600;
164 | }
165 | .markdown-body hr {
166 | height: 0;
167 | margin: 15px 0;
168 | overflow: hidden;
169 | background: transparent;
170 | border: 0;
171 | border-bottom: 1px solid #ddd;
172 | }
173 | .markdown-body hr::before {
174 | display: table;
175 | content: "";
176 | }
177 | .markdown-body hr::after {
178 | display: table;
179 | clear: both;
180 | content: "";
181 | }
182 | .markdown-body table {
183 | border-spacing: 0;
184 | border-collapse: collapse;
185 | }
186 | .markdown-body td,
187 | .markdown-body th {
188 | padding: 0;
189 | }
190 | .markdown-body h1,
191 | .markdown-body h2,
192 | .markdown-body h3,
193 | .markdown-body h4,
194 | .markdown-body h5,
195 | .markdown-body h6 {
196 | margin-top: 0;
197 | margin-bottom: 0;
198 | }
199 | .markdown-body h1 {
200 | font-size: 32px;
201 | font-weight: 600;
202 | }
203 | .markdown-body h2 {
204 | font-size: 24px;
205 | font-weight: 600;
206 | }
207 | .markdown-body h3 {
208 | font-size: 20px;
209 | font-weight: 600;
210 | }
211 | .markdown-body h4 {
212 | font-size: 16px;
213 | font-weight: 600;
214 | }
215 | .markdown-body h5 {
216 | font-size: 14px;
217 | font-weight: 600;
218 | }
219 | .markdown-body h6 {
220 | font-size: 12px;
221 | font-weight: 600;
222 | }
223 | .markdown-body p {
224 | margin-top: 0;
225 | margin-bottom: 10px;
226 | }
227 | .markdown-body blockquote {
228 | margin: 0;
229 | }
230 | .markdown-body ul,
231 | .markdown-body ol {
232 | padding-left: 0;
233 | margin-top: 0;
234 | margin-bottom: 0;
235 | }
236 | .markdown-body ol ol,
237 | .markdown-body ul ol {
238 | list-style-type: lower-roman;
239 | }
240 | .markdown-body ul ul ol,
241 | .markdown-body ul ol ol,
242 | .markdown-body ol ul ol,
243 | .markdown-body ol ol ol {
244 | list-style-type: lower-alpha;
245 | }
246 | .markdown-body dd {
247 | margin-left: 0;
248 | }
249 | .markdown-body code {
250 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
251 | font-size: 12px;
252 | }
253 | .markdown-body pre {
254 | margin-top: 0;
255 | margin-bottom: 0;
256 | font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace;
257 | }
258 | .markdown-body .octicon {
259 | vertical-align: text-bottom;
260 | }
261 | .markdown-body input {
262 | -webkit-font-feature-settings: "liga" 0;
263 | font-feature-settings: "liga" 0;
264 | }
265 | .markdown-body::before {
266 | display: table;
267 | content: "";
268 | }
269 | .markdown-body::after {
270 | display: table;
271 | clear: both;
272 | content: "";
273 | }
274 | .markdown-body>*:first-child {
275 | margin-top: 0 !important;
276 | }
277 | .markdown-body>*:last-child {
278 | margin-bottom: 0 !important;
279 | }
280 | .markdown-body a:not([href]) {
281 | color: inherit;
282 | text-decoration: none;
283 | }
284 | .markdown-body .anchor {
285 | float: left;
286 | padding-right: 4px;
287 | margin-left: -20px;
288 | line-height: 1;
289 | }
290 | .markdown-body .anchor:focus {
291 | outline: none;
292 | }
293 | .markdown-body p,
294 | .markdown-body blockquote,
295 | .markdown-body ul,
296 | .markdown-body ol,
297 | .markdown-body dl,
298 | .markdown-body table,
299 | .markdown-body pre {
300 | margin-top: 0;
301 | margin-bottom: 16px;
302 | }
303 | .markdown-body hr {
304 | height: 0.25em;
305 | padding: 0;
306 | margin: 24px 0;
307 | background-color: #e7e7e7;
308 | border: 0;
309 | }
310 | .markdown-body blockquote {
311 | padding: 0 1em;
312 | color: #777;
313 | border-left: 0.25em solid #ddd;
314 | }
315 | .markdown-body blockquote>:first-child {
316 | margin-top: 0;
317 | }
318 | .markdown-body blockquote>:last-child {
319 | margin-bottom: 0;
320 | }
321 | .markdown-body kbd {
322 | display: inline-block;
323 | padding: 3px 5px;
324 | font-size: 11px;
325 | line-height: 10px;
326 | color: #555;
327 | vertical-align: middle;
328 | background-color: #fcfcfc;
329 | border: solid 1px #ccc;
330 | border-bottom-color: #bbb;
331 | border-radius: 3px;
332 | box-shadow: inset 0 -1px 0 #bbb;
333 | }
334 | .markdown-body h1,
335 | .markdown-body h2,
336 | .markdown-body h3,
337 | .markdown-body h4,
338 | .markdown-body h5,
339 | .markdown-body h6 {
340 | margin-top: 24px;
341 | margin-bottom: 16px;
342 | font-weight: 600;
343 | line-height: 1.25;
344 | }
345 | .markdown-body h1 .octicon-link,
346 | .markdown-body h2 .octicon-link,
347 | .markdown-body h3 .octicon-link,
348 | .markdown-body h4 .octicon-link,
349 | .markdown-body h5 .octicon-link,
350 | .markdown-body h6 .octicon-link {
351 | color: #000;
352 | vertical-align: middle;
353 | visibility: hidden;
354 | }
355 | .markdown-body h1:hover .anchor,
356 | .markdown-body h2:hover .anchor,
357 | .markdown-body h3:hover .anchor,
358 | .markdown-body h4:hover .anchor,
359 | .markdown-body h5:hover .anchor,
360 | .markdown-body h6:hover .anchor {
361 | text-decoration: none;
362 | }
363 | .markdown-body h1:hover .anchor .octicon-link,
364 | .markdown-body h2:hover .anchor .octicon-link,
365 | .markdown-body h3:hover .anchor .octicon-link,
366 | .markdown-body h4:hover .anchor .octicon-link,
367 | .markdown-body h5:hover .anchor .octicon-link,
368 | .markdown-body h6:hover .anchor .octicon-link {
369 | visibility: visible;
370 | }
371 | .markdown-body h1 {
372 | padding-bottom: 0.3em;
373 | font-size: 2em;
374 | border-bottom: 1px solid #eee;
375 | }
376 | .markdown-body h2 {
377 | padding-bottom: 0.3em;
378 | font-size: 1.5em;
379 | border-bottom: 1px solid #eee;
380 | }
381 | .markdown-body h3 {
382 | font-size: 1.25em;
383 | }
384 | .markdown-body h4 {
385 | font-size: 1em;
386 | }
387 | .markdown-body h5 {
388 | font-size: 0.875em;
389 | }
390 | .markdown-body h6 {
391 | font-size: 0.85em;
392 | color: #777;
393 | }
394 | .markdown-body ul,
395 | .markdown-body ol {
396 | padding-left: 2em;
397 | }
398 | .markdown-body ul ul,
399 | .markdown-body ul ol,
400 | .markdown-body ol ol,
401 | .markdown-body ol ul {
402 | margin-top: 0;
403 | margin-bottom: 0;
404 | }
405 | .markdown-body li>p {
406 | margin-top: 16px;
407 | }
408 | .markdown-body li+li {
409 | margin-top: 0.25em;
410 | }
411 | .markdown-body dl {
412 | padding: 0;
413 | }
414 | .markdown-body dl dt {
415 | padding: 0;
416 | margin-top: 16px;
417 | font-size: 1em;
418 | font-style: italic;
419 | font-weight: bold;
420 | }
421 | .markdown-body dl dd {
422 | padding: 0 16px;
423 | margin-bottom: 16px;
424 | }
425 | .markdown-body table {
426 | display: block;
427 | width: 100%;
428 | overflow: auto;
429 | }
430 | .markdown-body table th {
431 | font-weight: bold;
432 | }
433 | .markdown-body table th,
434 | .markdown-body table td {
435 | padding: 6px 13px;
436 | border: 1px solid #ddd;
437 | }
438 | .markdown-body table tr {
439 | background-color: #fff;
440 | border-top: 1px solid #ccc;
441 | }
442 | .markdown-body table tr:nth-child(2n) {
443 | background-color: #f8f8f8;
444 | }
445 | .markdown-body img {
446 | max-width: 100%;
447 | box-sizing: content-box;
448 | background-color: #fff;
449 | }
450 | .markdown-body code {
451 | padding: 0;
452 | padding-top: 0.2em;
453 | padding-bottom: 0.2em;
454 | margin: 0;
455 | font-size: 85%;
456 | background-color: rgba(0,0,0,0.04);
457 | border-radius: 3px;
458 | }
459 | .markdown-body code::before,
460 | .markdown-body code::after {
461 | letter-spacing: -0.2em;
462 | content: "\00a0";
463 | }
464 | .markdown-body pre {
465 | word-wrap: normal;
466 | }
467 | .markdown-body pre>code {
468 | padding: 0;
469 | margin: 0;
470 | font-size: 100%;
471 | word-break: normal;
472 | white-space: pre;
473 | background: transparent;
474 | border: 0;
475 | }
476 | .markdown-body .highlight {
477 | margin-bottom: 16px;
478 | }
479 | .markdown-body .highlight pre {
480 | margin-bottom: 0;
481 | word-break: normal;
482 | }
483 | .markdown-body .highlight pre,
484 | .markdown-body pre {
485 | padding: 16px;
486 | overflow: auto;
487 | font-size: 85%;
488 | line-height: 1.45;
489 | background-color: #f7f7f7;
490 | border-radius: 3px;
491 | }
492 | .markdown-body pre code {
493 | display: inline;
494 | max-width: auto;
495 | padding: 0;
496 | margin: 0;
497 | overflow: visible;
498 | line-height: inherit;
499 | word-wrap: normal;
500 | background-color: transparent;
501 | border: 0;
502 | }
503 | .markdown-body pre code::before,
504 | .markdown-body pre code::after {
505 | content: normal;
506 | }
507 | .markdown-body .pl-0 {
508 | padding-left: 0 !important;
509 | }
510 | .markdown-body .pl-1 {
511 | padding-left: 3px !important;
512 | }
513 | .markdown-body .pl-2 {
514 | padding-left: 6px !important;
515 | }
516 | .markdown-body .pl-3 {
517 | padding-left: 12px !important;
518 | }
519 | .markdown-body .pl-4 {
520 | padding-left: 24px !important;
521 | }
522 | .markdown-body .pl-5 {
523 | padding-left: 36px !important;
524 | }
525 | .markdown-body .pl-6 {
526 | padding-left: 48px !important;
527 | }
528 | .markdown-body .full-commit .btn-outline:not(:disabled):hover {
529 | color: #4078c0;
530 | border: 1px solid #4078c0;
531 | }
532 | .markdown-body kbd {
533 | display: inline-block;
534 | padding: 3px 5px;
535 | font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace;
536 | line-height: 10px;
537 | color: #555;
538 | vertical-align: middle;
539 | background-color: #fcfcfc;
540 | border: solid 1px #ccc;
541 | border-bottom-color: #bbb;
542 | border-radius: 3px;
543 | box-shadow: inset 0 -1px 0 #bbb;
544 | }
545 | .markdown-body :checked+.radio-label {
546 | position: relative;
547 | z-index: 1;
548 | border-color: #4078c0;
549 | }
550 | .markdown-body .task-list-item {
551 | list-style-type: none;
552 | }
553 | .markdown-body .task-list-item+.task-list-item {
554 | margin-top: 3px;
555 | }
556 | .markdown-body .task-list-item input {
557 | margin: 0 0.2em 0.25em -1.6em;
558 | vertical-align: middle;
559 | }
560 | .markdown-body hr {
561 | border-bottom-color: #eee;
562 | }
563 | `;
564 |
565 | if(!document.getElementById('github-markdown-css')) {
566 | const styleNode = document.createElement('style');
567 | styleNode.id = 'github-markdown-css';
568 | styleNode.innerHTML = styles;
569 |
570 | document.head.appendChild(styleNode);
571 | }
572 |
573 |
--------------------------------------------------------------------------------
/src/withTests.js:
--------------------------------------------------------------------------------
1 | import addons from '@storybook/addons';
2 | import { normalize } from 'upath'
3 |
4 | const findTestResults = (testFiles, jestTestResults, jestTestFilesOptions) =>
5 | testFiles.map(name => {
6 | const fileName = `${name}${jestTestFilesOptions.filesExt}`;
7 | if (jestTestResults && jestTestResults.testResults) {
8 | return {
9 | fileName,
10 | name,
11 | result: jestTestResults.testResults.find(t => normalize(t.name).includes(fileName)),
12 | };
13 | }
14 | return { fileName, name };
15 | });
16 |
17 | const withTests = (results, options) => (...testFiles) => {
18 |
19 | const emitAddTests = ({ kind, story }) => {
20 | addons.getChannel().emit('storybook/tests/add_tests', {
21 | kind,
22 | storyName: story,
23 | tests: findTestResults(testFiles, results, options),
24 | });
25 | };
26 |
27 | return (storyFn, { kind, story }) => {
28 | emitAddTests({ kind, story });
29 | return storyFn();
30 | };
31 | }
32 |
33 | export default withTests;
34 |
--------------------------------------------------------------------------------
/storybook-addon-jest.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/storybook-eol/storybook-addon-jest/5e2859043c9c486514629d8d86f9c87e98a2bb4e/storybook-addon-jest.gif
--------------------------------------------------------------------------------
/styles.js:
--------------------------------------------------------------------------------
1 | require('./dist/styles');
2 |
--------------------------------------------------------------------------------