creevey 0.8.0-beta.0 → 0.8.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 +30 -7
- package/README.md +9 -1
- package/addon/README.md +3 -0
- package/addon/package.json +4 -0
- package/docs/config.md +29 -26
- package/jest.config.js +6 -0
- package/lib/cjs/client/addon/Manager.js +122 -271
- package/lib/cjs/client/addon/components/Addon.js +17 -38
- package/lib/cjs/client/addon/components/Icons.js +11 -7
- package/lib/cjs/client/addon/components/Panel.js +17 -13
- package/lib/cjs/client/addon/components/TestSelect.js +11 -9
- package/lib/cjs/client/addon/components/Tools.js +21 -40
- package/lib/cjs/client/addon/decorator.js +1 -1
- package/lib/cjs/client/addon/index.js +31 -0
- package/lib/cjs/client/addon/preset.ie11.js +74 -0
- package/lib/cjs/client/addon/preset.js +13 -31
- package/lib/cjs/client/addon/readyForCapture.js +12 -0
- package/lib/cjs/client/addon/register.js +46 -70
- package/lib/cjs/client/addon/utils.js +6 -2
- package/lib/cjs/client/addon/withCreevey.js +221 -155
- package/lib/cjs/client/shared/components/ImagesView/BlendView.js +26 -24
- package/lib/cjs/client/shared/components/ImagesView/ImagesView.js +22 -18
- package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +44 -66
- package/lib/cjs/client/shared/components/ImagesView/SlideView.js +38 -50
- package/lib/cjs/client/shared/components/ImagesView/SwapView.js +26 -45
- package/lib/cjs/client/shared/components/ImagesView/index.js +9 -9
- package/lib/cjs/client/shared/components/PageFooter/PageFooter.js +12 -8
- package/lib/cjs/client/shared/components/PageFooter/Paging.js +14 -18
- package/lib/cjs/client/shared/components/PageHeader/ImagePreview.js +22 -18
- package/lib/cjs/client/shared/components/PageHeader/PageHeader.js +42 -67
- package/lib/cjs/client/shared/components/ResultsPage.js +39 -69
- package/lib/cjs/client/shared/creeveyClientApi.js +55 -82
- package/lib/cjs/client/shared/helpers.js +140 -211
- package/lib/cjs/client/shared/viewMode.js +5 -5
- package/lib/cjs/client/web/142.js +2 -0
- package/lib/cjs/client/web/142.js.LICENSE.txt +12 -0
- package/lib/cjs/client/web/32.js +1 -0
- package/lib/cjs/client/web/551.js +1 -0
- package/lib/cjs/client/web/566.js +2 -0
- package/lib/cjs/client/web/566.js.LICENSE.txt +31 -0
- package/lib/cjs/client/web/691.js +2 -0
- package/lib/cjs/client/web/691.js.LICENSE.txt +8 -0
- package/lib/cjs/client/web/725.js +1 -0
- package/lib/cjs/client/web/main.js +2 -38
- package/lib/cjs/client/web/main.js.LICENSE.txt +49 -0
- package/lib/cjs/creevey.js +3 -5
- package/lib/cjs/index.js +10 -15
- package/lib/cjs/server/config.js +5 -4
- package/lib/cjs/server/docker.js +3 -7
- package/lib/cjs/server/extract.js +7 -4
- package/lib/cjs/server/index.js +3 -5
- package/lib/cjs/server/loaders/babel/creevey-plugin.js +1 -3
- package/lib/cjs/server/loaders/babel/helpers.js +13 -23
- package/lib/cjs/server/loaders/babel/register.js +2 -4
- package/lib/cjs/server/loaders/webpack/compile.js +34 -51
- package/lib/cjs/server/loaders/webpack/creevey-loader.js +20 -22
- package/lib/cjs/server/loaders/webpack/dummy-hmr.js +2 -7
- package/lib/cjs/server/loaders/webpack/mdx-loader.js +2 -2
- package/lib/cjs/server/loaders/webpack/start.js +1 -1
- package/lib/cjs/server/logger.js +2 -1
- package/lib/cjs/server/master/index.js +4 -4
- package/lib/cjs/server/master/master.js +1 -0
- package/lib/cjs/server/master/pool.js +38 -47
- package/lib/cjs/server/master/runner.js +53 -66
- package/lib/cjs/server/master/server.js +78 -4
- package/lib/cjs/server/messages.js +128 -18
- package/lib/cjs/server/selenium/browser.js +129 -55
- package/lib/cjs/server/selenium/selenoid.js +5 -7
- package/lib/cjs/server/stories.js +58 -72
- package/lib/cjs/server/storybook/entry.js +7 -22
- package/lib/cjs/server/storybook/helpers.js +20 -27
- package/lib/cjs/server/storybook/providers/browser.js +74 -0
- package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +37 -20
- package/lib/cjs/server/update.js +1 -5
- package/lib/cjs/server/utils.js +26 -35
- package/lib/cjs/server/worker/helpers.js +2 -6
- package/lib/cjs/server/worker/reporter.js +8 -20
- package/lib/cjs/server/worker/worker.js +21 -19
- package/lib/cjs/shared/index.js +101 -0
- package/lib/cjs/shared/serializeRegExp.js +42 -0
- package/lib/cjs/types.js +11 -6
- package/lib/esm/client/addon/Manager.js +122 -271
- package/lib/esm/client/addon/components/Addon.js +15 -34
- package/lib/esm/client/addon/components/Icons.js +10 -6
- package/lib/esm/client/addon/components/Panel.js +17 -13
- package/lib/esm/client/addon/components/TestSelect.js +11 -9
- package/lib/esm/client/addon/components/Tools.js +19 -36
- package/lib/esm/client/addon/decorator.js +1 -1
- package/lib/esm/client/addon/index.js +2 -0
- package/lib/esm/client/addon/preset.ie11.js +59 -0
- package/lib/esm/client/addon/preset.js +12 -26
- package/lib/esm/client/addon/readyForCapture.js +5 -0
- package/lib/esm/client/addon/register.js +42 -66
- package/lib/esm/client/addon/utils.js +3 -2
- package/lib/esm/client/addon/withCreevey.js +209 -156
- package/lib/esm/client/shared/components/ImagesView/BlendView.js +23 -20
- package/lib/esm/client/shared/components/ImagesView/ImagesView.js +21 -17
- package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +42 -63
- package/lib/esm/client/shared/components/ImagesView/SlideView.js +36 -47
- package/lib/esm/client/shared/components/ImagesView/SwapView.js +24 -42
- package/lib/esm/client/shared/components/PageFooter/PageFooter.js +12 -8
- package/lib/esm/client/shared/components/PageFooter/Paging.js +14 -18
- package/lib/esm/client/shared/components/PageHeader/ImagePreview.js +22 -18
- package/lib/esm/client/shared/components/PageHeader/PageHeader.js +37 -60
- package/lib/esm/client/shared/components/ResultsPage.js +36 -64
- package/lib/esm/client/shared/creeveyClientApi.js +57 -84
- package/lib/esm/client/shared/helpers.js +124 -195
- package/lib/esm/client/shared/viewMode.js +4 -4
- package/lib/esm/creevey.js +3 -5
- package/lib/esm/index.js +2 -3
- package/lib/esm/server/config.js +4 -5
- package/lib/esm/server/docker.js +2 -2
- package/lib/esm/server/extract.js +6 -4
- package/lib/esm/server/index.js +3 -4
- package/lib/esm/server/loaders/babel/creevey-plugin.js +1 -3
- package/lib/esm/server/loaders/babel/helpers.js +12 -22
- package/lib/esm/server/loaders/babel/register.js +3 -5
- package/lib/esm/server/loaders/webpack/compile.js +35 -52
- package/lib/esm/server/loaders/webpack/creevey-loader.js +9 -10
- package/lib/esm/server/loaders/webpack/dummy-hmr.js +2 -6
- package/lib/esm/server/loaders/webpack/mdx-loader.js +2 -2
- package/lib/esm/server/loaders/webpack/start.js +1 -1
- package/lib/esm/server/master/index.js +4 -4
- package/lib/esm/server/master/master.js +1 -0
- package/lib/esm/server/master/pool.js +38 -49
- package/lib/esm/server/master/runner.js +53 -66
- package/lib/esm/server/master/server.js +76 -6
- package/lib/esm/server/messages.js +118 -14
- package/lib/esm/server/selenium/browser.js +126 -57
- package/lib/esm/server/selenium/selenoid.js +4 -6
- package/lib/esm/server/stories.js +58 -70
- package/lib/esm/server/storybook/entry.js +5 -22
- package/lib/esm/server/storybook/helpers.js +11 -20
- package/lib/esm/server/storybook/providers/browser.js +60 -0
- package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +35 -19
- package/lib/esm/server/update.js +1 -5
- package/lib/esm/server/utils.js +18 -31
- package/lib/esm/server/worker/helpers.js +2 -6
- package/lib/esm/server/worker/reporter.js +8 -20
- package/lib/esm/server/worker/worker.js +22 -20
- package/lib/esm/shared/index.js +78 -0
- package/lib/esm/shared/serializeRegExp.js +24 -0
- package/lib/esm/types.js +3 -0
- package/lib/types/client/addon/Manager.d.ts +2 -2
- package/lib/types/client/addon/components/TestSelect.d.ts +0 -1
- package/lib/types/client/addon/index.d.ts +2 -0
- package/lib/types/client/addon/preset.d.ts +2 -1
- package/lib/types/client/addon/preset.ie11.d.ts +10 -0
- package/lib/types/client/addon/readyForCapture.d.ts +6 -0
- package/lib/types/client/addon/utils.d.ts +1 -0
- package/lib/types/client/addon/withCreevey.d.ts +13 -2
- package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +1 -1
- package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +0 -1
- package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +1 -1
- package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +1 -1
- package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +1 -1
- package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +0 -1
- package/lib/types/client/shared/components/PageFooter/Paging.d.ts +0 -1
- package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +1 -1
- package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +0 -1
- package/lib/types/client/shared/components/ResultsPage.d.ts +1 -1
- package/lib/types/client/web/CreeveyApp.d.ts +0 -1
- package/lib/types/client/web/CreeveyLoader.d.ts +1 -2
- package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +1 -1
- package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +0 -1
- package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +6 -6
- package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +0 -1
- package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +1 -1
- package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +1 -1
- package/lib/types/index.d.ts +0 -1
- package/lib/types/server/loaders/babel/register.d.ts +1 -1
- package/lib/types/server/loaders/webpack/creevey-loader.d.ts +4 -2
- package/lib/types/server/logger.d.ts +6 -2
- 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 +17 -6
- package/lib/types/server/selenium/browser.d.ts +5 -2
- package/lib/types/server/stories.d.ts +2 -2
- package/lib/types/server/storybook/entry.d.ts +2 -3
- package/lib/types/server/storybook/helpers.d.ts +1 -1
- package/lib/types/server/storybook/providers/browser.d.ts +4 -0
- package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
- package/lib/types/server/utils.d.ts +5 -1
- package/lib/types/server/worker/helpers.d.ts +2 -1
- package/lib/types/shared/index.d.ts +7 -0
- package/lib/types/shared/serializeRegExp.d.ts +9 -0
- package/lib/types/types.d.ts +32 -5
- package/package.json +120 -103
- package/preset/ie11.js +5 -0
- package/{preset.js → preset/index.js} +2 -2
- package/types/mdx.d.ts +3 -2
- package/types/mocha.d.ts +1 -0
- package/lib/cjs/client/web/1.js +0 -13
- package/lib/cjs/client/web/2.js +0 -1
- package/lib/cjs/shared.js +0 -35
- package/lib/esm/shared.js +0 -22
- package/lib/types/server/storybook/nodejs-provider.d.ts +0 -5
- package/lib/types/shared.d.ts +0 -4
@@ -1,67 +1,45 @@
|
|
1
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
2
|
-
|
3
|
-
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
4
|
-
|
5
|
-
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
6
|
-
|
7
1
|
import * as Events from '@storybook/core-events';
|
8
2
|
import * as polyfill from 'event-source-polyfill';
|
3
|
+
import { buildQueries, within } from '@storybook/testing-library';
|
9
4
|
import { addons, makeDecorator } from '@storybook/addons';
|
10
5
|
import { isObject, noop } from '../../types';
|
6
|
+
import { denormalizeStoryParameters, serializeRawStories } from '../../shared';
|
7
|
+
import { getConnectionUrl } from '../shared/helpers';
|
8
|
+
import { isInternetExplorer } from './utils';
|
11
9
|
|
12
|
-
if (
|
10
|
+
if (typeof process != 'object' || typeof process.version != 'string') {
|
13
11
|
// NOTE If you don't use babel-polyfill or any other polyfills that add EventSource for IE11
|
14
12
|
// You don't get hot reload in IE11. So put polyfill for that to better UX
|
15
13
|
// Don't load in nodejs environment
|
16
14
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
17
|
-
|
18
|
-
|
15
|
+
const {
|
16
|
+
NativeEventSource,
|
17
|
+
EventSourcePolyfill
|
18
|
+
} = polyfill; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
19
19
|
|
20
20
|
window.EventSource = NativeEventSource || EventSourcePolyfill;
|
21
21
|
}
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
function resetCurrentStory(_x) {
|
26
|
-
return _resetCurrentStory.apply(this, arguments);
|
27
|
-
}
|
23
|
+
const disableAnimationsStyles = "\n*,\n*:hover,\n*::before,\n*::after {\n animation-delay: -0.0001ms !important;\n animation-duration: 0s !important;\n animation-play-state: paused !important;\n cursor: none !important;\n caret-color: transparent !important;\n transition: 0s !important;\n}\n";
|
28
24
|
|
29
|
-
function
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
return channel.emit(Events.SET_CURRENT_STORY, {
|
37
|
-
storyId: true,
|
38
|
-
name: '',
|
39
|
-
kind: ''
|
40
|
-
});
|
41
|
-
}, 0);
|
42
|
-
return _context3.abrupt("return", new Promise(function (resolve) {
|
43
|
-
return channel.once(Events.STORY_MISSING, resolve);
|
44
|
-
}));
|
45
|
-
|
46
|
-
case 2:
|
47
|
-
case "end":
|
48
|
-
return _context3.stop();
|
49
|
-
}
|
50
|
-
}
|
51
|
-
}, _callee3);
|
52
|
-
}));
|
53
|
-
return _resetCurrentStory.apply(this, arguments);
|
25
|
+
async function resetCurrentStory(channel) {
|
26
|
+
setTimeout(() => channel.emit(Events.SET_CURRENT_STORY, {
|
27
|
+
storyId: true,
|
28
|
+
name: '',
|
29
|
+
kind: ''
|
30
|
+
}), 0);
|
31
|
+
return new Promise(resolve => channel.once(Events.STORY_MISSING, resolve));
|
54
32
|
}
|
55
33
|
|
56
34
|
function catchRenderError(channel) {
|
57
|
-
|
58
|
-
|
59
|
-
return rejectCallback = reject;
|
60
|
-
});
|
35
|
+
let rejectCallback;
|
36
|
+
const promise = new Promise((_resolve, reject) => rejectCallback = reject);
|
61
37
|
|
62
38
|
function errorHandler(_ref) {
|
63
|
-
|
64
|
-
|
39
|
+
let {
|
40
|
+
title,
|
41
|
+
description
|
42
|
+
} = _ref;
|
65
43
|
rejectCallback({
|
66
44
|
message: title,
|
67
45
|
stack: description
|
@@ -85,10 +63,8 @@ function catchRenderError(channel) {
|
|
85
63
|
}
|
86
64
|
|
87
65
|
function waitForStoryRendered(channel) {
|
88
|
-
|
89
|
-
|
90
|
-
return resolveCallback = resolve;
|
91
|
-
});
|
66
|
+
let resolveCallback;
|
67
|
+
const promise = new Promise(resolve => resolveCallback = resolve);
|
92
68
|
|
93
69
|
function renderHandler() {
|
94
70
|
resolveCallback();
|
@@ -106,13 +82,11 @@ function waitForStoryRendered(channel) {
|
|
106
82
|
|
107
83
|
function waitForFontsLoaded() {
|
108
84
|
if (!document.fonts) return;
|
109
|
-
|
110
|
-
return font.status == 'loading';
|
111
|
-
});
|
85
|
+
const areFontsLoading = Array.from(document.fonts).some(font => font.status == 'loading');
|
112
86
|
|
113
87
|
if (areFontsLoading) {
|
114
|
-
return new Promise(
|
115
|
-
|
88
|
+
return new Promise(resolve => {
|
89
|
+
const fontsLoadedHandler = () => {
|
116
90
|
document.fonts.removeEventListener('loadingdone', fontsLoadedHandler);
|
117
91
|
resolve();
|
118
92
|
};
|
@@ -122,128 +96,129 @@ function waitForFontsLoaded() {
|
|
122
96
|
}
|
123
97
|
}
|
124
98
|
|
99
|
+
function waitForCaptureCall() {
|
100
|
+
return new Promise(resolve => captureResolver = resolve);
|
101
|
+
}
|
102
|
+
|
103
|
+
function initCreeveyState() {
|
104
|
+
var _window$localStorage$;
|
105
|
+
|
106
|
+
const prevState = JSON.parse((_window$localStorage$ = window.localStorage.getItem('Creevey_Tests')) !== null && _window$localStorage$ !== void 0 ? _window$localStorage$ : '{}');
|
107
|
+
if (prevState.creeveyHost) window.__CREEVEY_SERVER_HOST__ = prevState.creeveyHost;
|
108
|
+
if (prevState.creeveyPort) window.__CREEVEY_SERVER_PORT__ = prevState.creeveyPort;
|
109
|
+
if (prevState.setStoriesCounter) setStoriesCounter = prevState.setStoriesCounter;
|
110
|
+
if (prevState.isTestBrowser) isTestBrowser = prevState.isTestBrowser;
|
111
|
+
window.addEventListener('beforeunload', () => {
|
112
|
+
window.localStorage.setItem('Creevey_Tests', JSON.stringify({
|
113
|
+
creeveyHost: window.__CREEVEY_SERVER_HOST__,
|
114
|
+
creeveyPort: window.__CREEVEY_SERVER_PORT__,
|
115
|
+
setStoriesCounter,
|
116
|
+
isTestBrowser
|
117
|
+
}));
|
118
|
+
});
|
119
|
+
}
|
120
|
+
|
121
|
+
let isTestBrowser = false;
|
122
|
+
let captureResolver;
|
123
|
+
let waitForCreevey;
|
124
|
+
let creeveyReady;
|
125
|
+
let setStoriesCounter = 0;
|
125
126
|
export function withCreevey() {
|
126
|
-
|
127
|
-
|
127
|
+
let currentStory = '';
|
128
|
+
let isAnimationDisabled = false;
|
129
|
+
initCreeveyState();
|
128
130
|
|
129
131
|
function disableAnimation() {
|
130
132
|
isAnimationDisabled = true;
|
131
|
-
|
132
|
-
|
133
|
+
const style = document.createElement('style');
|
134
|
+
const textNode = document.createTextNode(disableAnimationsStyles);
|
133
135
|
style.setAttribute('type', 'text/css');
|
134
136
|
style.appendChild(textNode);
|
135
137
|
document.head.appendChild(style);
|
136
138
|
}
|
137
139
|
|
138
|
-
function
|
139
|
-
|
140
|
+
async function getStories() {
|
141
|
+
var _window$__STORYBOOK_S;
|
142
|
+
|
143
|
+
const storiesPromise = new Promise(resolve => addons.getChannel().once(Events.SET_STORIES, data => resolve(serializeRawStories(denormalizeStoryParameters(data)))));
|
144
|
+
const store = (_window$__STORYBOOK_S = window.__STORYBOOK_STORY_STORE__) !== null && _window$__STORYBOOK_S !== void 0 ? _window$__STORYBOOK_S : {};
|
145
|
+
|
146
|
+
if (store.cacheAllCSFFiles) {
|
147
|
+
await store.cacheAllCSFFiles();
|
148
|
+
addons.getChannel().emit(Events.SET_STORIES, store.getSetStoriesPayload());
|
149
|
+
} else return;
|
150
|
+
|
151
|
+
addons.getChannel().on(Events.SET_STORIES, data => {
|
152
|
+
// TODO Figure out how to get only updated stories
|
153
|
+
// TODO Subscribe on hmr? like use dummy-hmr
|
154
|
+
setStoriesCounter += 1;
|
155
|
+
const stories = serializeRawStories(denormalizeStoryParameters(data));
|
156
|
+
const storiesByFiles = new Map();
|
157
|
+
Object.values(stories).forEach(story => {
|
158
|
+
const storiesFromFile = storiesByFiles.get(story.parameters.fileName);
|
159
|
+
if (storiesFromFile) storiesFromFile.push(story);else storiesByFiles.set(story.parameters.fileName, [story]);
|
160
|
+
});
|
161
|
+
void fetch("http://".concat(getConnectionUrl(), "/stories"), {
|
162
|
+
method: 'POST',
|
163
|
+
headers: {
|
164
|
+
'Content-Type': 'application/json'
|
165
|
+
},
|
166
|
+
body: JSON.stringify({
|
167
|
+
setStoriesCounter,
|
168
|
+
stories: [...storiesByFiles.entries()]
|
169
|
+
})
|
170
|
+
});
|
171
|
+
});
|
172
|
+
return storiesPromise;
|
140
173
|
}
|
141
174
|
|
142
|
-
function
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
storyId: storyId,
|
177
|
-
name: name,
|
178
|
-
kind: kind
|
179
|
-
});
|
180
|
-
}, 0);
|
181
|
-
_context2.prev = 12;
|
182
|
-
_context2.next = 15;
|
183
|
-
return Promise.race([_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
|
184
|
-
return regeneratorRuntime.wrap(function _callee$(_context) {
|
185
|
-
while (1) {
|
186
|
-
switch (_context.prev = _context.next) {
|
187
|
-
case 0:
|
188
|
-
_context.next = 2;
|
189
|
-
return renderPromise;
|
190
|
-
|
191
|
-
case 2:
|
192
|
-
_context.next = 4;
|
193
|
-
return waitForFontsLoaded();
|
194
|
-
|
195
|
-
case 4:
|
196
|
-
_context.next = 6;
|
197
|
-
return waitForReady;
|
198
|
-
|
199
|
-
case 6:
|
200
|
-
case "end":
|
201
|
-
return _context.stop();
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}, _callee);
|
205
|
-
}))(), errorPromise]);
|
206
|
-
|
207
|
-
case 15:
|
208
|
-
callback();
|
209
|
-
_context2.next = 22;
|
210
|
-
break;
|
211
|
-
|
212
|
-
case 18:
|
213
|
-
_context2.prev = 18;
|
214
|
-
_context2.t0 = _context2["catch"](12);
|
215
|
-
// NOTE Event `STORY_THREW_EXCEPTION` triggered only in react and vue frameworks and return Error instance
|
216
|
-
// NOTE Event `STORY_ERRORED` return error-like object without `name` field
|
217
|
-
errorMessage = _context2.t0 instanceof Error ? (_reason$stack = _context2.t0.stack) !== null && _reason$stack !== void 0 ? _reason$stack : _context2.t0.message : isObject(_context2.t0) ? "".concat(_context2.t0.message, "\n ").concat(_context2.t0.stack) : _context2.t0;
|
218
|
-
callback(errorMessage);
|
219
|
-
|
220
|
-
case 22:
|
221
|
-
_context2.prev = 22;
|
222
|
-
renderPromise.cancel();
|
223
|
-
errorPromise.cancel();
|
224
|
-
return _context2.finish(22);
|
225
|
-
|
226
|
-
case 26:
|
227
|
-
case "end":
|
228
|
-
return _context2.stop();
|
229
|
-
}
|
230
|
-
}
|
231
|
-
}, _callee2, null, [[12, 18, 22, 26]]);
|
232
|
-
}));
|
233
|
-
return _selectStory.apply(this, arguments);
|
175
|
+
async function selectStory(storyId, kind, name, shouldWaitForReady, callback) {
|
176
|
+
if (!isAnimationDisabled) disableAnimation();
|
177
|
+
isTestBrowser = true;
|
178
|
+
const channel = addons.getChannel();
|
179
|
+
const waitForReady = shouldWaitForReady ? new Promise(resolve => window.__CREEVEY_SET_READY_FOR_CAPTURE__ = resolve) : Promise.resolve();
|
180
|
+
if (storyId == currentStory) await resetCurrentStory(channel);else currentStory = storyId;
|
181
|
+
let isCaptureCalled = false;
|
182
|
+
const renderPromise = waitForStoryRendered(channel);
|
183
|
+
const errorPromise = catchRenderError(channel);
|
184
|
+
const capturePromise = waitForCaptureCall().then(() => isCaptureCalled = true);
|
185
|
+
setTimeout(() => channel.emit(Events.SET_CURRENT_STORY, {
|
186
|
+
storyId,
|
187
|
+
name,
|
188
|
+
kind
|
189
|
+
}), 0);
|
190
|
+
|
191
|
+
try {
|
192
|
+
await Promise.race([(async () => {
|
193
|
+
await Promise.race([renderPromise, capturePromise]);
|
194
|
+
await waitForFontsLoaded();
|
195
|
+
await waitForReady;
|
196
|
+
})(), errorPromise]);
|
197
|
+
callback([null, isCaptureCalled]);
|
198
|
+
} catch (reason) {
|
199
|
+
var _reason$stack;
|
200
|
+
|
201
|
+
// NOTE Event `STORY_THREW_EXCEPTION` triggered only in react and vue frameworks and return Error instance
|
202
|
+
// NOTE Event `STORY_ERRORED` return error-like object without `name` field
|
203
|
+
const errorMessage = reason instanceof Error ? (_reason$stack = reason.stack) !== null && _reason$stack !== void 0 ? _reason$stack : reason.message : isObject(reason) ? "".concat(reason.message, "\n ").concat(reason.stack) : reason;
|
204
|
+
callback([errorMessage]);
|
205
|
+
} finally {
|
206
|
+
renderPromise.cancel();
|
207
|
+
errorPromise.cancel();
|
208
|
+
}
|
234
209
|
}
|
235
210
|
|
236
211
|
function updateGlobals(globals) {
|
237
212
|
addons.getChannel().emit(Events.UPDATE_GLOBALS, {
|
238
|
-
globals
|
213
|
+
globals
|
239
214
|
});
|
240
215
|
}
|
241
216
|
|
242
217
|
function insertIgnoreStyles(ignoreSelectors) {
|
243
|
-
|
218
|
+
const stylesElement = document.createElement('style');
|
244
219
|
stylesElement.setAttribute('type', 'text/css');
|
245
220
|
document.head.appendChild(stylesElement);
|
246
|
-
ignoreSelectors.forEach(
|
221
|
+
ignoreSelectors.forEach(selector => {
|
247
222
|
stylesElement.innerHTML += "\n ".concat(selector, " {\n background: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n outline: 0 !important;\n color: rgba(0,0,0,0) !important;\n }\n ").concat(selector, " *, ").concat(selector, "::before, ").concat(selector, "::after {\n visibility: hidden !important;\n }\n ");
|
248
223
|
});
|
249
224
|
return stylesElement;
|
@@ -255,16 +230,94 @@ export function withCreevey() {
|
|
255
230
|
(_ignoreStyles$parentN = ignoreStyles.parentNode) === null || _ignoreStyles$parentN === void 0 ? void 0 : _ignoreStyles$parentN.removeChild(ignoreStyles);
|
256
231
|
}
|
257
232
|
|
233
|
+
function hasPlayCompletedYet(callback) {
|
234
|
+
creeveyReady();
|
235
|
+
let isCaptureCalled = false;
|
236
|
+
let isPlayCompleted = false;
|
237
|
+
const channel = addons.getChannel();
|
238
|
+
void waitForStoryRendered(channel).then(() => {
|
239
|
+
if (isCaptureCalled) return;
|
240
|
+
isPlayCompleted = true;
|
241
|
+
callback(true);
|
242
|
+
});
|
243
|
+
void waitForCaptureCall().then(() => {
|
244
|
+
if (isPlayCompleted) return;
|
245
|
+
isCaptureCalled = true;
|
246
|
+
callback(false);
|
247
|
+
});
|
248
|
+
}
|
249
|
+
|
250
|
+
window.__CREEVEY_GET_STORIES__ = getStories;
|
258
251
|
window.__CREEVEY_SELECT_STORY__ = selectStory;
|
259
252
|
window.__CREEVEY_UPDATE_GLOBALS__ = updateGlobals;
|
260
253
|
window.__CREEVEY_INSERT_IGNORE_STYLES__ = insertIgnoreStyles;
|
261
254
|
window.__CREEVEY_REMOVE_IGNORE_STYLES__ = removeIgnoreStyles;
|
255
|
+
window.__CREEVEY_HAS_PLAY_COMPLETED_YET__ = hasPlayCompletedYet;
|
262
256
|
window.__CREEVEY_SET_READY_FOR_CAPTURE__ = noop;
|
257
|
+
|
258
|
+
const queryAllByQuery = (container, query) => [...container.querySelectorAll(query)].filter(e => e instanceof HTMLElement);
|
259
|
+
|
260
|
+
const getMultipleError = (_, query) => "Found multiple elements by query: ".concat(query);
|
261
|
+
|
262
|
+
const getMissingError = (_, query) => "Unable to find an element by query: ".concat(query);
|
263
|
+
|
264
|
+
const [queryByQuery, getAllByQuery, getByQuery, findAllByQuery, findByQuery] = buildQueries(queryAllByQuery, getMultipleError, getMissingError);
|
265
|
+
const queries = {
|
266
|
+
queryByQuery,
|
267
|
+
getAllByQuery,
|
268
|
+
getByQuery,
|
269
|
+
findAllByQuery,
|
270
|
+
findByQuery
|
271
|
+
};
|
263
272
|
return makeDecorator({
|
264
273
|
name: 'withCreevey',
|
265
274
|
parameterName: 'creevey',
|
266
|
-
wrapper:
|
275
|
+
wrapper: (getStory, context) => {
|
276
|
+
var _ref2;
|
277
|
+
|
278
|
+
// TODO Define proper types, like captureElement is a promise
|
279
|
+
const {
|
280
|
+
captureElement
|
281
|
+
} = context.parameters.creevey = (_ref2 = context.parameters.creevey) !== null && _ref2 !== void 0 ? _ref2 : {};
|
282
|
+
Object.defineProperty(context.parameters.creevey, 'captureElement', {
|
283
|
+
get() {
|
284
|
+
switch (true) {
|
285
|
+
case captureElement === undefined:
|
286
|
+
return Promise.resolve(context.canvasElement);
|
287
|
+
|
288
|
+
case captureElement === null:
|
289
|
+
return Promise.resolve(document.documentElement);
|
290
|
+
|
291
|
+
case typeof captureElement == 'string':
|
292
|
+
return isInternetExplorer // some code from testing-library makes IE hang
|
293
|
+
? Promise.resolve(context.canvasElement.querySelector(captureElement)) : within(context.canvasElement, queries).findByQuery(captureElement);
|
294
|
+
|
295
|
+
case typeof captureElement == 'function':
|
296
|
+
// TODO Define type for it
|
297
|
+
return Promise.resolve(captureElement(context));
|
298
|
+
}
|
299
|
+
},
|
300
|
+
|
301
|
+
enumerable: true,
|
302
|
+
configurable: true
|
303
|
+
});
|
267
304
|
return getStory(context);
|
268
305
|
}
|
269
306
|
});
|
307
|
+
}
|
308
|
+
export async function capture(options) {
|
309
|
+
if (!isTestBrowser) return;
|
310
|
+
captureResolver();
|
311
|
+
waitForCreevey = new Promise(resolve => creeveyReady = resolve);
|
312
|
+
await fetch("http://".concat(getConnectionUrl(), "/capture"), {
|
313
|
+
method: 'POST',
|
314
|
+
headers: {
|
315
|
+
'Content-Type': 'application/json'
|
316
|
+
},
|
317
|
+
body: JSON.stringify({
|
318
|
+
workerId: window.__CREEVEY_WORKER_ID__,
|
319
|
+
options
|
320
|
+
})
|
321
|
+
});
|
322
|
+
await waitForCreevey;
|
270
323
|
}
|
@@ -2,19 +2,22 @@ import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { getBorderColor, themeBorderColors } from './ImagesView';
|
3
3
|
import { styled, withTheme } from '@storybook/theming';
|
4
4
|
import { useApplyScale, useCalcScale, useLoadImages } from '../../helpers';
|
5
|
-
|
5
|
+
import { readyForCapture } from '../../../addon/readyForCapture';
|
6
|
+
const Container = styled.div({
|
6
7
|
position: 'relative',
|
7
8
|
display: 'flex',
|
8
9
|
filter: 'invert(100%)'
|
9
10
|
});
|
10
|
-
|
11
|
+
const ImageContainer = styled.div({
|
11
12
|
position: 'absolute',
|
12
13
|
width: '100%',
|
13
14
|
height: '100%',
|
14
15
|
display: 'flex'
|
15
16
|
});
|
16
|
-
|
17
|
-
|
17
|
+
const Image = styled.img(_ref => {
|
18
|
+
let {
|
19
|
+
borderColor
|
20
|
+
} = _ref;
|
18
21
|
return {
|
19
22
|
boxSizing: 'border-box',
|
20
23
|
border: "1px solid ".concat(borderColor),
|
@@ -22,28 +25,28 @@ var Image = styled.img(function (_ref) {
|
|
22
25
|
filter: 'invert(100%)'
|
23
26
|
};
|
24
27
|
});
|
25
|
-
|
28
|
+
const ActualImage = styled(Image)({
|
26
29
|
mixBlendMode: 'difference'
|
27
30
|
});
|
28
|
-
|
31
|
+
const DiffImage = styled(Image)({
|
29
32
|
opacity: '0'
|
30
33
|
});
|
31
|
-
export
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
export const BlendView = withTheme(_ref2 => {
|
35
|
+
let {
|
36
|
+
actual,
|
37
|
+
diff,
|
38
|
+
expect,
|
39
|
+
theme
|
40
|
+
} = _ref2;
|
41
|
+
const expectImageRef = useRef(null);
|
42
|
+
const diffImageRef = useRef(null);
|
43
|
+
const actualImageRef = useRef(null);
|
44
|
+
const loaded = useLoadImages(expect, diff, actual);
|
45
|
+
const scale = useCalcScale(diffImageRef, loaded);
|
41
46
|
useApplyScale(expectImageRef, scale, loaded);
|
42
47
|
useApplyScale(actualImageRef, scale, loaded);
|
43
|
-
useEffect(
|
44
|
-
|
45
|
-
|
46
|
-
if (loaded) (_window$__CREEVEY_SET = (_window = window).__CREEVEY_SET_READY_FOR_CAPTURE__) === null || _window$__CREEVEY_SET === void 0 ? void 0 : _window$__CREEVEY_SET.call(_window);
|
48
|
+
useEffect(() => {
|
49
|
+
if (loaded) readyForCapture();
|
47
50
|
}, [loaded]);
|
48
51
|
return /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(ImageContainer, null, /*#__PURE__*/React.createElement(Image, {
|
49
52
|
ref: expectImageRef,
|
@@ -4,26 +4,24 @@ import { SwapView } from './SwapView';
|
|
4
4
|
import { SlideView } from './SlideView';
|
5
5
|
import { BlendView } from './BlendView';
|
6
6
|
import { styled, withTheme } from '@storybook/theming';
|
7
|
-
export
|
7
|
+
export const themeBorderColors = {
|
8
8
|
actual: 'negative',
|
9
9
|
expect: 'positive',
|
10
10
|
diff: 'secondary'
|
11
11
|
};
|
12
12
|
|
13
|
-
|
14
|
-
return color in theme.color;
|
15
|
-
};
|
13
|
+
const isColor = (theme, color) => color in theme.color;
|
16
14
|
|
17
15
|
export function getBorderColor(theme, color) {
|
18
16
|
return isColor(theme, color) ? theme.color[color] : color;
|
19
17
|
}
|
20
|
-
|
18
|
+
const views = {
|
21
19
|
'side-by-side': SideBySideView,
|
22
20
|
swap: SwapView,
|
23
21
|
slide: SlideView,
|
24
22
|
blend: BlendView
|
25
23
|
};
|
26
|
-
|
24
|
+
const Container = styled.div({
|
27
25
|
height: '100%',
|
28
26
|
display: 'flex',
|
29
27
|
textAlign: 'center',
|
@@ -31,25 +29,31 @@ var Container = styled.div({
|
|
31
29
|
justifyContent: 'center',
|
32
30
|
padding: '0 20px'
|
33
31
|
});
|
34
|
-
|
32
|
+
const ImageLink = styled.a({
|
35
33
|
lineHeight: 0
|
36
34
|
});
|
37
|
-
|
38
|
-
|
35
|
+
const ActualImage = withTheme(styled.img(_ref => {
|
36
|
+
let {
|
37
|
+
theme
|
38
|
+
} = _ref;
|
39
39
|
return {
|
40
40
|
border: "1px solid ".concat(getBorderColor(theme, themeBorderColors.expect)),
|
41
41
|
maxWidth: '100%'
|
42
42
|
};
|
43
43
|
}));
|
44
44
|
export function ImagesView(_ref2) {
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
let {
|
46
|
+
url,
|
47
|
+
image,
|
48
|
+
canApprove,
|
49
|
+
mode
|
50
|
+
} = _ref2;
|
51
|
+
const ViewComponent = views[mode];
|
52
|
+
const {
|
53
|
+
actual,
|
54
|
+
diff,
|
55
|
+
expect
|
56
|
+
} = image;
|
53
57
|
return /*#__PURE__*/React.createElement(Container, null, canApprove && diff && expect ? /*#__PURE__*/React.createElement(ViewComponent, {
|
54
58
|
actual: "".concat(url, "/").concat(actual),
|
55
59
|
diff: "".concat(url, "/").concat(diff),
|