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
@@ -5,7 +5,7 @@ import { addHook } from 'pirates';
|
|
5
5
|
import { isDefined } from '../../../types';
|
6
6
|
import { extensions } from '../../utils';
|
7
7
|
import plugin from './creevey-plugin';
|
8
|
-
import { hasDocsAddon, hasSvelteCSFAddon } from '../../storybook/helpers';
|
8
|
+
import { hasDocsAddon, hasSvelteCSFAddon, isStorybookVersionLessThan } from '../../storybook/helpers';
|
9
9
|
let parents = null;
|
10
10
|
let story = null; //@ts-expect-error private field doesn't have types
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
@@ -69,7 +69,8 @@ function getRequireContext(rootDir) {
|
|
69
69
|
}
|
70
70
|
|
71
71
|
export default async function register(config, debug = false) {
|
72
|
-
const
|
72
|
+
const rootDir = isStorybookVersionLessThan(6, 4) ? config.storybookDir : process.cwd();
|
73
|
+
const requireContext = getRequireContext(rootDir);
|
73
74
|
const preview = resolve(config.storybookDir, 'preview');
|
74
75
|
if (hasDocsAddon()) await (await import('../hooks/mdx')).addMDXHook(() => story);
|
75
76
|
if (hasSvelteCSFAddon()) await (await import('../hooks/svelte')).addSvelteHook(() => story); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import path from 'path';
|
2
|
-
import { writeFileSync, copyFile, readdir, mkdir,
|
2
|
+
import { writeFileSync, copyFile, readdir, mkdir, existsSync } from 'fs';
|
3
3
|
import { promisify } from 'util';
|
4
4
|
import master from './master';
|
5
5
|
import creeveyApi from './api';
|
6
6
|
import { isDefined } from '../../types';
|
7
|
-
import { shutdown, shutdownWorkers, testsToImages } from '../utils';
|
7
|
+
import { shutdown, shutdownWorkers, testsToImages, readDirRecursive } from '../utils';
|
8
8
|
import { subscribeOn } from '../messages';
|
9
9
|
import { logger } from '../logger';
|
10
10
|
const copyFileAsync = promisify(copyFile);
|
@@ -37,12 +37,6 @@ function reportDataModule(data) {
|
|
37
37
|
`;
|
38
38
|
}
|
39
39
|
|
40
|
-
function readDirRecursive(dirPath) {
|
41
|
-
return [].concat(...readdirSync(dirPath, {
|
42
|
-
withFileTypes: true
|
43
|
-
}).map(dirent => dirent.isDirectory() ? readDirRecursive(`${dirPath}/${dirent.name}`) : [`${dirPath}/${dirent.name}`]));
|
44
|
-
}
|
45
|
-
|
46
40
|
function outputUnnecessaryImages(imagesDir, images) {
|
47
41
|
if (!existsSync(imagesDir)) return;
|
48
42
|
const unnecessaryImages = readDirRecursive(imagesDir).map(imagePath => path.posix.relative(imagesDir, imagePath)).filter(imagePath => !images.has(imagePath));
|
@@ -86,9 +80,9 @@ export default async function (config, options, resolveApi) {
|
|
86
80
|
});
|
87
81
|
runner = await master(config, {
|
88
82
|
watch: options.ui,
|
89
|
-
debug: options.debug
|
83
|
+
debug: options.debug,
|
84
|
+
port: options.port
|
90
85
|
});
|
91
|
-
await runner.init();
|
92
86
|
|
93
87
|
if (options.saveReport) {
|
94
88
|
await copyStatics(config.reportDir);
|
@@ -27,6 +27,7 @@ export default async function master(config, options) {
|
|
27
27
|
} catch (error) {// Ignore error
|
28
28
|
}
|
29
29
|
|
30
|
+
await runner.init();
|
30
31
|
const tests = await loadTestsFromStories(Object.keys(config.browsers), listener => config.storiesProvider(config, options, listener), testsDiff => {
|
31
32
|
runner.updateTests(testsDiff);
|
32
33
|
saveTestsJson(runner.tests, config.reportDir);
|
@@ -2,8 +2,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
2
2
|
|
3
3
|
import cluster from 'cluster';
|
4
4
|
import { EventEmitter } from 'events';
|
5
|
-
import { isWorkerMessage
|
6
|
-
import { sendTestMessage, sendShutdownMessage } from '../messages';
|
5
|
+
import { isWorkerMessage } from '../../types';
|
6
|
+
import { sendTestMessage, sendShutdownMessage, subscribeOnWorker } from '../messages';
|
7
7
|
import { isShuttingDown } from '../utils';
|
8
8
|
const FORK_RETRIES = 5;
|
9
9
|
export default class Pool extends EventEmitter {
|
@@ -151,37 +151,37 @@ export default class Pool extends EventEmitter {
|
|
151
151
|
return test.retries < this.maxRetries && !this.forcedStop;
|
152
152
|
}
|
153
153
|
|
154
|
+
handleTestResult(worker, test, result) {
|
155
|
+
const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
|
156
|
+
|
157
|
+
if (shouldRetry) {
|
158
|
+
test.retries += 1;
|
159
|
+
this.queue[this.failFast ? 'unshift' : 'push'](test);
|
160
|
+
}
|
161
|
+
|
162
|
+
this.sendStatus({
|
163
|
+
id: test.id,
|
164
|
+
status: shouldRetry ? 'retrying' : result.status,
|
165
|
+
result
|
166
|
+
});
|
167
|
+
worker.isRunning = false;
|
168
|
+
setImmediate(() => this.process());
|
169
|
+
}
|
170
|
+
|
154
171
|
subscribe(worker, test) {
|
155
|
-
worker
|
156
|
-
if (
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
result = {
|
163
|
-
status: 'failed',
|
164
|
-
...message.payload
|
165
|
-
};
|
166
|
-
} else {
|
167
|
-
result = message.payload;
|
168
|
-
}
|
169
|
-
|
170
|
-
const shouldRetry = result.status == 'failed' && this.shouldRetry(test);
|
171
|
-
|
172
|
-
if (shouldRetry) {
|
173
|
-
test.retries += 1;
|
174
|
-
this.queue[this.failFast ? 'unshift' : 'push'](test);
|
175
|
-
}
|
176
|
-
|
177
|
-
this.sendStatus({
|
178
|
-
id: test.id,
|
179
|
-
status: shouldRetry ? 'retrying' : result.status,
|
180
|
-
result
|
172
|
+
const subscriptions = [subscribeOnWorker(worker, 'worker', message => {
|
173
|
+
if (message.type != 'error') return;
|
174
|
+
subscriptions.forEach(unsubscribe => unsubscribe());
|
175
|
+
this.gracefullyKill(worker);
|
176
|
+
this.handleTestResult(worker, test, {
|
177
|
+
status: 'failed',
|
178
|
+
...message.payload
|
181
179
|
});
|
182
|
-
|
183
|
-
|
184
|
-
|
180
|
+
}), subscribeOnWorker(worker, 'test', message => {
|
181
|
+
if (message.type != 'end') return;
|
182
|
+
subscriptions.forEach(unsubscribe => unsubscribe());
|
183
|
+
this.handleTestResult(worker, test, message.payload);
|
184
|
+
})];
|
185
185
|
}
|
186
186
|
|
187
187
|
}
|
@@ -1,22 +1,90 @@
|
|
1
1
|
import path from 'path';
|
2
2
|
import http from 'http';
|
3
|
+
import cluster from 'cluster';
|
3
4
|
import Koa from 'koa';
|
5
|
+
import cors from '@koa/cors';
|
4
6
|
import serve from 'koa-static';
|
5
7
|
import mount from 'koa-mount';
|
8
|
+
import body from 'koa-bodyparser';
|
6
9
|
import WebSocket from 'ws';
|
7
|
-
import { subscribeOn } from '../messages';
|
8
|
-
import { noop } from '../../types';
|
10
|
+
import { emitStoriesMessage, sendStoriesMessage, subscribeOn, subscribeOnWorker } from '../messages';
|
11
|
+
import { isDefined, noop } from '../../types';
|
9
12
|
import { logger } from '../logger';
|
10
|
-
|
13
|
+
import { deserializeStory } from '../../shared';
|
14
|
+
export default function server(reportDir, port, ui) {
|
11
15
|
let resolveApi = noop;
|
16
|
+
let setStoriesCounter = 0;
|
12
17
|
const creeveyApi = new Promise(resolve => resolveApi = resolve);
|
13
18
|
const app = new Koa();
|
14
19
|
const server = http.createServer(app.callback());
|
15
20
|
const wss = new WebSocket.Server({
|
16
21
|
server
|
17
22
|
});
|
18
|
-
app.use(
|
19
|
-
|
23
|
+
app.use(cors());
|
24
|
+
app.use(body());
|
25
|
+
app.use(async (ctx, next) => {
|
26
|
+
if (ctx.method == 'GET' && ctx.path == '/ping') {
|
27
|
+
ctx.body = 'pong';
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
|
31
|
+
await next();
|
32
|
+
});
|
33
|
+
|
34
|
+
if (ui) {
|
35
|
+
app.use(async (_, next) => {
|
36
|
+
await creeveyApi;
|
37
|
+
await next();
|
38
|
+
});
|
39
|
+
}
|
40
|
+
|
41
|
+
app.use(async (ctx, next) => {
|
42
|
+
if (ctx.method == 'POST' && ctx.path == '/stories') {
|
43
|
+
const {
|
44
|
+
setStoriesCounter: counter,
|
45
|
+
stories
|
46
|
+
} = ctx.request.body;
|
47
|
+
if (setStoriesCounter >= counter) return;
|
48
|
+
const deserializedStories = stories.map(([file, stories]) => [file, stories.map(deserializeStory)]);
|
49
|
+
setStoriesCounter = counter;
|
50
|
+
emitStoriesMessage({
|
51
|
+
type: 'update',
|
52
|
+
payload: deserializedStories
|
53
|
+
});
|
54
|
+
Object.values(cluster.workers).filter(isDefined).filter(worker => worker.isConnected()).forEach(worker => sendStoriesMessage(worker, {
|
55
|
+
type: 'update',
|
56
|
+
payload: deserializedStories
|
57
|
+
}));
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
|
61
|
+
await next();
|
62
|
+
});
|
63
|
+
app.use(async (ctx, next) => {
|
64
|
+
if (ctx.method == 'POST' && ctx.path == '/capture') {
|
65
|
+
const {
|
66
|
+
workerId,
|
67
|
+
options
|
68
|
+
} = ctx.request.body;
|
69
|
+
const worker = Object.values(cluster.workers).filter(isDefined).find(worker => worker.process.pid == workerId); // NOTE: Hypothetical case when someone send to us capture req and we don't have a worker with browser session for it
|
70
|
+
|
71
|
+
if (!worker) return;
|
72
|
+
await new Promise(resolve => {
|
73
|
+
const unsubscribe = subscribeOnWorker(worker, 'stories', message => {
|
74
|
+
if (message.type != 'capture') return;
|
75
|
+
unsubscribe();
|
76
|
+
resolve();
|
77
|
+
});
|
78
|
+
sendStoriesMessage(worker, {
|
79
|
+
type: 'capture',
|
80
|
+
payload: options
|
81
|
+
});
|
82
|
+
}); // TODO Pass screenshot result to show it in inspector
|
83
|
+
|
84
|
+
ctx.body = 'Ok';
|
85
|
+
return;
|
86
|
+
}
|
87
|
+
|
20
88
|
await next();
|
21
89
|
});
|
22
90
|
app.use(serve(path.join(__dirname, '../../client/web')));
|
@@ -14,6 +14,12 @@ export function emitWorkerMessage(message) {
|
|
14
14
|
...message
|
15
15
|
});
|
16
16
|
}
|
17
|
+
export function emitStoriesMessage(message) {
|
18
|
+
return emitMessage({
|
19
|
+
scope: 'stories',
|
20
|
+
...message
|
21
|
+
});
|
22
|
+
}
|
17
23
|
export function emitTestMessage(message) {
|
18
24
|
return emitMessage({
|
19
25
|
scope: 'test',
|
@@ -37,19 +43,28 @@ export function emitShutdownMessage() {
|
|
37
43
|
scope: 'shutdown'
|
38
44
|
});
|
39
45
|
}
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
|
47
|
+
function createHandlers() {
|
48
|
+
return Object.assign(Object.create(null), {
|
49
|
+
worker: new Set(),
|
50
|
+
stories: new Set(),
|
51
|
+
test: new Set(),
|
52
|
+
webpack: new Set(),
|
53
|
+
docker: new Set(),
|
54
|
+
shutdown: new Set()
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
const handlers = createHandlers();
|
47
59
|
|
48
60
|
const handler = message => {
|
49
61
|
switch (message.scope) {
|
50
62
|
case 'worker':
|
51
63
|
return handlers.worker.forEach(h => h(message));
|
52
64
|
|
65
|
+
case 'stories':
|
66
|
+
return handlers.stories.forEach(h => h(message));
|
67
|
+
|
53
68
|
case 'test':
|
54
69
|
return handlers.test.forEach(h => h(message));
|
55
70
|
|
@@ -65,26 +80,34 @@ const handler = message => {
|
|
65
80
|
};
|
66
81
|
|
67
82
|
process.on('message', handler);
|
68
|
-
export function
|
83
|
+
export function sendStoriesMessage(target, message) {
|
69
84
|
var _target$send;
|
70
85
|
|
71
86
|
(_target$send = target.send) === null || _target$send === void 0 ? void 0 : _target$send.call(target, {
|
72
|
-
scope: '
|
87
|
+
scope: 'stories',
|
73
88
|
...message
|
74
89
|
});
|
75
90
|
}
|
76
|
-
export function
|
91
|
+
export function sendTestMessage(target, message) {
|
77
92
|
var _target$send2;
|
78
93
|
|
79
94
|
(_target$send2 = target.send) === null || _target$send2 === void 0 ? void 0 : _target$send2.call(target, {
|
80
|
-
scope: '
|
95
|
+
scope: 'test',
|
81
96
|
...message
|
82
97
|
});
|
83
98
|
}
|
84
|
-
export function
|
99
|
+
export function sendDockerMessage(target, message) {
|
85
100
|
var _target$send3;
|
86
101
|
|
87
102
|
(_target$send3 = target.send) === null || _target$send3 === void 0 ? void 0 : _target$send3.call(target, {
|
103
|
+
scope: 'docker',
|
104
|
+
...message
|
105
|
+
});
|
106
|
+
}
|
107
|
+
export function sendShutdownMessage(target) {
|
108
|
+
var _target$send4;
|
109
|
+
|
110
|
+
(_target$send4 = target.send) === null || _target$send4 === void 0 ? void 0 : _target$send4.call(target, {
|
88
111
|
scope: 'shutdown'
|
89
112
|
});
|
90
113
|
}
|
@@ -97,6 +120,13 @@ export function subscribeOn(scope, handler) {
|
|
97
120
|
return () => handlers.worker.delete(workerHandler);
|
98
121
|
}
|
99
122
|
|
123
|
+
case 'stories':
|
124
|
+
{
|
125
|
+
const storiesHandler = handler;
|
126
|
+
handlers.stories.add(storiesHandler);
|
127
|
+
return () => handlers.stories.delete(storiesHandler);
|
128
|
+
}
|
129
|
+
|
100
130
|
case 'test':
|
101
131
|
{
|
102
132
|
const testHandler = handler;
|
@@ -125,4 +155,80 @@ export function subscribeOn(scope, handler) {
|
|
125
155
|
return () => handlers.shutdown.delete(shutdownHandler);
|
126
156
|
}
|
127
157
|
}
|
158
|
+
}
|
159
|
+
const workers = new Map();
|
160
|
+
export function subscribeOnWorker(worker, scope, handler) {
|
161
|
+
var _workers$get;
|
162
|
+
|
163
|
+
const workerHandlers = (_workers$get = workers.get(worker)) !== null && _workers$get !== void 0 ? _workers$get : createHandlers();
|
164
|
+
|
165
|
+
if (!workers.has(worker)) {
|
166
|
+
workers.set(worker, workerHandlers);
|
167
|
+
worker.once('exit', () => workers.delete(worker));
|
168
|
+
worker.on('message', message => {
|
169
|
+
switch (message.scope) {
|
170
|
+
case 'worker':
|
171
|
+
return workerHandlers.worker.forEach(h => h(message));
|
172
|
+
|
173
|
+
case 'stories':
|
174
|
+
return workerHandlers.stories.forEach(h => h(message));
|
175
|
+
|
176
|
+
case 'test':
|
177
|
+
return workerHandlers.test.forEach(h => h(message));
|
178
|
+
|
179
|
+
case 'webpack':
|
180
|
+
return workerHandlers.webpack.forEach(h => h(message));
|
181
|
+
|
182
|
+
case 'docker':
|
183
|
+
return workerHandlers.docker.forEach(h => h(message));
|
184
|
+
|
185
|
+
case 'shutdown':
|
186
|
+
return workerHandlers.shutdown.forEach(h => h(message));
|
187
|
+
}
|
188
|
+
});
|
189
|
+
}
|
190
|
+
|
191
|
+
switch (scope) {
|
192
|
+
case 'worker':
|
193
|
+
{
|
194
|
+
const workerHandler = handler;
|
195
|
+
workerHandlers.worker.add(workerHandler);
|
196
|
+
return () => workerHandlers.worker.delete(workerHandler);
|
197
|
+
}
|
198
|
+
|
199
|
+
case 'stories':
|
200
|
+
{
|
201
|
+
const storiesHandler = handler;
|
202
|
+
workerHandlers.stories.add(storiesHandler);
|
203
|
+
return () => workerHandlers.stories.delete(storiesHandler);
|
204
|
+
}
|
205
|
+
|
206
|
+
case 'test':
|
207
|
+
{
|
208
|
+
const testHandler = handler;
|
209
|
+
workerHandlers.test.add(testHandler);
|
210
|
+
return () => workerHandlers.test.delete(testHandler);
|
211
|
+
}
|
212
|
+
|
213
|
+
case 'webpack':
|
214
|
+
{
|
215
|
+
const webpackHandler = handler;
|
216
|
+
workerHandlers.webpack.add(webpackHandler);
|
217
|
+
return () => workerHandlers.webpack.delete(webpackHandler);
|
218
|
+
}
|
219
|
+
|
220
|
+
case 'docker':
|
221
|
+
{
|
222
|
+
const dockerHandler = handler;
|
223
|
+
workerHandlers.docker.add(dockerHandler);
|
224
|
+
return () => workerHandlers.docker.delete(dockerHandler);
|
225
|
+
}
|
226
|
+
|
227
|
+
case 'shutdown':
|
228
|
+
{
|
229
|
+
const shutdownHandler = handler;
|
230
|
+
workerHandlers.shutdown.add(shutdownHandler);
|
231
|
+
return () => workerHandlers.shutdown.delete(shutdownHandler);
|
232
|
+
}
|
233
|
+
}
|
128
234
|
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import { toId, storyNameFromExport } from '@storybook/csf';
|
2
|
+
export default async function parse(files) {
|
3
|
+
result = {}; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
4
|
+
|
5
|
+
(await import('@babel/register')).default({
|
6
|
+
babelrc: false,
|
7
|
+
rootMode: 'upward-optional',
|
8
|
+
ignore: [/node_modules/],
|
9
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
10
|
+
plugins: [['@babel/plugin-transform-runtime']],
|
11
|
+
presets: ['@babel/preset-typescript', ['@babel/preset-env', {
|
12
|
+
targets: {
|
13
|
+
node: '10'
|
14
|
+
}
|
15
|
+
}]]
|
16
|
+
});
|
17
|
+
await Promise.all(files.map(async file => import(file)));
|
18
|
+
return result;
|
19
|
+
}
|
20
|
+
let result = {};
|
21
|
+
let kindTitle = '';
|
22
|
+
let storyTitle = '';
|
23
|
+
let storyParams = null;
|
24
|
+
|
25
|
+
const setStoryParameters = params => {
|
26
|
+
storyParams = params;
|
27
|
+
};
|
28
|
+
|
29
|
+
const getStoryId = (kindTitle, storyTitle) => {
|
30
|
+
return toId(kindTitle, storyNameFromExport(storyTitle));
|
31
|
+
};
|
32
|
+
|
33
|
+
export const kind = (title, kindFn) => {
|
34
|
+
kindTitle = title;
|
35
|
+
kindFn();
|
36
|
+
kindTitle = '';
|
37
|
+
};
|
38
|
+
export const story = (title, storyFn) => {
|
39
|
+
var _result$storyId;
|
40
|
+
|
41
|
+
storyTitle = title;
|
42
|
+
storyParams = null;
|
43
|
+
storyFn({
|
44
|
+
setStoryParameters
|
45
|
+
});
|
46
|
+
const storyId = getStoryId(kindTitle, storyTitle);
|
47
|
+
result[storyId] = Object.assign({}, storyParams, {
|
48
|
+
tests: (_result$storyId = result[storyId]) === null || _result$storyId === void 0 ? void 0 : _result$storyId.tests
|
49
|
+
});
|
50
|
+
storyTitle = '';
|
51
|
+
storyParams = null;
|
52
|
+
};
|
53
|
+
export const test = (title, testFn) => {
|
54
|
+
const storyId = getStoryId(kindTitle, storyTitle);
|
55
|
+
|
56
|
+
if (!result[storyId]) {
|
57
|
+
result[storyId] = {};
|
58
|
+
}
|
59
|
+
|
60
|
+
result[storyId].tests = Object.assign({}, result[storyId].tests, {
|
61
|
+
[title]: testFn
|
62
|
+
});
|
63
|
+
};
|