creevey 0.7.39 → 0.9.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -2
- package/README.md +1 -1
- package/docs/config.md +37 -5
- package/docs/grid.md +2 -1
- package/lib/cjs/client/addon/Manager.js +3 -2
- package/lib/cjs/client/addon/preset.js +1 -0
- package/lib/cjs/client/addon/readyForCapture.js +12 -0
- package/lib/cjs/client/addon/utils.js +1 -41
- package/lib/cjs/client/addon/withCreevey.js +313 -41
- package/lib/cjs/client/shared/components/ImagesView/BlendView.js +3 -3
- package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +3 -3
- package/lib/cjs/client/shared/components/ImagesView/SlideView.js +4 -3
- package/lib/cjs/client/shared/components/ImagesView/SwapView.js +3 -3
- package/lib/cjs/client/shared/helpers.js +1 -1
- package/lib/cjs/client/web/1.js +2 -2
- package/lib/cjs/client/web/2.js +1 -1
- package/lib/cjs/client/web/main.js +6 -6
- package/lib/cjs/index.js +27 -9
- package/lib/cjs/server/config.js +7 -3
- package/lib/cjs/server/extract.js +11 -4
- package/lib/cjs/server/index.js +2 -4
- package/lib/cjs/server/loaders/babel/register.js +2 -1
- package/lib/cjs/server/master/index.js +3 -9
- package/lib/cjs/server/master/master.js +1 -0
- package/lib/cjs/server/master/pool.js +29 -29
- package/lib/cjs/server/master/server.js +75 -3
- package/lib/cjs/server/messages.js +124 -12
- package/lib/cjs/server/parser.js +85 -0
- package/lib/cjs/server/selenium/browser.js +119 -21
- package/lib/cjs/server/selenium/selenoid.js +1 -1
- package/lib/cjs/server/stories.js +49 -58
- package/lib/cjs/server/storybook/entry.js +5 -4
- package/lib/cjs/server/storybook/helpers.js +11 -3
- package/lib/cjs/server/storybook/providers/browser.js +78 -0
- package/lib/cjs/server/storybook/providers/hybrid.js +79 -0
- package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +42 -18
- package/lib/cjs/server/utils.js +32 -2
- package/lib/cjs/server/worker/helpers.js +2 -6
- package/lib/cjs/server/worker/worker.js +15 -3
- package/lib/cjs/shared.js +107 -0
- package/lib/cjs/types.js +5 -0
- package/lib/esm/client/addon/Manager.js +3 -3
- package/lib/esm/client/addon/preset.js +1 -0
- package/lib/esm/client/addon/readyForCapture.js +5 -0
- package/lib/esm/client/addon/utils.js +1 -33
- package/lib/esm/client/addon/withCreevey.js +303 -41
- package/lib/esm/client/shared/components/ImagesView/BlendView.js +2 -3
- package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +2 -3
- package/lib/esm/client/shared/components/ImagesView/SlideView.js +3 -3
- package/lib/esm/client/shared/components/ImagesView/SwapView.js +2 -3
- package/lib/esm/client/shared/helpers.js +1 -1
- package/lib/esm/index.js +6 -3
- package/lib/esm/server/config.js +7 -5
- package/lib/esm/server/extract.js +8 -4
- package/lib/esm/server/index.js +2 -3
- package/lib/esm/server/loaders/babel/register.js +3 -2
- package/lib/esm/server/master/index.js +4 -10
- package/lib/esm/server/master/master.js +1 -0
- package/lib/esm/server/master/pool.js +31 -31
- package/lib/esm/server/master/server.js +73 -5
- package/lib/esm/server/messages.js +118 -12
- package/lib/esm/server/parser.js +63 -0
- package/lib/esm/server/selenium/browser.js +116 -23
- package/lib/esm/server/selenium/selenoid.js +1 -1
- package/lib/esm/server/stories.js +51 -58
- package/lib/esm/server/storybook/entry.js +4 -4
- package/lib/esm/server/storybook/helpers.js +9 -3
- package/lib/esm/server/storybook/providers/browser.js +61 -0
- package/lib/esm/server/storybook/providers/hybrid.js +63 -0
- package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +40 -18
- package/lib/esm/server/utils.js +29 -2
- package/lib/esm/server/worker/helpers.js +2 -6
- package/lib/esm/server/worker/worker.js +16 -4
- package/lib/esm/shared.js +76 -0
- package/lib/esm/types.js +3 -0
- package/lib/types/client/addon/preset.d.ts +2 -0
- package/lib/types/client/addon/readyForCapture.d.ts +6 -0
- package/lib/types/client/addon/utils.d.ts +1 -5
- package/lib/types/client/addon/withCreevey.d.ts +13 -2
- package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +2 -2
- package/lib/types/index.d.ts +2 -1
- package/lib/types/server/config.d.ts +1 -1
- package/lib/types/server/master/master.d.ts +1 -0
- package/lib/types/server/master/pool.d.ts +1 -0
- package/lib/types/server/master/server.d.ts +1 -1
- package/lib/types/server/messages.d.ts +12 -2
- package/lib/types/server/parser.d.ts +12 -0
- package/lib/types/server/selenium/browser.d.ts +5 -2
- package/lib/types/server/stories.d.ts +1 -2
- package/lib/types/server/storybook/entry.d.ts +13 -9
- package/lib/types/server/storybook/helpers.d.ts +1 -0
- package/lib/types/server/storybook/providers/browser.d.ts +4 -0
- package/lib/types/server/storybook/providers/hybrid.d.ts +4 -0
- package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
- package/lib/types/server/utils.d.ts +2 -0
- package/lib/types/server/worker/helpers.d.ts +2 -1
- package/lib/types/shared.d.ts +16 -0
- package/lib/types/types.d.ts +33 -4
- package/package.json +28 -18
- package/storybook-static/stories.json +4 -513
- package/types/mocha.d.ts +1 -0
- package/lib/types/server/storybook/nodejs-provider.d.ts +0 -5
@@ -2,15 +2,15 @@
|
|
2
2
|
import path from 'path';
|
3
3
|
import { isWorker, isMaster } from 'cluster';
|
4
4
|
import chokidar from 'chokidar';
|
5
|
-
import { noop } from '
|
6
|
-
import { getCreeveyCache } from '
|
7
|
-
import { subscribeOn } from '
|
8
|
-
import { importStorybookClientLogger, importStorybookConfig, importStorybookCoreCommon, importStorybookCoreEvents, isStorybookVersionLessThan } from '
|
9
|
-
import { logger } from '
|
10
|
-
import {
|
5
|
+
import { noop } from '../../../types';
|
6
|
+
import { getCreeveyCache } from '../../utils';
|
7
|
+
import { subscribeOn } from '../../messages';
|
8
|
+
import { importStorybookClientLogger, importStorybookConfig, importStorybookCoreCommon, importStorybookCoreEvents, isStorybookVersionGreaterThan, isStorybookVersionLessThan } from '../helpers';
|
9
|
+
import { logger } from '../../logger';
|
10
|
+
import { denormalizeStoryParameters } from '../../../shared';
|
11
11
|
|
12
12
|
async function initStorybookEnvironment() {
|
13
|
-
// @ts-
|
13
|
+
// @ts-expect-error There is no @types/global-jsdom package
|
14
14
|
(await import('global-jsdom')).default(undefined, {
|
15
15
|
url: 'http://localhost'
|
16
16
|
}); // NOTE Cutoff `jsdom` part from userAgent, because storybook check enviroment and create events channel if runs in browser
|
@@ -28,7 +28,7 @@ async function initStorybookEnvironment() {
|
|
28
28
|
if (isWorker) logger.warn = noop; // NOTE: disable logger for 5.x storybook
|
29
29
|
|
30
30
|
logger.debug = noop;
|
31
|
-
return import('
|
31
|
+
return import('../entry');
|
32
32
|
}
|
33
33
|
|
34
34
|
function watchStories(channel, watcher, initialFiles) {
|
@@ -39,7 +39,7 @@ function watchStories(channel, watcher, initialFiles) {
|
|
39
39
|
watcher.on('change', filePath => storiesByFiles.set(path.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
|
40
40
|
watcher.on('unlink', filePath => storiesByFiles.set(path.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
|
41
41
|
return data => {
|
42
|
-
const stories = isStorybookVersionLessThan(6) ? data.stories :
|
42
|
+
const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
|
43
43
|
const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
|
44
44
|
const addedFiles = Array.from(files).filter(filePath => !watchingFiles.has(filePath));
|
45
45
|
const removedFiles = Array.from(watchingFiles).filter(filePath => !files.has(filePath));
|
@@ -84,13 +84,14 @@ async function loadStoriesDirectly(config, {
|
|
84
84
|
debug
|
85
85
|
}) {
|
86
86
|
const {
|
87
|
-
toRequireContext
|
87
|
+
toRequireContext,
|
88
|
+
normalizeStoriesEntry
|
88
89
|
} = await importStorybookCoreCommon();
|
89
90
|
const {
|
90
91
|
addParameters,
|
91
92
|
configure
|
92
|
-
} = await import('
|
93
|
-
const requireContext = await (await import('
|
93
|
+
} = await import('../entry');
|
94
|
+
const requireContext = await (await import('../../loaders/babel/register')).default(config, debug);
|
94
95
|
|
95
96
|
const preview = (() => {
|
96
97
|
try {
|
@@ -103,12 +104,16 @@ async function loadStoriesDirectly(config, {
|
|
103
104
|
const {
|
104
105
|
stories
|
105
106
|
} = await importStorybookConfig();
|
106
|
-
const contexts = stories.map(
|
107
|
+
const contexts = stories.map(entry => {
|
108
|
+
const normalizedEntry = isStorybookVersionLessThan(6, 4) ? entry : normalizeStoriesEntry(entry, {
|
109
|
+
configDir: config.storybookDir,
|
110
|
+
workingDir: process.cwd()
|
111
|
+
});
|
107
112
|
const {
|
108
113
|
path: storiesPath,
|
109
114
|
recursive,
|
110
115
|
match
|
111
|
-
} = toRequireContext(
|
116
|
+
} = toRequireContext(normalizedEntry);
|
112
117
|
watcher === null || watcher === void 0 ? void 0 : watcher.add(path.resolve(config.storybookDir, storiesPath));
|
113
118
|
return () => requireContext(storiesPath, recursive, new RegExp(match));
|
114
119
|
});
|
@@ -162,7 +167,8 @@ async function loadStoriesDirectly(config, {
|
|
162
167
|
void startStorybook();
|
163
168
|
});
|
164
169
|
void startStorybook();
|
165
|
-
}
|
170
|
+
} // TODO Do we need to support multiple storybooks here?
|
171
|
+
|
166
172
|
|
167
173
|
export async function loadStories(config, {
|
168
174
|
watch,
|
@@ -175,16 +181,16 @@ export async function loadStories(config, {
|
|
175
181
|
} = storybookApi;
|
176
182
|
channel.removeAllListeners(Events.CURRENT_STORY_WAS_SET);
|
177
183
|
channel.on('storiesUpdated', storiesListener);
|
178
|
-
let watcher
|
184
|
+
let watcher;
|
179
185
|
if (watch) watcher = chokidar.watch([], {
|
180
186
|
ignoreInitial: true
|
181
187
|
});
|
182
188
|
const loadPromise = new Promise(resolve => {
|
183
189
|
channel.once(Events.SET_STORIES, data => {
|
184
|
-
const stories = isStorybookVersionLessThan(6) ? data.stories :
|
190
|
+
const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
|
185
191
|
const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
|
186
192
|
if (watcher) channel.on(Events.SET_STORIES, watchStories(channel, watcher, files));
|
187
|
-
resolve(
|
193
|
+
resolve(stories);
|
188
194
|
});
|
189
195
|
});
|
190
196
|
if (config.useWebpackToExtractTests) loadStoriesFromBundle(watch);else void loadStoriesDirectly(config, {
|
@@ -192,4 +198,20 @@ export async function loadStories(config, {
|
|
192
198
|
debug
|
193
199
|
});
|
194
200
|
return loadPromise;
|
201
|
+
}
|
202
|
+
export async function extractStoriesData(config, {
|
203
|
+
watch,
|
204
|
+
debug
|
205
|
+
}) {
|
206
|
+
const storybookApi = await initStorybookEnvironment();
|
207
|
+
const Events = await importStorybookCoreEvents();
|
208
|
+
const {
|
209
|
+
channel
|
210
|
+
} = storybookApi;
|
211
|
+
channel.removeAllListeners(Events.CURRENT_STORY_WAS_SET);
|
212
|
+
const loadPromise = new Promise(resolve => channel.once(Events.SET_STORIES, resolve));
|
213
|
+
if (config.useWebpackToExtractTests) loadStoriesFromBundle(watch);else void loadStoriesDirectly(config, {
|
214
|
+
debug
|
215
|
+
});
|
216
|
+
return loadPromise;
|
195
217
|
}
|
package/lib/esm/server/utils.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { createWriteStream, existsSync, readFileSync, unlink } from 'fs';
|
1
|
+
import { createWriteStream, existsSync, readFileSync, readdirSync, unlink } from 'fs';
|
2
2
|
import cluster from 'cluster';
|
3
3
|
import { isDefined, noop, isFunction } from '../types';
|
4
4
|
import { emitShutdownMessage, sendShutdownMessage } from './messages';
|
@@ -9,6 +9,7 @@ export const isShuttingDown = {
|
|
9
9
|
};
|
10
10
|
export const LOCALHOST_REGEXP = /(localhost|127\.0\.0\.1)/i;
|
11
11
|
export const extensions = ['.js', '.jsx', '.ts', '.tsx'];
|
12
|
+
export const skipOptionKeys = ['in', 'kinds', 'stories', 'tests', 'reason'];
|
12
13
|
|
13
14
|
function matchBy(pattern, value) {
|
14
15
|
return typeof pattern == 'string' && pattern == value || Array.isArray(pattern) && pattern.includes(value) || pattern instanceof RegExp && pattern.test(value) || !isDefined(pattern);
|
@@ -20,9 +21,30 @@ export function shouldSkip(browser, meta, skipOptions, test) {
|
|
20
21
|
}
|
21
22
|
|
22
23
|
if (Array.isArray(skipOptions)) {
|
23
|
-
|
24
|
+
for (const skip of skipOptions) {
|
25
|
+
const reason = shouldSkip(browser, meta, skip, test);
|
26
|
+
if (reason) return reason;
|
27
|
+
}
|
28
|
+
|
29
|
+
return false;
|
30
|
+
}
|
31
|
+
|
32
|
+
let hasSkipOptionKeys = false;
|
33
|
+
|
34
|
+
for (const skipKey in skipOptions) {
|
35
|
+
if (skipOptionKeys.includes(skipKey)) {
|
36
|
+
hasSkipOptionKeys = true;
|
37
|
+
continue;
|
38
|
+
}
|
39
|
+
|
40
|
+
const reason = shouldSkip(browser, meta, {
|
41
|
+
reason: skipKey,
|
42
|
+
...skipOptions[skipKey]
|
43
|
+
}, test);
|
44
|
+
if (reason) return reason;
|
24
45
|
}
|
25
46
|
|
47
|
+
if (!hasSkipOptionKeys) return false;
|
26
48
|
const {
|
27
49
|
in: browsers,
|
28
50
|
kinds,
|
@@ -116,4 +138,9 @@ export function removeProps(obj, propPath) {
|
|
116
138
|
if (typeof prop == 'string') delete obj[prop];
|
117
139
|
if (isFunction(prop)) Object.keys(obj).filter(prop).forEach(key => delete obj[key]);
|
118
140
|
}
|
141
|
+
}
|
142
|
+
export function readDirRecursive(dirPath) {
|
143
|
+
return [].concat(...readdirSync(dirPath, {
|
144
|
+
withFileTypes: true
|
145
|
+
}).map(dirent => dirent.isDirectory() ? readDirRecursive(`${dirPath}/${dirent.name}`) : [`${dirPath}/${dirent.name}`]));
|
119
146
|
}
|
@@ -47,14 +47,10 @@ function removeTestOrSuite(testOrSuite) {
|
|
47
47
|
|
48
48
|
export async function addTestsFromStories(rootSuite, config, {
|
49
49
|
browser,
|
50
|
-
|
51
|
-
debug
|
50
|
+
...options
|
52
51
|
}) {
|
53
52
|
const mochaTestsById = new Map();
|
54
|
-
const tests = await loadTestsFromStories([browser], listener => config.storiesProvider(config, {
|
55
|
-
watch,
|
56
|
-
debug
|
57
|
-
}, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
|
53
|
+
const tests = await loadTestsFromStories([browser], listener => config.storiesProvider(config, options, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
|
58
54
|
const oldTest = mochaTestsById.get(id);
|
59
55
|
mochaTestsById.delete(id);
|
60
56
|
if (oldTest) removeTestOrSuite(oldTest);
|
@@ -8,7 +8,7 @@ import { Key, until } from 'selenium-webdriver';
|
|
8
8
|
import { isImageError } from '../../types';
|
9
9
|
import { subscribeOn, emitTestMessage, emitWorkerMessage } from '../messages';
|
10
10
|
import chaiImage from './chai-image';
|
11
|
-
import { getBrowser, switchStory } from '../selenium';
|
11
|
+
import { closeBrowser, getBrowser, switchStory } from '../selenium';
|
12
12
|
import { CreeveyReporter, TeamcityReporter } from './reporter';
|
13
13
|
import { addTestsFromStories } from './helpers';
|
14
14
|
import { logger } from '../logger';
|
@@ -49,6 +49,7 @@ export default async function worker(config, options) {
|
|
49
49
|
let retries = 0;
|
50
50
|
let images = {};
|
51
51
|
let error = undefined;
|
52
|
+
const screenshots = [];
|
52
53
|
const testScope = [];
|
53
54
|
|
54
55
|
function runHandler(failures) {
|
@@ -173,13 +174,23 @@ export default async function worker(config, options) {
|
|
173
174
|
|
174
175
|
mocha.cleanReferencesAfterRun(false);
|
175
176
|
chai.use(chaiImage(getExpected, config.diffOptions));
|
177
|
+
if ((await getBrowser(config, options.browser)) == null) return;
|
176
178
|
await addTestsFromStories(mocha.suite, config, {
|
177
179
|
browser: options.browser,
|
178
180
|
watch: options.ui,
|
179
|
-
debug: options.debug
|
181
|
+
debug: options.debug,
|
182
|
+
port: options.port
|
180
183
|
});
|
181
|
-
|
182
|
-
|
184
|
+
|
185
|
+
try {
|
186
|
+
var _await$getBrowser;
|
187
|
+
|
188
|
+
await ((_await$getBrowser = await getBrowser(config, options.browser)) === null || _await$getBrowser === void 0 ? void 0 : _await$getBrowser.getCurrentUrl());
|
189
|
+
} catch (_) {
|
190
|
+
await closeBrowser();
|
191
|
+
}
|
192
|
+
|
193
|
+
const browser = await getBrowser(config, options.browser);
|
183
194
|
const sessionId = (_await$browser$getSes = await (browser === null || browser === void 0 ? void 0 : browser.getSession())) === null || _await$browser$getSes === void 0 ? void 0 : _await$browser$getSes.getId();
|
184
195
|
if (browser == null) return;
|
185
196
|
const interval = setInterval(() => void browser.getCurrentUrl().then(url => {
|
@@ -194,6 +205,7 @@ export default async function worker(config, options) {
|
|
194
205
|
this.expect = chai.expect;
|
195
206
|
this.browserName = options.browser;
|
196
207
|
this.testScope = testScope;
|
208
|
+
this.screenshots = screenshots;
|
197
209
|
});
|
198
210
|
mocha.suite.beforeEach(switchStory);
|
199
211
|
subscribeOn('test', message => {
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import { mapValues, mergeWith, cloneDeepWith } from 'lodash';
|
2
|
+
// NOTE: Copy-paste from storybook/api
|
3
|
+
export const combineParameters = (...parameterSets) => // eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
4
|
+
mergeWith({}, ...parameterSets, (_, srcValue) => {
|
5
|
+
// Treat arrays as scalars:
|
6
|
+
if (Array.isArray(srcValue)) return srcValue;
|
7
|
+
return undefined;
|
8
|
+
}); // NOTE: Copy-paste from storybook/api
|
9
|
+
|
10
|
+
export const denormalizeStoryParameters = ({
|
11
|
+
globalParameters,
|
12
|
+
kindParameters,
|
13
|
+
stories
|
14
|
+
}) => {
|
15
|
+
return mapValues(stories, storyData => {
|
16
|
+
var _globalParameters$cre, _kindParameters$story, _kindParameters$story2;
|
17
|
+
|
18
|
+
storyData.parameters.creevey = combineParameters((_globalParameters$cre = globalParameters.creevey) !== null && _globalParameters$cre !== void 0 ? _globalParameters$cre : {}, (_kindParameters$story = (_kindParameters$story2 = kindParameters[storyData.kind]) === null || _kindParameters$story2 === void 0 ? void 0 : _kindParameters$story2.creevey) !== null && _kindParameters$story !== void 0 ? _kindParameters$story : {}, storyData.parameters.creevey);
|
19
|
+
return storyData;
|
20
|
+
});
|
21
|
+
};
|
22
|
+
export const isSerializedRegExp = exp => {
|
23
|
+
return typeof exp === 'object' && exp !== null && Reflect.get(exp, '__regexp') === true;
|
24
|
+
};
|
25
|
+
export const serializeRegExp = exp => {
|
26
|
+
const {
|
27
|
+
source,
|
28
|
+
flags
|
29
|
+
} = exp;
|
30
|
+
return {
|
31
|
+
__regexp: true,
|
32
|
+
source,
|
33
|
+
flags
|
34
|
+
};
|
35
|
+
};
|
36
|
+
export const deserializeRegExp = ({
|
37
|
+
source,
|
38
|
+
flags
|
39
|
+
}) => {
|
40
|
+
return new RegExp(source, flags);
|
41
|
+
};
|
42
|
+
export const serializeRawStories = stories => {
|
43
|
+
return mapValues(stories, storyData => {
|
44
|
+
const creevey = storyData.parameters.creevey;
|
45
|
+
|
46
|
+
if ((creevey === null || creevey === void 0 ? void 0 : creevey.skip) !== undefined) {
|
47
|
+
creevey.skip = cloneDeepWith(creevey.skip, value => {
|
48
|
+
if (value instanceof RegExp) {
|
49
|
+
return serializeRegExp(value);
|
50
|
+
}
|
51
|
+
|
52
|
+
return undefined;
|
53
|
+
});
|
54
|
+
}
|
55
|
+
|
56
|
+
return storyData;
|
57
|
+
});
|
58
|
+
};
|
59
|
+
export const deserializeRawStories = stories => {
|
60
|
+
return mapValues(stories, deserializeStory);
|
61
|
+
};
|
62
|
+
export const deserializeStory = story => {
|
63
|
+
const creevey = story.parameters.creevey;
|
64
|
+
|
65
|
+
if ((creevey === null || creevey === void 0 ? void 0 : creevey.skip) !== undefined) {
|
66
|
+
creevey.skip = cloneDeepWith(creevey.skip, value => {
|
67
|
+
if (isSerializedRegExp(value)) {
|
68
|
+
return deserializeRegExp(value);
|
69
|
+
}
|
70
|
+
|
71
|
+
return undefined;
|
72
|
+
});
|
73
|
+
}
|
74
|
+
|
75
|
+
return story;
|
76
|
+
};
|
package/lib/esm/types.js
CHANGED
@@ -29,6 +29,9 @@ export function isProcessMessage(message) {
|
|
29
29
|
export function isWorkerMessage(message) {
|
30
30
|
return isProcessMessage(message) && message.scope == 'worker';
|
31
31
|
}
|
32
|
+
export function isStoriesMessage(message) {
|
33
|
+
return isProcessMessage(message) && message.scope == 'stories';
|
34
|
+
}
|
32
35
|
export function isTestMessage(message) {
|
33
36
|
return isProcessMessage(message) && message.scope == 'test';
|
34
37
|
}
|
@@ -3,12 +3,14 @@ import { Configuration } from 'webpack';
|
|
3
3
|
export declare function config(entry?: string[]): string[];
|
4
4
|
export declare function managerEntries(entry?: string[]): string[];
|
5
5
|
declare global {
|
6
|
+
const __CREEVEY_SERVER_HOST__: string;
|
6
7
|
const __CREEVEY_SERVER_PORT__: number;
|
7
8
|
const __CREEVEY_CLIENT_PORT__: number | null;
|
8
9
|
}
|
9
10
|
export interface CreeveyAddonOptions {
|
10
11
|
creeveyConfigPath?: string;
|
11
12
|
creeveyPreExtract?: string;
|
13
|
+
creeveyHost?: string;
|
12
14
|
creeveyPort?: number;
|
13
15
|
clientPort?: number;
|
14
16
|
configType: string;
|
@@ -1,6 +1,2 @@
|
|
1
|
-
import {
|
2
|
-
import { SetStoriesPayload } from '@storybook/api/dist/ts3.9/lib/stories';
|
3
|
-
import { StoriesRaw, TestStatus } from '../../types';
|
1
|
+
import { TestStatus } from '../../types';
|
4
2
|
export declare function getEmojiByTestStatus(status: TestStatus | undefined, skip?: string | boolean): string;
|
5
|
-
export declare const combineParameters: (...parameterSets: Parameters[]) => Parameters;
|
6
|
-
export declare const denormalizeStoryParameters: ({ globalParameters, kindParameters, stories, }: SetStoriesPayload) => StoriesRaw;
|
@@ -1,13 +1,24 @@
|
|
1
|
+
import type { PreviewWeb } from '@storybook/preview-web';
|
2
|
+
import type { AnyFramework } from '@storybook/csf';
|
3
|
+
import type { StoryStore } from '@storybook/client-api';
|
1
4
|
import { MakeDecoratorResult, Channel } from '@storybook/addons';
|
2
|
-
import { StorybookGlobals } from '../../types';
|
5
|
+
import { CaptureOptions, StoriesRaw, StorybookGlobals } from '../../types';
|
3
6
|
declare global {
|
4
7
|
interface Window {
|
5
|
-
|
8
|
+
__CREEVEY_SERVER_HOST__: string;
|
9
|
+
__CREEVEY_SERVER_PORT__: number;
|
10
|
+
__CREEVEY_WORKER_ID__: number;
|
11
|
+
__CREEVEY_GET_STORIES__: () => Promise<StoriesRaw | void>;
|
12
|
+
__CREEVEY_SELECT_STORY__: (storyId: string, kind: string, name: string, shouldWaitForReady: boolean, callback: (response: [error?: string | null, isCaptureCalled?: boolean]) => void) => void;
|
6
13
|
__CREEVEY_UPDATE_GLOBALS__: (globals: StorybookGlobals) => void;
|
7
14
|
__CREEVEY_INSERT_IGNORE_STYLES__: (ignoreElements: string[]) => HTMLStyleElement;
|
8
15
|
__CREEVEY_REMOVE_IGNORE_STYLES__: (ignoreStyles: HTMLStyleElement) => void;
|
16
|
+
__CREEVEY_HAS_PLAY_COMPLETED_YET__: (callback: (isPlayCompleted: boolean) => void) => void;
|
9
17
|
__CREEVEY_SET_READY_FOR_CAPTURE__?: () => void;
|
10
18
|
__STORYBOOK_ADDONS_CHANNEL__: Channel;
|
19
|
+
__STORYBOOK_STORY_STORE__: StoryStore<AnyFramework>;
|
20
|
+
__STORYBOOK_PREVIEW__: PreviewWeb<AnyFramework>;
|
11
21
|
}
|
12
22
|
}
|
13
23
|
export declare function withCreevey(): MakeDecoratorResult;
|
24
|
+
export declare function capture(options?: CaptureOptions): Promise<void>;
|
@@ -4,7 +4,7 @@ import { Theme } from '@storybook/theming';
|
|
4
4
|
export interface SuiteLinkProps {
|
5
5
|
title: string;
|
6
6
|
suite: CreeveySuite;
|
7
|
-
'data-
|
7
|
+
'data-testid'?: string;
|
8
8
|
}
|
9
9
|
export declare const Container: React.SFC<import("emotion-theming/types/helper").AddOptionalTo<Pick<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & Pick<{
|
10
10
|
theme: Theme;
|
@@ -30,4 +30,4 @@ export declare const Button: React.SFC<import("emotion-theming/types/helper").Ad
|
|
30
30
|
export declare const SuiteContainer: import("@emotion/styled-base").StyledComponent<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {
|
31
31
|
padding: number;
|
32
32
|
}, Theme>;
|
33
|
-
export declare function SuiteLink({ title, suite, 'data-
|
33
|
+
export declare function SuiteLink({ title, suite, 'data-testid': dataTid }: SuiteLinkProps): JSX.Element;
|
package/lib/types/index.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
import { Config, Options } from '../types';
|
2
2
|
export declare const defaultBrowser = "chrome";
|
3
|
-
export declare const defaultConfig: Omit<Config, 'gridUrl' | 'storiesProvider'>;
|
3
|
+
export declare const defaultConfig: Omit<Config, 'gridUrl' | 'storiesProvider' | 'testDir'>;
|
4
4
|
export declare function readConfig(options: Options): Promise<Config>;
|
@@ -1,2 +1,2 @@
|
|
1
1
|
import { CreeveyApi } from './api';
|
2
|
-
export default function server(reportDir: string, port: number): (api: CreeveyApi) => void;
|
2
|
+
export default function server(reportDir: string, port: number, ui: boolean): (api: CreeveyApi) => void;
|
@@ -1,18 +1,28 @@
|
|
1
1
|
/// <reference types="webpack-env" />
|
2
2
|
/// <reference types="node" />
|
3
3
|
import cluster from 'cluster';
|
4
|
-
import { WorkerMessage, TestMessage, WebpackMessage, DockerMessage, WorkerHandler, TestHandler, WebpackHandler, DockerHandler, ShutdownHandler } from '../types';
|
4
|
+
import { WorkerMessage, StoriesMessage, TestMessage, WebpackMessage, DockerMessage, WorkerHandler, StoriesHandler, TestHandler, WebpackHandler, DockerHandler, ShutdownHandler } from '../types';
|
5
5
|
export declare function emitWorkerMessage(message: WorkerMessage): boolean;
|
6
|
+
export declare function emitStoriesMessage(message: StoriesMessage): boolean;
|
6
7
|
export declare function emitTestMessage(message: TestMessage): boolean;
|
7
8
|
export declare function emitWebpackMessage(message: WebpackMessage): boolean;
|
8
9
|
export declare function emitDockerMessage(message: DockerMessage): boolean;
|
9
10
|
export declare function emitShutdownMessage(): boolean;
|
11
|
+
export declare function sendStoriesMessage(target: NodeJS.Process | cluster.Worker, message: StoriesMessage): void;
|
10
12
|
export declare function sendTestMessage(target: NodeJS.Process | cluster.Worker, message: TestMessage): void;
|
11
13
|
export declare function sendDockerMessage(target: NodeJS.Process | cluster.Worker, message: DockerMessage): void;
|
12
14
|
export declare function sendShutdownMessage(target: NodeJS.Process | cluster.Worker): void;
|
13
15
|
export declare function subscribeOn(scope: 'worker', handler: WorkerHandler): () => void;
|
16
|
+
export declare function subscribeOn(scope: 'stories', handler: StoriesHandler): () => void;
|
14
17
|
export declare function subscribeOn(scope: 'test', handler: TestHandler): () => void;
|
15
18
|
export declare function subscribeOn(scope: 'webpack', handler: WebpackHandler): () => void;
|
16
19
|
export declare function subscribeOn(scope: 'docker', handler: DockerHandler): () => void;
|
17
20
|
export declare function subscribeOn(scope: 'shutdown', handler: ShutdownHandler): () => void;
|
18
|
-
export declare function subscribeOn(scope: 'worker' | 'test' | 'webpack' | 'docker' | 'shutdown', handler: WorkerHandler | TestHandler | WebpackHandler | DockerHandler | ShutdownHandler): () => void;
|
21
|
+
export declare function subscribeOn(scope: 'worker' | 'stories' | 'test' | 'webpack' | 'docker' | 'shutdown', handler: WorkerHandler | StoriesHandler | TestHandler | WebpackHandler | DockerHandler | ShutdownHandler): () => void;
|
22
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'worker', handler: WorkerHandler): () => void;
|
23
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'stories', handler: StoriesHandler): () => void;
|
24
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'test', handler: TestHandler): () => void;
|
25
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'webpack', handler: WebpackHandler): () => void;
|
26
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'docker', handler: DockerHandler): () => void;
|
27
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'shutdown', handler: ShutdownHandler): () => void;
|
28
|
+
export declare function subscribeOnWorker(worker: cluster.Worker, scope: 'worker' | 'stories' | 'test' | 'webpack' | 'docker' | 'shutdown', handler: WorkerHandler | StoriesHandler | TestHandler | WebpackHandler | DockerHandler | ShutdownHandler): () => void;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { CreeveyStoryParams, CreeveyTestFunction } from '../types';
|
2
|
+
export declare type CreeveyParamsByStoryId = {
|
3
|
+
[storyId: string]: CreeveyStoryParams;
|
4
|
+
};
|
5
|
+
export default function parse(files: string[]): Promise<CreeveyParamsByStoryId>;
|
6
|
+
declare const setStoryParameters: (params: CreeveyStoryParams) => void;
|
7
|
+
export declare const kind: (title: string, kindFn: () => void) => void;
|
8
|
+
export declare const story: (title: string, storyFn: (arg: {
|
9
|
+
setStoryParameters: (params: CreeveyStoryParams) => void;
|
10
|
+
}) => void) => void;
|
11
|
+
export declare const test: (title: string, testFn: CreeveyTestFunction) => void;
|
12
|
+
export {};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Context } from 'mocha';
|
2
2
|
import { WebDriver } from 'selenium-webdriver';
|
3
|
-
import {
|
3
|
+
import { Config, StorybookGlobals, StoriesRaw } from '../../types';
|
4
4
|
declare global {
|
5
5
|
interface Window {
|
6
6
|
__CREEVEY_RESTORE_SCROLL__?: () => void;
|
@@ -9,6 +9,9 @@ declare global {
|
|
9
9
|
__CREEVEY_REMOVE_IGNORE_STYLES__: (ignoreStyles: HTMLStyleElement) => void;
|
10
10
|
}
|
11
11
|
}
|
12
|
+
export declare function takeScreenshot(browser: WebDriver, captureElement?: string | null, ignoreElements?: string | string[] | null): Promise<string>;
|
12
13
|
export declare function updateStorybookGlobals(browser: WebDriver, globals: StorybookGlobals): Promise<void>;
|
13
|
-
export declare function
|
14
|
+
export declare function loadStoriesFromBrowser(port: number): Promise<StoriesRaw>;
|
15
|
+
export declare function getBrowser(config: Config, name: string): Promise<WebDriver | null>;
|
16
|
+
export declare function closeBrowser(): Promise<void>;
|
14
17
|
export declare function switchStory(this: Context): Promise<void>;
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import type { StoriesRaw, ServerTest, StoryInput, SetStoriesData } from '../types';
|
2
|
-
export declare function
|
3
|
-
export declare function loadTestsFromStories(browsers: string[], provider: (storiesListener: (stories: Map<string, StoryInput[]>) => void) => Promise<SetStoriesData>, update?: (testsDiff: Partial<{
|
2
|
+
export declare function loadTestsFromStories(browsers: string[], provider: (storiesListener: (stories: Map<string, StoryInput[]>) => void) => Promise<StoriesRaw>, update?: (testsDiff: Partial<{
|
4
3
|
[id: string]: ServerTest;
|
5
4
|
}>) => void): Promise<Partial<{
|
6
5
|
[id: string]: ServerTest;
|
@@ -1,14 +1,18 @@
|
|
1
1
|
/// <reference types="node" />
|
2
2
|
/// <reference types="webpack-env" />
|
3
3
|
import type { StoryApi } from '@storybook/addons';
|
4
|
-
|
5
|
-
|
6
|
-
export declare const
|
4
|
+
import type { Channel } from '@storybook/channels';
|
5
|
+
declare const start: typeof import("@storybook/core").start;
|
6
|
+
export declare const channel: Channel;
|
7
|
+
declare type ClientApi = ReturnType<typeof start>['clientApi'];
|
8
|
+
export declare const clientApi: ClientApi;
|
9
|
+
export declare const forceReRender: (() => never) | (() => void);
|
7
10
|
export declare const storiesOf: (kind: string, m: NodeModule) => StoryApi;
|
8
11
|
export declare const configure: (...args: unknown[]) => unknown;
|
9
|
-
export declare const addDecorator:
|
10
|
-
export declare const addParameters:
|
11
|
-
export declare const clearDecorators:
|
12
|
-
export declare const setAddon: (addon: any) => void;
|
13
|
-
export declare const getStorybook:
|
14
|
-
export declare const raw:
|
12
|
+
export declare const addDecorator: ClientApi['addDecorator'];
|
13
|
+
export declare const addParameters: ClientApi['addParameters'];
|
14
|
+
export declare const clearDecorators: ClientApi['clearDecorators'];
|
15
|
+
export declare const setAddon: (() => never) | ((addon: any) => void);
|
16
|
+
export declare const getStorybook: ClientApi['getStorybook'];
|
17
|
+
export declare const raw: ClientApi['raw'];
|
18
|
+
export {};
|
@@ -14,6 +14,7 @@ export declare function hasDocsAddon(): boolean;
|
|
14
14
|
export declare function hasSvelteCSFAddon(): boolean;
|
15
15
|
export declare function getStorybookVersion(): string;
|
16
16
|
export declare function isStorybookVersionLessThan(major: number, minor?: number): boolean;
|
17
|
+
export declare function isStorybookVersionGreaterThan(major: number, minor?: number): boolean;
|
17
18
|
export declare function isStorybookVersion(major: number, minor?: number): boolean;
|
18
19
|
export declare function getStorybookFramework(): string;
|
19
20
|
export declare const storybookConfigRef: {
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import type { StoryInput, SetStoriesData, Config, StoriesRaw } from '../../../types';
|
2
|
+
export declare function loadStories(config: Config, { watch, debug }: {
|
3
|
+
watch: boolean;
|
4
|
+
debug: boolean;
|
5
|
+
}, storiesListener: (stories: Map<string, StoryInput[]>) => void): Promise<StoriesRaw>;
|
6
|
+
export declare function extractStoriesData(config: Config, { watch, debug }: {
|
7
|
+
watch: boolean;
|
8
|
+
debug: boolean;
|
9
|
+
}): Promise<SetStoriesData>;
|
@@ -4,6 +4,7 @@ export declare const isShuttingDown: {
|
|
4
4
|
};
|
5
5
|
export declare const LOCALHOST_REGEXP: RegExp;
|
6
6
|
export declare const extensions: string[];
|
7
|
+
export declare const skipOptionKeys: string[];
|
7
8
|
export declare function shouldSkip(browser: string, meta: {
|
8
9
|
kind: string;
|
9
10
|
story: string;
|
@@ -16,3 +17,4 @@ export declare function testsToImages(tests: (TestData | undefined)[]): Set<stri
|
|
16
17
|
export declare const isInsideDocker: boolean;
|
17
18
|
export declare const downloadBinary: (downloadUrl: string, destination: string) => Promise<void>;
|
18
19
|
export declare function removeProps(obj: Record<string, unknown>, propPath: (string | ((key: string) => boolean))[]): void;
|
20
|
+
export declare function readDirRecursive(dirPath: string): string[];
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import { Suite } from 'mocha';
|
2
2
|
import { Config } from '../../types';
|
3
|
-
export declare function addTestsFromStories(rootSuite: Suite, config: Config, { browser,
|
3
|
+
export declare function addTestsFromStories(rootSuite: Suite, config: Config, { browser, ...options }: {
|
4
4
|
browser: string;
|
5
5
|
watch: boolean;
|
6
6
|
debug: boolean;
|
7
|
+
port: number;
|
7
8
|
}): Promise<void>;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Parameters } from '@storybook/api';
|
2
|
+
import { SetStoriesData, StoriesRaw, StoryInput } from './types';
|
3
|
+
export declare const combineParameters: (...parameterSets: Parameters[]) => Parameters;
|
4
|
+
export declare const denormalizeStoryParameters: ({ globalParameters, kindParameters, stories, }: SetStoriesData) => StoriesRaw;
|
5
|
+
interface SerializedRegExp {
|
6
|
+
__regexp: true;
|
7
|
+
source: string;
|
8
|
+
flags: string;
|
9
|
+
}
|
10
|
+
export declare const isSerializedRegExp: (exp: unknown) => exp is SerializedRegExp;
|
11
|
+
export declare const serializeRegExp: (exp: RegExp) => SerializedRegExp;
|
12
|
+
export declare const deserializeRegExp: ({ source, flags }: SerializedRegExp) => RegExp;
|
13
|
+
export declare const serializeRawStories: (stories: StoriesRaw) => StoriesRaw;
|
14
|
+
export declare const deserializeRawStories: (stories: StoriesRaw) => StoriesRaw;
|
15
|
+
export declare const deserializeStory: (story: StoryInput) => StoryInput;
|
16
|
+
export {};
|