-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
index.js
135 lines (111 loc) · 4.1 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import path from 'path';
import fs from 'fs';
import glob from 'glob';
import global, { describe, it } from 'global';
import readPkgUp from 'read-pkg-up';
import addons from '@storybook/addons';
import runWithRequireContext from './require_context';
import createChannel from './storybook-channel-mock';
import { snapshotWithOptions } from './test-bodies';
import { getPossibleStoriesFiles, getSnapshotFileName } from './utils';
export {
snapshot,
multiSnapshotWithOptions,
snapshotWithOptions,
shallowSnapshot,
renderOnly,
} from './test-bodies';
export { getSnapshotFileName };
let storybook;
let configPath;
global.STORYBOOK_REACT_CLASSES = global.STORYBOOK_REACT_CLASSES || {};
const babel = require('babel-core');
const { pkg } = readPkgUp.sync();
const hasDependency = name =>
(pkg.devDependencies && pkg.devDependencies[name]) ||
(pkg.dependencies && pkg.dependencies[name]) ||
fs.existsSync(path.join('node_modules', name, 'package.json'));
export default function testStorySnapshots(options = {}) {
addons.setChannel(createChannel());
const isStorybook =
options.framework === 'react' || (!options.framework && hasDependency('@storybook/react'));
const isRNStorybook =
options.framework === 'react-native' ||
(!options.framework && hasDependency('@storybook/react-native'));
if (isStorybook) {
storybook = require.requireActual('@storybook/react');
// eslint-disable-next-line
const loadBabelConfig = require('@storybook/react/dist/server/babel_config')
.default;
const configDirPath = path.resolve(options.configPath || '.storybook');
configPath = path.join(configDirPath, 'config.js');
const babelConfig = loadBabelConfig(configDirPath);
const content = babel.transformFileSync(configPath, babelConfig).code;
const contextOpts = {
filename: configPath,
dirname: configDirPath,
};
runWithRequireContext(content, contextOpts);
} else if (isRNStorybook) {
storybook = require.requireActual('@storybook/react-native');
configPath = path.resolve(options.configPath || 'storybook');
require.requireActual(configPath);
} else {
throw new Error('storyshots is intended only to be used with storybook');
}
if (typeof describe !== 'function') {
throw new Error('testStorySnapshots is intended only to be used inside jest');
}
// NOTE: keep `suit` typo for backwards compatibility
const suite = options.suite || options.suit || 'Storyshots';
const stories = storybook.getStorybook();
if (stories.length === 0) {
throw new Error('storyshots found 0 stories');
}
// Added not to break existing storyshots configs (can be removed in a future major release)
// eslint-disable-next-line
options.storyNameRegex = options.storyNameRegex || options.storyRegex;
const snapshotOptions = {
renderer: options.renderer,
serializer: options.serializer,
};
// eslint-disable-next-line
options.test =
options.test || snapshotWithOptions({ options: snapshotOptions });
// eslint-disable-next-line
for (const group of stories) {
const { fileName, kind } = group;
if (options.storyKindRegex && !kind.match(options.storyKindRegex)) {
// eslint-disable-next-line
continue;
}
describe(suite, () => {
describe(kind, () => {
// eslint-disable-next-line
for (const story of group.stories) {
if (options.storyNameRegex && !story.name.match(options.storyNameRegex)) {
// eslint-disable-next-line
continue;
}
it(story.name, () => {
const context = { fileName, kind, story: story.name };
return options.test({
story,
context,
});
});
}
});
});
}
}
describe('Storyshots Integrity', () => {
describe('Abandoned Storyshots', () => {
const storyshots = glob.sync('**/*.storyshot');
const abandonedStoryshots = storyshots.filter(fileName => {
const possibleStoriesFiles = getPossibleStoriesFiles(fileName);
return !possibleStoriesFiles.some(fs.existsSync);
});
expect(abandonedStoryshots).toHaveLength(0);
});
});