creevey 0.7.37 → 0.8.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +30 -5
  2. package/README.md +1 -1
  3. package/docs/config.md +37 -5
  4. package/docs/grid.md +2 -1
  5. package/lib/cjs/client/addon/Manager.js +3 -1
  6. package/lib/cjs/client/addon/utils.js +1 -41
  7. package/lib/cjs/client/addon/withCreevey.js +11 -13
  8. package/lib/cjs/client/web/1.js +2 -2
  9. package/lib/cjs/client/web/2.js +1 -1
  10. package/lib/cjs/client/web/main.js +6 -6
  11. package/lib/cjs/index.js +14 -1
  12. package/lib/cjs/server/config.js +3 -0
  13. package/lib/cjs/server/extract.js +7 -3
  14. package/lib/cjs/server/loaders/babel/register.js +2 -1
  15. package/lib/cjs/server/loaders/webpack/compile.js +3 -19
  16. package/lib/cjs/server/loaders/webpack/creevey-loader.js +1 -1
  17. package/lib/cjs/server/master/master.js +3 -5
  18. package/lib/cjs/server/selenium/browser.js +25 -11
  19. package/lib/cjs/server/selenium/selenoid.js +1 -1
  20. package/lib/cjs/server/stories.js +20 -226
  21. package/lib/cjs/server/storybook/entry.js +5 -4
  22. package/lib/cjs/server/storybook/helpers.js +40 -4
  23. package/lib/cjs/server/storybook/nodejs-provider.js +220 -0
  24. package/lib/cjs/server/utils.js +25 -2
  25. package/lib/cjs/server/worker/helpers.js +8 -9
  26. package/lib/cjs/server/worker/worker.js +1 -2
  27. package/lib/cjs/shared.js +35 -0
  28. package/lib/esm/client/addon/Manager.js +3 -2
  29. package/lib/esm/client/addon/utils.js +1 -33
  30. package/lib/esm/client/addon/withCreevey.js +1 -1
  31. package/lib/esm/index.js +3 -1
  32. package/lib/esm/server/config.js +4 -1
  33. package/lib/esm/server/extract.js +7 -3
  34. package/lib/esm/server/loaders/babel/register.js +3 -2
  35. package/lib/esm/server/loaders/webpack/compile.js +4 -20
  36. package/lib/esm/server/loaders/webpack/creevey-loader.js +1 -1
  37. package/lib/esm/server/master/master.js +3 -5
  38. package/lib/esm/server/selenium/browser.js +22 -7
  39. package/lib/esm/server/selenium/selenoid.js +1 -1
  40. package/lib/esm/server/stories.js +23 -219
  41. package/lib/esm/server/storybook/entry.js +4 -4
  42. package/lib/esm/server/storybook/helpers.js +36 -4
  43. package/lib/esm/server/storybook/nodejs-provider.js +200 -0
  44. package/lib/esm/server/utils.js +23 -1
  45. package/lib/esm/server/worker/helpers.js +8 -9
  46. package/lib/esm/server/worker/worker.js +1 -2
  47. package/lib/esm/shared.js +22 -0
  48. package/lib/types/cli.d.ts +1 -1
  49. package/lib/types/client/addon/Manager.d.ts +37 -37
  50. package/lib/types/client/addon/components/Addon.d.ts +8 -8
  51. package/lib/types/client/addon/components/Icons.d.ts +7 -7
  52. package/lib/types/client/addon/components/Panel.d.ts +9 -9
  53. package/lib/types/client/addon/components/TestSelect.d.ts +9 -9
  54. package/lib/types/client/addon/components/Tools.d.ts +6 -6
  55. package/lib/types/client/addon/decorator.d.ts +1 -1
  56. package/lib/types/client/addon/preset.d.ts +22 -22
  57. package/lib/types/client/addon/register.d.ts +3 -3
  58. package/lib/types/client/addon/utils.d.ts +2 -6
  59. package/lib/types/client/addon/withCreevey.d.ts +13 -46
  60. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -3
  61. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +25 -25
  62. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -3
  63. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -3
  64. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -3
  65. package/lib/types/client/shared/components/ImagesView/index.d.ts +5 -5
  66. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +9 -9
  67. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +8 -8
  68. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +12 -12
  69. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +17 -17
  70. package/lib/types/client/shared/components/ResultsPage.d.ts +18 -18
  71. package/lib/types/client/shared/creeveyClientApi.d.ts +9 -9
  72. package/lib/types/client/shared/helpers.d.ts +46 -46
  73. package/lib/types/client/shared/viewMode.d.ts +4 -4
  74. package/lib/types/client/web/CreeveyApp.d.ts +12 -12
  75. package/lib/types/client/web/CreeveyContext.d.ts +11 -11
  76. package/lib/types/client/web/CreeveyLoader.d.ts +3 -3
  77. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +19 -19
  78. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +6 -6
  79. package/lib/types/client/web/CreeveyView/SideBar/SideBar.d.ts +14 -14
  80. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +13 -13
  81. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +33 -33
  82. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +8 -8
  83. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +10 -10
  84. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +9 -9
  85. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +6 -6
  86. package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +1 -1
  87. package/lib/types/client/web/KeyboardEventsContext.d.ts +13 -13
  88. package/lib/types/client/web/index.d.ts +4 -4
  89. package/lib/types/creevey.d.ts +1 -1
  90. package/lib/types/server/config.d.ts +4 -4
  91. package/lib/types/server/docker.d.ts +7 -7
  92. package/lib/types/server/extract.d.ts +2 -2
  93. package/lib/types/server/index.d.ts +2 -2
  94. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +1 -1
  95. package/lib/types/server/loaders/babel/helpers.d.ts +19 -19
  96. package/lib/types/server/loaders/babel/register.d.ts +5 -5
  97. package/lib/types/server/loaders/hooks/mdx.d.ts +1 -1
  98. package/lib/types/server/loaders/hooks/svelte.d.ts +1 -1
  99. package/lib/types/server/loaders/webpack/compile.d.ts +2 -2
  100. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +2 -2
  101. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +10 -10
  102. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +6 -6
  103. package/lib/types/server/loaders/webpack/start.d.ts +1 -1
  104. package/lib/types/server/logger.d.ts +6 -6
  105. package/lib/types/server/master/api.d.ts +7 -7
  106. package/lib/types/server/master/index.d.ts +3 -3
  107. package/lib/types/server/master/master.d.ts +6 -6
  108. package/lib/types/server/master/pool.d.ts +30 -30
  109. package/lib/types/server/master/runner.d.ts +26 -26
  110. package/lib/types/server/master/server.d.ts +2 -2
  111. package/lib/types/server/messages.d.ts +18 -18
  112. package/lib/types/server/selenium/browser.d.ts +14 -14
  113. package/lib/types/server/selenium/index.d.ts +2 -2
  114. package/lib/types/server/selenium/selenoid.d.ts +3 -3
  115. package/lib/types/server/stories.d.ts +8 -13
  116. package/lib/types/server/storybook/entry.d.ts +18 -14
  117. package/lib/types/server/storybook/helpers.d.ts +24 -22
  118. package/lib/types/server/storybook/nodejs-provider.d.ts +5 -0
  119. package/lib/types/server/update.d.ts +2 -2
  120. package/lib/types/server/utils.d.ts +19 -18
  121. package/lib/types/server/worker/chai-image.d.ts +6 -6
  122. package/lib/types/server/worker/helpers.d.ts +7 -7
  123. package/lib/types/server/worker/index.d.ts +1 -1
  124. package/lib/types/server/worker/reporter.d.ts +8 -8
  125. package/lib/types/server/worker/worker.d.ts +4 -4
  126. package/lib/types/shared.d.ts +4 -0
  127. package/lib/types/types.d.ts +459 -431
  128. package/package.json +53 -48
  129. package/types/mocha.d.ts +1 -0
  130. package/storybook-static/stories.json +0 -530
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.loadStories = loadStories;
7
+
8
+ var _path = _interopRequireDefault(require("path"));
9
+
10
+ var _cluster = require("cluster");
11
+
12
+ var _chokidar = _interopRequireDefault(require("chokidar"));
13
+
14
+ var _types = require("../../types");
15
+
16
+ var _utils = require("../utils");
17
+
18
+ var _messages = require("../messages");
19
+
20
+ var _helpers = require("./helpers");
21
+
22
+ var _logger = require("../logger");
23
+
24
+ var _shared = require("../../shared");
25
+
26
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
+
28
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
29
+
30
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
31
+
32
+ async function initStorybookEnvironment() {
33
+ // @ts-ignore
34
+ (await Promise.resolve().then(() => _interopRequireWildcard(require('global-jsdom')))).default(undefined, {
35
+ url: 'http://localhost'
36
+ }); // NOTE Cutoff `jsdom` part from userAgent, because storybook check enviroment and create events channel if runs in browser
37
+ // https://github.com/storybookjs/storybook/blob/v5.2.8/lib/core/src/client/preview/start.js#L98
38
+ // Example: "Mozilla/5.0 (linux) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/15.2.1"
39
+
40
+ Object.defineProperty(window.navigator, 'userAgent', {
41
+ value: window.navigator.userAgent.split(' ').filter(token => !token.startsWith('jsdom')).join(' ')
42
+ }); // TODO Look at creevey debug flag
43
+
44
+ const {
45
+ logger
46
+ } = await (0, _helpers.importStorybookClientLogger)(); // NOTE: Disable duplication warnings for >=6.2 storybook
47
+
48
+ if (_cluster.isWorker) logger.warn = _types.noop; // NOTE: disable logger for 5.x storybook
49
+
50
+ logger.debug = _types.noop;
51
+ return Promise.resolve().then(() => _interopRequireWildcard(require('./entry')));
52
+ }
53
+
54
+ function watchStories(channel, watcher, initialFiles) {
55
+ const watchingFiles = initialFiles;
56
+ let storiesByFiles = new Map();
57
+ (0, _messages.subscribeOn)('shutdown', () => void watcher.close());
58
+ watcher.add(Array.from(watchingFiles));
59
+ watcher.on('change', filePath => storiesByFiles.set(_path.default.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
60
+ watcher.on('unlink', filePath => storiesByFiles.set(_path.default.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
61
+ return data => {
62
+ const stories = (0, _helpers.isStorybookVersionLessThan)(6) || (0, _helpers.isStorybookVersionGreaterThan)(6, 3) ? data.stories : (0, _shared.denormalizeStoryParameters)(data);
63
+ const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
64
+ const addedFiles = Array.from(files).filter(filePath => !watchingFiles.has(filePath));
65
+ const removedFiles = Array.from(watchingFiles).filter(filePath => !files.has(filePath));
66
+ watcher.add(addedFiles);
67
+ addedFiles.forEach(filePath => {
68
+ watchingFiles.add(filePath);
69
+ storiesByFiles.set(filePath, []);
70
+ });
71
+ removedFiles.forEach(filePath => watchingFiles.delete(filePath));
72
+ Object.values(stories).forEach(story => {
73
+ var _storiesByFiles$get;
74
+
75
+ return (_storiesByFiles$get = storiesByFiles.get(story.parameters.fileName)) === null || _storiesByFiles$get === void 0 ? void 0 : _storiesByFiles$get.push(story);
76
+ });
77
+ channel.emit('storiesUpdated', storiesByFiles);
78
+ storiesByFiles = new Map();
79
+ };
80
+ }
81
+
82
+ function loadStoriesFromBundle(watch) {
83
+ const bundlePath = _path.default.join((0, _utils.getCreeveyCache)(), 'storybook/main.js');
84
+
85
+ if (watch) {
86
+ (0, _messages.subscribeOn)('webpack', message => {
87
+ if (message.type != 'rebuild succeeded') return;
88
+ Object.values(global.__CREEVEY_HMR_DATA__).filter(({
89
+ callback
90
+ }) => callback).forEach(({
91
+ data,
92
+ callback
93
+ }) => callback(data));
94
+ delete require.cache[bundlePath];
95
+ Promise.resolve(`${bundlePath}`).then(s => _interopRequireWildcard(require(s)));
96
+ });
97
+ }
98
+
99
+ Promise.resolve(`${bundlePath}`).then(s => _interopRequireWildcard(require(s)));
100
+ }
101
+
102
+ async function loadStoriesDirectly(config, {
103
+ watcher,
104
+ debug
105
+ }) {
106
+ const {
107
+ toRequireContext,
108
+ normalizeStoriesEntry
109
+ } = await (0, _helpers.importStorybookCoreCommon)();
110
+ const {
111
+ addParameters,
112
+ configure
113
+ } = await Promise.resolve().then(() => _interopRequireWildcard(require('./entry')));
114
+ const requireContext = await (await Promise.resolve().then(() => _interopRequireWildcard(require('../loaders/babel/register')))).default(config, debug);
115
+
116
+ const preview = (() => {
117
+ try {
118
+ return require.resolve(`${config.storybookDir}/preview`);
119
+ } catch (_) {
120
+ /* noop */
121
+ }
122
+ })();
123
+
124
+ const {
125
+ stories
126
+ } = await (0, _helpers.importStorybookConfig)();
127
+ const contexts = stories.map(entry => {
128
+ const normalizedEntry = (0, _helpers.isStorybookVersionLessThan)(6, 4) ? entry : normalizeStoriesEntry(entry, {
129
+ configDir: config.storybookDir,
130
+ workingDir: process.cwd()
131
+ });
132
+ const {
133
+ path: storiesPath,
134
+ recursive,
135
+ match
136
+ } = toRequireContext(normalizedEntry);
137
+ watcher === null || watcher === void 0 ? void 0 : watcher.add(_path.default.resolve(config.storybookDir, storiesPath));
138
+ return () => requireContext(storiesPath, recursive, new RegExp(match));
139
+ });
140
+
141
+ let disposeCallback = data => void data;
142
+
143
+ Object.assign(module, {
144
+ hot: {
145
+ data: {},
146
+
147
+ accept() {
148
+ /* noop */
149
+ },
150
+
151
+ dispose(callback) {
152
+ disposeCallback = callback;
153
+ }
154
+
155
+ }
156
+ });
157
+
158
+ async function startStorybook() {
159
+ if (preview) {
160
+ const {
161
+ parameters,
162
+ globals,
163
+ globalTypes
164
+ } = await Promise.resolve(`${preview}`).then(s => _interopRequireWildcard(require(s)));
165
+ if (parameters) addParameters(parameters);
166
+ if (globals) addParameters({
167
+ globals
168
+ });
169
+ if (globalTypes) addParameters({
170
+ globalTypes
171
+ });
172
+ }
173
+
174
+ try {
175
+ configure(contexts.map(ctx => ctx()), module, false);
176
+ } catch (error) {
177
+ if (_cluster.isMaster) _logger.logger.error(error);
178
+ }
179
+ }
180
+
181
+ watcher === null || watcher === void 0 ? void 0 : watcher.add(config.storybookDir);
182
+ watcher === null || watcher === void 0 ? void 0 : watcher.on('all', (_event, filename) => {
183
+ var _module$hot;
184
+
185
+ disposeCallback((_module$hot = module.hot) === null || _module$hot === void 0 ? void 0 : _module$hot.data);
186
+ delete require.cache[filename];
187
+ void startStorybook();
188
+ });
189
+ void startStorybook();
190
+ }
191
+
192
+ async function loadStories(config, {
193
+ watch,
194
+ debug
195
+ }, storiesListener) {
196
+ const storybookApi = await initStorybookEnvironment();
197
+ const Events = await (0, _helpers.importStorybookCoreEvents)();
198
+ const {
199
+ channel
200
+ } = storybookApi;
201
+ channel.removeAllListeners(Events.CURRENT_STORY_WAS_SET);
202
+ channel.on('storiesUpdated', storiesListener);
203
+ let watcher = null;
204
+ if (watch) watcher = _chokidar.default.watch([], {
205
+ ignoreInitial: true
206
+ });
207
+ const loadPromise = new Promise(resolve => {
208
+ channel.once(Events.SET_STORIES, data => {
209
+ const stories = (0, _helpers.isStorybookVersionLessThan)(6) || (0, _helpers.isStorybookVersionGreaterThan)(6, 3) ? data.stories : (0, _shared.denormalizeStoryParameters)(data);
210
+ const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
211
+ if (watcher) channel.on(Events.SET_STORIES, watchStories(channel, watcher, files));
212
+ resolve(data);
213
+ });
214
+ });
215
+ if (config.useWebpackToExtractTests) loadStoriesFromBundle(watch);else void loadStoriesDirectly(config, {
216
+ watcher,
217
+ debug
218
+ });
219
+ return loadPromise;
220
+ }
@@ -10,7 +10,7 @@ exports.getCreeveyCache = getCreeveyCache;
10
10
  exports.runSequence = runSequence;
11
11
  exports.testsToImages = testsToImages;
12
12
  exports.removeProps = removeProps;
13
- exports.downloadBinary = exports.isInsideDocker = exports.extensions = exports.LOCALHOST_REGEXP = exports.isShuttingDown = void 0;
13
+ exports.downloadBinary = exports.isInsideDocker = exports.skipOptionKeys = exports.extensions = exports.LOCALHOST_REGEXP = exports.isShuttingDown = void 0;
14
14
 
15
15
  var _fs = require("fs");
16
16
 
@@ -34,6 +34,8 @@ const LOCALHOST_REGEXP = /(localhost|127\.0\.0\.1)/i;
34
34
  exports.LOCALHOST_REGEXP = LOCALHOST_REGEXP;
35
35
  const extensions = ['.js', '.jsx', '.ts', '.tsx'];
36
36
  exports.extensions = extensions;
37
+ const skipOptionKeys = ['in', 'kinds', 'stories', 'tests', 'reason'];
38
+ exports.skipOptionKeys = skipOptionKeys;
37
39
 
38
40
  function matchBy(pattern, value) {
39
41
  return typeof pattern == 'string' && pattern == value || Array.isArray(pattern) && pattern.includes(value) || pattern instanceof RegExp && pattern.test(value) || !(0, _types.isDefined)(pattern);
@@ -45,9 +47,30 @@ function shouldSkip(browser, meta, skipOptions, test) {
45
47
  }
46
48
 
47
49
  if (Array.isArray(skipOptions)) {
48
- return skipOptions.map(skipOption => shouldSkip(browser, meta, skipOption, test)).find(Boolean) || false;
50
+ for (const skip of skipOptions) {
51
+ const reason = shouldSkip(browser, meta, skip, test);
52
+ if (reason) return reason;
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ let hasSkipOptionKeys = false;
59
+
60
+ for (const skipKey in skipOptions) {
61
+ if (skipOptionKeys.includes(skipKey)) {
62
+ hasSkipOptionKeys = true;
63
+ continue;
64
+ }
65
+
66
+ const reason = shouldSkip(browser, meta, {
67
+ reason: skipKey,
68
+ ...skipOptions[skipKey]
69
+ }, test);
70
+ if (reason) return reason;
49
71
  }
50
72
 
73
+ if (!hasSkipOptionKeys) return false;
51
74
  const {
52
75
  in: browsers,
53
76
  kinds,
@@ -60,15 +60,14 @@ async function addTestsFromStories(rootSuite, config, {
60
60
  debug
61
61
  }) {
62
62
  const mochaTestsById = new Map();
63
- const tests = await (0, _stories.loadTestsFromStories)(config, [browser], {
63
+ const tests = await (0, _stories.loadTestsFromStories)([browser], listener => config.storiesProvider(config, {
64
64
  watch,
65
- debug,
66
- update: testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
67
- const oldTest = mochaTestsById.get(id);
68
- mochaTestsById.delete(id);
69
- if (oldTest) removeTestOrSuite(oldTest);
70
- if (newTest) mochaTestsById.set(id, addTest(rootSuite, newTest));
71
- })
72
- });
65
+ debug
66
+ }, listener), testsDiff => Object.entries(testsDiff).forEach(([id, newTest]) => {
67
+ const oldTest = mochaTestsById.get(id);
68
+ mochaTestsById.delete(id);
69
+ if (oldTest) removeTestOrSuite(oldTest);
70
+ if (newTest) mochaTestsById.set(id, addTest(rootSuite, newTest));
71
+ }));
73
72
  Object.values(tests).filter(_types.isDefined).forEach(test => mochaTestsById.set(test.id, addTest(rootSuite, test)));
74
73
  }
@@ -45,8 +45,7 @@ async function getStat(filePath) {
45
45
  try {
46
46
  return await statAsync(filePath);
47
47
  } catch (error) {
48
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
49
- if (error.code === 'ENOENT') {
48
+ if (typeof error == 'object' && error && error.code === 'ENOENT') {
50
49
  return null;
51
50
  }
52
51
 
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.denormalizeStoryParameters = exports.combineParameters = void 0;
7
+
8
+ var _lodash = require("lodash");
9
+
10
+ // NOTE: Copy-paste from storybook/api
11
+ const combineParameters = (...parameterSets) => // eslint-disable-next-line @typescript-eslint/no-unsafe-return
12
+ (0, _lodash.mergeWith)({}, ...parameterSets, (_, srcValue) => {
13
+ // Treat arrays as scalars:
14
+ if (Array.isArray(srcValue)) return srcValue;
15
+ return undefined;
16
+ }); // NOTE: Copy-paste from storybook/api
17
+
18
+
19
+ exports.combineParameters = combineParameters;
20
+
21
+ const denormalizeStoryParameters = ({
22
+ globalParameters,
23
+ kindParameters,
24
+ stories
25
+ }) => {
26
+ return (0, _lodash.mapValues)(stories, storyData => {
27
+ var _kindParameters$story;
28
+
29
+ return { ...storyData,
30
+ parameters: combineParameters(globalParameters, (_kindParameters$story = kindParameters[storyData.kind]) !== null && _kindParameters$story !== void 0 ? _kindParameters$story : {}, storyData.parameters)
31
+ };
32
+ });
33
+ };
34
+
35
+ exports.denormalizeStoryParameters = denormalizeStoryParameters;
@@ -31,11 +31,12 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
31
31
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
32
32
 
33
33
  import { SET_STORIES, STORY_RENDERED } from '@storybook/core-events';
34
+ import { denormalizeStoryParameters } from '../../shared';
34
35
  import { isDefined } from '../../types';
35
36
  import { initCreeveyClientApi } from '../shared/creeveyClientApi';
36
37
  import { calcStatus } from '../shared/helpers';
37
38
  import { ADDON_ID } from './register';
38
- import { getEmojiByTestStatus, denormalizeStoryParameters } from './utils';
39
+ import { getEmojiByTestStatus } from './utils';
39
40
  export var CreeveyManager = /*#__PURE__*/function () {
40
41
  function CreeveyManager(storybookApi) {
41
42
  var _this = this;
@@ -230,7 +231,7 @@ export var CreeveyManager = /*#__PURE__*/function () {
230
231
 
231
232
  _defineProperty(this, "onSetStories", function (data) {
232
233
  // TODO: Send PR to storybook to fix this
233
- var stories = data.v ? denormalizeStoryParameters(data) : data;
234
+ var stories = data.v ? denormalizeStoryParameters(data) : data.stories;
234
235
  _this.stories = stories;
235
236
  });
236
237
 
@@ -1,10 +1,3 @@
1
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2
-
3
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
4
-
5
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
-
7
- import { mapValues, mergeWith } from 'lodash';
8
1
  export function getEmojiByTestStatus(status) {
9
2
  var skip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
10
3
 
@@ -35,29 +28,4 @@ export function getEmojiByTestStatus(status) {
35
28
  return '';
36
29
  }
37
30
  }
38
- } // NOTE: Copy-paste from storybook/api
39
-
40
- export var combineParameters = function combineParameters() {
41
- for (var _len = arguments.length, parameterSets = new Array(_len), _key = 0; _key < _len; _key++) {
42
- parameterSets[_key] = arguments[_key];
43
- }
44
-
45
- return (// eslint-disable-next-line @typescript-eslint/no-unsafe-return
46
- mergeWith.apply(void 0, [{}].concat(parameterSets, [function (_, srcValue) {
47
- // Treat arrays as scalars:
48
- if (Array.isArray(srcValue)) return srcValue;
49
- return undefined;
50
- }]))
51
- );
52
- }; // NOTE: Copy-paste from storybook/api
53
-
54
- export var denormalizeStoryParameters = function denormalizeStoryParameters(_ref) {
55
- var globalParameters = _ref.globalParameters,
56
- kindParameters = _ref.kindParameters,
57
- stories = _ref.stories;
58
- return mapValues(stories, function (storyData) {
59
- return _objectSpread(_objectSpread({}, storyData), {}, {
60
- parameters: combineParameters(globalParameters, kindParameters[storyData.kind], storyData.parameters)
61
- });
62
- });
63
- };
31
+ }
@@ -4,7 +4,7 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
4
4
 
5
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
6
 
7
- import Events from '@storybook/core-events';
7
+ import * as Events from '@storybook/core-events';
8
8
  import * as polyfill from 'event-source-polyfill';
9
9
  import { addons, makeDecorator } from '@storybook/addons';
10
10
  import { isObject, noop } from '../../types';
package/lib/esm/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './types';
2
- export * from './client/addon/withCreevey';
2
+ export * from './client/addon/withCreevey'; // export { loadStories as browserStoriesProvider } from './server/storybook/browser-provider';
3
+
4
+ export { loadStories as nodejsStoriesProvider } from './server/storybook/nodejs-provider';
@@ -1,6 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { isStorybookVersionLessThan, storybookDirRef } from './storybook/helpers';
3
+ import { isCSFv3Enabled, isStorybookVersionLessThan, storybookDirRef } from './storybook/helpers';
4
+ import { loadStories as nodejsStoriesProvider } from './storybook/nodejs-provider'; // import { loadStories as browserStoriesProvider } from './storybook/browser-provider';
5
+
4
6
  import { isDefined } from '../types';
5
7
  export const defaultBrowser = 'chrome';
6
8
  export const defaultConfig = {
@@ -58,6 +60,7 @@ export async function readConfig(options) {
58
60
  if (isDefined(configPath)) Object.assign(userConfig, (await import(configPath)).default);
59
61
  storybookDirRef.current = userConfig.storybookDir;
60
62
  if (isStorybookVersionLessThan(6, 2)) userConfig.useWebpackToExtractTests = true;
63
+ if (!userConfig.storiesProvider) userConfig.storiesProvider = (await isCSFv3Enabled()) ? nodejsStoriesProvider : nodejsStoriesProvider;
61
64
  if (options.failFast != undefined) userConfig.failFast = Boolean(options.failFast);
62
65
  if (options.reportDir) userConfig.reportDir = path.resolve(options.reportDir);
63
66
  if (options.screenDir) userConfig.screenDir = path.resolve(options.screenDir); // NOTE: Hack to pass typescript checking
@@ -16,10 +16,14 @@ export default async function extract(config, options) {
16
16
  });
17
17
  }
18
18
 
19
- const tests = await loadTestsFromStories(config, Object.keys(config.browsers), {
20
- debug: options.debug
19
+ const tests = await loadTestsFromStories(Object.keys(config.browsers), async listener => {
20
+ const stories = await config.storiesProvider(config, {
21
+ watch: false,
22
+ debug: options.debug
23
+ }, listener);
24
+ if (options.extract) saveStoriesJson(stories, options.extract);
25
+ return stories;
21
26
  });
22
- if (options.extract) saveStoriesJson(options.extract);
23
27
  if (options.tests) saveTestsJson(tests); // eslint-disable-next-line no-process-exit
24
28
 
25
29
  process.exit(0);
@@ -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 requireContext = getRequireContext(config.storybookDir);
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
@@ -3,7 +3,7 @@ import path from 'path';
3
3
  import webpack from 'webpack';
4
4
  import nodeExternals from 'webpack-node-externals';
5
5
  import { extensions as fallbackExtensions, getCreeveyCache } from '../../utils';
6
- import { getStorybookFramework, hasDocsAddon, isStorybookVersionLessThan, resolveFromStorybook } from '../../storybook/helpers';
6
+ import { getStorybookFramework, hasDocsAddon, importStorybookConfig, isStorybookVersionLessThan, resolveFromStorybook } from '../../storybook/helpers';
7
7
  import { noop } from '../../../types';
8
8
  import { emitWebpackMessage, subscribeOn } from '../../messages';
9
9
  import { logger } from '../../logger';
@@ -157,27 +157,11 @@ async function getWebpackConfigForStorybook_6_2(framework, configDir, outputDir)
157
157
  });
158
158
  }
159
159
 
160
- async function removeAddons(configDir) {
161
- const storybookUtilsPath = isStorybookVersionLessThan(6, 2) ? '@storybook/core/dist/server/utils' : '@storybook/core-common/dist/cjs/utils';
162
- const serverRequireModule = isStorybookVersionLessThan(6, 2) ? 'server-require' : 'interpret-require';
163
-
160
+ async function removeAddons() {
164
161
  try {
165
162
  var _config$core;
166
163
 
167
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
168
- const {
169
- getInterpretedFile
170
- } = await import(resolveFromStorybook(`${storybookUtilsPath}/interpret-files`)); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
171
-
172
- const {
173
- default: serverRequireFallback,
174
- serverRequire = serverRequireFallback
175
- } = await import(resolveFromStorybook(`${storybookUtilsPath}/${serverRequireModule}`)); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
176
-
177
- const mainConfigFile = isStorybookVersionLessThan(6, 1) ? path.join(configDir, 'main') : // eslint-disable-next-line @typescript-eslint/no-unsafe-call
178
- getInterpretedFile(path.join(configDir, 'main')); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
179
-
180
- const config = serverRequire(mainConfigFile);
164
+ const config = await importStorybookConfig();
181
165
 
182
166
  if (((_config$core = config.core) === null || _config$core === void 0 ? void 0 : _config$core.builder) == 'webpack5') {
183
167
  logger.warn("Be aware Creevey doesn't fully support webpack@5, some feature might not work well");
@@ -220,7 +204,7 @@ export default async function compile(config, {
220
204
  };
221
205
  process.env.NODE_ENV = 'production'; // NOTE Remove addons by monkey patching, only for new config file (main.js)
222
206
 
223
- const areAddonsRemoved = await removeAddons(config.storybookDir);
207
+ const areAddonsRemoved = await removeAddons();
224
208
  const getWebpackConfig = isStorybookVersionLessThan(6, 2) ? getWebpackConfigForStorybook_pre6_2 : getWebpackConfigForStorybook_6_2;
225
209
  const storybookWebpackConfig = await getWebpackConfig(storybookFramework, config.storybookDir, outputDir);
226
210
  const extensions = (_storybookWebpackConf = (_storybookWebpackConf2 = storybookWebpackConfig.resolve) === null || _storybookWebpackConf2 === void 0 ? void 0 : _storybookWebpackConf2.extensions) !== null && _storybookWebpackConf !== void 0 ? _storybookWebpackConf : fallbackExtensions;
@@ -138,7 +138,7 @@ export default function (source) {
138
138
  } catch (error) {
139
139
  this && logger.warn('Failed to transform file', this.resourcePath);
140
140
 
141
- if ('loc' in error) {
141
+ if (typeof error == 'object' && error && 'loc' in error) {
142
142
  logger.warn(codeFrameColumns(source, {
143
143
  start: error.loc
144
144
  }, {
@@ -27,11 +27,9 @@ export default async function master(config, options) {
27
27
  } catch (error) {// Ignore error
28
28
  }
29
29
 
30
- const tests = await loadTestsFromStories(config, Object.keys(config.browsers), { ...options,
31
- update: testsDiff => {
32
- runner.updateTests(testsDiff);
33
- saveTestsJson(runner.tests, config.reportDir);
34
- }
30
+ const tests = await loadTestsFromStories(Object.keys(config.browsers), listener => config.storiesProvider(config, options, listener), testsDiff => {
31
+ runner.updateTests(testsDiff);
32
+ saveTestsJson(runner.tests, config.reportDir);
35
33
  });
36
34
  runner.tests = mergeTests(testsFromReport, tests);
37
35
  saveTestsJson(runner.tests, config.reportDir);
@@ -1,17 +1,17 @@
1
+ import chalk from 'chalk';
1
2
  import http from 'http';
2
3
  import https from 'https';
3
- import { PNG } from 'pngjs';
4
4
  import { getLogger } from 'loglevel';
5
5
  import prefix from 'loglevel-plugin-prefix';
6
- import { Builder, By, Origin, Capabilities } from 'selenium-webdriver';
7
- import { noop, isDefined } from '../../types';
8
- import { subscribeOn } from '../messages';
9
6
  import { networkInterfaces } from 'os';
10
- import { runSequence, LOCALHOST_REGEXP, isShuttingDown } from '../utils';
7
+ import { PNG } from 'pngjs';
8
+ import { Builder, By, Capabilities, Origin } from 'selenium-webdriver';
11
9
  import { PageLoadStrategy } from 'selenium-webdriver/lib/capabilities';
12
- import { importStorybookCoreEvents, isStorybookVersionLessThan } from '../storybook/helpers';
10
+ import { isDefined, noop } from '../../types';
13
11
  import { colors, logger } from '../logger';
14
- import chalk from 'chalk';
12
+ import { subscribeOn } from '../messages';
13
+ import { importStorybookCoreEvents, isStorybookVersionLessThan } from '../storybook/helpers';
14
+ import { isShuttingDown, LOCALHOST_REGEXP, runSequence } from '../utils';
15
15
  const DOCKER_INTERNAL = 'host.docker.internal';
16
16
  let browserLogger = logger;
17
17
 
@@ -473,6 +473,19 @@ export async function getBrowser(config, browserConfig) {
473
473
 
474
474
  return browser;
475
475
  }
476
+
477
+ async function updateStoryArgs(browser, story, updatedArgs) {
478
+ const Events = await importStorybookCoreEvents();
479
+ await browser.executeAsyncScript(function (storyId, updatedArgs, UPDATE_STORY_ARGS, STORY_RENDERED, callback) {
480
+ window.__STORYBOOK_ADDONS_CHANNEL__.once(STORY_RENDERED, callback);
481
+
482
+ window.__STORYBOOK_ADDONS_CHANNEL__.emit(UPDATE_STORY_ARGS, {
483
+ storyId,
484
+ updatedArgs
485
+ });
486
+ }, story.id, updatedArgs, Events.UPDATE_STORY_ARGS, Events.STORY_RENDERED);
487
+ }
488
+
476
489
  export async function switchStory() {
477
490
  var _this$currentTest, _this$currentTest$ctx, _parameters$creevey;
478
491
 
@@ -517,6 +530,8 @@ export async function switchStory() {
517
530
 
518
531
  this.takeScreenshot = () => takeScreenshot(this.browser, captureElement, ignoreElements);
519
532
 
533
+ this.updateStoryArgs = updatedArgs => updateStoryArgs(this.browser, story, updatedArgs);
534
+
520
535
  this.testScope.reverse();
521
536
  }
522
537
 
@@ -30,7 +30,7 @@ async function createSelenoidConfig(browsers, {
30
30
  selenoidConfig[browserName].versions[version] = {
31
31
  image: useDocker ? dockerImage : webdriverCommand,
32
32
  port: '4444',
33
- path: !useDocker || ['chrome', 'opera', 'webkit'].includes(browserName) ? '/' : '/wd/hub'
33
+ path: !useDocker || ['chrome', 'opera', 'webkit', 'MicrosoftEdge'].includes(browserName) ? '/' : '/wd/hub'
34
34
  };
35
35
  });
36
36
  await mkdirAsync(selenoidConfigDir, {