creevey 0.7.39 → 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 (109) hide show
  1. package/CHANGELOG.md +16 -2
  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/web/1.js +2 -2
  8. package/lib/cjs/client/web/2.js +1 -1
  9. package/lib/cjs/client/web/main.js +6 -6
  10. package/lib/cjs/server/loaders/babel/register.js +2 -1
  11. package/lib/cjs/server/selenium/selenoid.js +1 -1
  12. package/lib/cjs/server/stories.js +3 -15
  13. package/lib/cjs/server/storybook/entry.js +5 -4
  14. package/lib/cjs/server/storybook/helpers.js +11 -3
  15. package/lib/cjs/server/storybook/nodejs-provider.js +11 -6
  16. package/lib/cjs/server/utils.js +25 -2
  17. package/lib/cjs/shared.js +35 -0
  18. package/lib/esm/client/addon/Manager.js +3 -2
  19. package/lib/esm/client/addon/utils.js +1 -33
  20. package/lib/esm/server/loaders/babel/register.js +3 -2
  21. package/lib/esm/server/selenium/selenoid.js +1 -1
  22. package/lib/esm/server/stories.js +5 -16
  23. package/lib/esm/server/storybook/entry.js +4 -4
  24. package/lib/esm/server/storybook/helpers.js +9 -3
  25. package/lib/esm/server/storybook/nodejs-provider.js +12 -7
  26. package/lib/esm/server/utils.js +23 -1
  27. package/lib/esm/shared.js +22 -0
  28. package/lib/types/cli.d.ts +1 -1
  29. package/lib/types/client/addon/Manager.d.ts +37 -37
  30. package/lib/types/client/addon/components/Addon.d.ts +8 -8
  31. package/lib/types/client/addon/components/Icons.d.ts +7 -7
  32. package/lib/types/client/addon/components/Panel.d.ts +9 -9
  33. package/lib/types/client/addon/components/TestSelect.d.ts +9 -9
  34. package/lib/types/client/addon/components/Tools.d.ts +6 -6
  35. package/lib/types/client/addon/decorator.d.ts +1 -1
  36. package/lib/types/client/addon/preset.d.ts +22 -22
  37. package/lib/types/client/addon/register.d.ts +3 -3
  38. package/lib/types/client/addon/utils.d.ts +2 -6
  39. package/lib/types/client/addon/withCreevey.d.ts +13 -13
  40. package/lib/types/client/shared/components/ImagesView/BlendView.d.ts +3 -3
  41. package/lib/types/client/shared/components/ImagesView/ImagesView.d.ts +25 -25
  42. package/lib/types/client/shared/components/ImagesView/SideBySideView.d.ts +3 -3
  43. package/lib/types/client/shared/components/ImagesView/SlideView.d.ts +3 -3
  44. package/lib/types/client/shared/components/ImagesView/SwapView.d.ts +3 -3
  45. package/lib/types/client/shared/components/ImagesView/index.d.ts +5 -5
  46. package/lib/types/client/shared/components/PageFooter/PageFooter.d.ts +9 -9
  47. package/lib/types/client/shared/components/PageFooter/Paging.d.ts +8 -8
  48. package/lib/types/client/shared/components/PageHeader/ImagePreview.d.ts +12 -12
  49. package/lib/types/client/shared/components/PageHeader/PageHeader.d.ts +17 -17
  50. package/lib/types/client/shared/components/ResultsPage.d.ts +18 -18
  51. package/lib/types/client/shared/creeveyClientApi.d.ts +9 -9
  52. package/lib/types/client/shared/helpers.d.ts +46 -46
  53. package/lib/types/client/shared/viewMode.d.ts +4 -4
  54. package/lib/types/client/web/CreeveyApp.d.ts +12 -12
  55. package/lib/types/client/web/CreeveyContext.d.ts +11 -11
  56. package/lib/types/client/web/CreeveyLoader.d.ts +3 -3
  57. package/lib/types/client/web/CreeveyView/SideBar/Checkbox.d.ts +19 -19
  58. package/lib/types/client/web/CreeveyView/SideBar/Search.d.ts +6 -6
  59. package/lib/types/client/web/CreeveyView/SideBar/SideBar.d.ts +14 -14
  60. package/lib/types/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +13 -13
  61. package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +33 -33
  62. package/lib/types/client/web/CreeveyView/SideBar/TestLink.d.ts +8 -8
  63. package/lib/types/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +10 -10
  64. package/lib/types/client/web/CreeveyView/SideBar/TestsStatus.d.ts +9 -9
  65. package/lib/types/client/web/CreeveyView/SideBar/Toggle.d.ts +6 -6
  66. package/lib/types/client/web/CreeveyView/SideBar/index.d.ts +1 -1
  67. package/lib/types/client/web/KeyboardEventsContext.d.ts +13 -13
  68. package/lib/types/client/web/index.d.ts +4 -4
  69. package/lib/types/creevey.d.ts +1 -1
  70. package/lib/types/server/config.d.ts +4 -4
  71. package/lib/types/server/docker.d.ts +7 -7
  72. package/lib/types/server/extract.d.ts +2 -2
  73. package/lib/types/server/index.d.ts +2 -2
  74. package/lib/types/server/loaders/babel/creevey-plugin.d.ts +1 -1
  75. package/lib/types/server/loaders/babel/helpers.d.ts +19 -19
  76. package/lib/types/server/loaders/babel/register.d.ts +5 -5
  77. package/lib/types/server/loaders/hooks/mdx.d.ts +1 -1
  78. package/lib/types/server/loaders/hooks/svelte.d.ts +1 -1
  79. package/lib/types/server/loaders/webpack/compile.d.ts +2 -2
  80. package/lib/types/server/loaders/webpack/creevey-loader.d.ts +2 -2
  81. package/lib/types/server/loaders/webpack/dummy-hmr.d.ts +10 -10
  82. package/lib/types/server/loaders/webpack/mdx-loader.d.ts +6 -6
  83. package/lib/types/server/loaders/webpack/start.d.ts +1 -1
  84. package/lib/types/server/logger.d.ts +6 -6
  85. package/lib/types/server/master/api.d.ts +7 -7
  86. package/lib/types/server/master/index.d.ts +3 -3
  87. package/lib/types/server/master/master.d.ts +6 -6
  88. package/lib/types/server/master/pool.d.ts +30 -30
  89. package/lib/types/server/master/runner.d.ts +26 -26
  90. package/lib/types/server/master/server.d.ts +2 -2
  91. package/lib/types/server/messages.d.ts +18 -18
  92. package/lib/types/server/selenium/browser.d.ts +14 -14
  93. package/lib/types/server/selenium/index.d.ts +2 -2
  94. package/lib/types/server/selenium/selenoid.d.ts +3 -3
  95. package/lib/types/server/stories.d.ts +8 -9
  96. package/lib/types/server/storybook/entry.d.ts +18 -14
  97. package/lib/types/server/storybook/helpers.d.ts +24 -23
  98. package/lib/types/server/storybook/nodejs-provider.d.ts +5 -5
  99. package/lib/types/server/update.d.ts +2 -2
  100. package/lib/types/server/utils.d.ts +19 -18
  101. package/lib/types/server/worker/chai-image.d.ts +6 -6
  102. package/lib/types/server/worker/helpers.d.ts +7 -7
  103. package/lib/types/server/worker/index.d.ts +1 -1
  104. package/lib/types/server/worker/reporter.d.ts +8 -8
  105. package/lib/types/server/worker/worker.d.ts +4 -4
  106. package/lib/types/shared.d.ts +4 -0
  107. package/lib/types/types.d.ts +459 -459
  108. package/package.json +21 -17
  109. package/storybook-static/stories.json +0 -530
@@ -90,7 +90,8 @@ function getRequireContext(rootDir) {
90
90
  }
91
91
 
92
92
  async function register(config, debug = false) {
93
- const requireContext = getRequireContext(config.storybookDir);
93
+ const rootDir = (0, _helpers.isStorybookVersionLessThan)(6, 4) ? config.storybookDir : process.cwd();
94
+ const requireContext = getRequireContext(rootDir);
94
95
  const preview = (0, _path.resolve)(config.storybookDir, 'preview');
95
96
  if ((0, _helpers.hasDocsAddon)()) await (await Promise.resolve().then(() => _interopRequireWildcard(require('../hooks/mdx')))).addMDXHook(() => story);
96
97
  if ((0, _helpers.hasSvelteCSFAddon)()) await (await Promise.resolve().then(() => _interopRequireWildcard(require('../hooks/svelte')))).addSvelteHook(() => story); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
@@ -51,7 +51,7 @@ async function createSelenoidConfig(browsers, {
51
51
  selenoidConfig[browserName].versions[version] = {
52
52
  image: useDocker ? dockerImage : webdriverCommand,
53
53
  port: '4444',
54
- path: !useDocker || ['chrome', 'opera', 'webkit'].includes(browserName) ? '/' : '/wd/hub'
54
+ path: !useDocker || ['chrome', 'opera', 'webkit', 'MicrosoftEdge'].includes(browserName) ? '/' : '/wd/hub'
55
55
  };
56
56
  });
57
57
  await mkdirAsync(selenoidConfigDir, {
@@ -3,7 +3,6 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.flatStories = flatStories;
7
6
  exports.loadTestsFromStories = loadTestsFromStories;
8
7
  exports.saveStoriesJson = saveStoriesJson;
9
8
  exports.saveTestsJson = saveTestsJson;
@@ -22,6 +21,8 @@ var _utils = require("./utils");
22
21
 
23
22
  var _helpers = require("./storybook/helpers");
24
23
 
24
+ var _shared = require("../shared");
25
+
25
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
27
 
27
28
  function storyTestFabric(delay, testFn) {
@@ -94,19 +95,6 @@ function convertStories(browsers, stories) {
94
95
  });
95
96
  });
96
97
  return tests;
97
- } // TODO use the storybook version, after the fix of skip option API
98
-
99
-
100
- function flatStories({
101
- globalParameters,
102
- kindParameters,
103
- stories
104
- }) {
105
- Object.values(stories).forEach(story => {
106
- // NOTE: Copy-paste merge parameters from storybook
107
- story.parameters = (0, _lodash.mergeWith)({}, globalParameters, kindParameters[story.kind], story.parameters, (objValue, srcValue) => Array.isArray(objValue) ? objValue.concat(srcValue) : undefined);
108
- });
109
- return stories;
110
98
  }
111
99
 
112
100
  async function loadTestsFromStories(browsers, provider, update) {
@@ -125,7 +113,7 @@ async function loadTestsFromStories(browsers, provider, update) {
125
113
  });
126
114
  update === null || update === void 0 ? void 0 : update(testsDiff);
127
115
  });
128
- const stories = (0, _helpers.isStorybookVersionLessThan)(6) ? data.stories : flatStories(data);
116
+ const stories = (0, _helpers.isStorybookVersionLessThan)(6) || (0, _helpers.isStorybookVersionGreaterThan)(6, 3) ? data.stories : (0, _shared.denormalizeStoryParameters)(data);
129
117
  const tests = convertStories(browsers, stories);
130
118
  Object.values(tests).filter(_types.isDefined).forEach(({
131
119
  id,
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.raw = exports.getStorybook = exports.setAddon = exports.clearDecorators = exports.addParameters = exports.addDecorator = exports.configure = exports.storiesOf = exports.forceReRender = exports.clientApi = exports.channel = void 0;
7
7
 
8
+ var _addons = require("@storybook/addons");
9
+
8
10
  var _helpers = require("./helpers");
9
11
 
10
12
  var _api$channel, _api$context;
@@ -16,10 +18,8 @@ const core = require((0, _helpers.resolveFromStorybook)('@storybook/core')); //@
16
18
 
17
19
 
18
20
  const start = (0, _helpers.isStorybookVersionLessThan)(6, 2) ? core.default.start : core.start;
19
- const api = start(() => void 0); //@ts-expect-error: 6.x has { channel }, but 5.x has { context: { channel } }
20
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
21
-
22
- const channel = (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel;
21
+ const api = start(() => void 0);
22
+ const channel = (0, _helpers.isStorybookVersionLessThan)(6, 4) ? (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel : _addons.addons.getChannel();
23
23
  exports.channel = channel;
24
24
  const clientApi = api.clientApi;
25
25
  exports.clientApi = clientApi;
@@ -38,6 +38,7 @@ const configure = (...args) => {
38
38
  if ((0, _helpers.isStorybookVersionLessThan)(5, 2)) {
39
39
  //NOTE: Storybook <= 5.1 pass args as is
40
40
  //@ts-expect-error: ignore it
41
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
41
42
  return api.configApi.configure(...args);
42
43
  }
43
44
 
@@ -7,6 +7,7 @@ exports.hasDocsAddon = hasDocsAddon;
7
7
  exports.hasSvelteCSFAddon = hasSvelteCSFAddon;
8
8
  exports.getStorybookVersion = getStorybookVersion;
9
9
  exports.isStorybookVersionLessThan = isStorybookVersionLessThan;
10
+ exports.isStorybookVersionGreaterThan = isStorybookVersionGreaterThan;
10
11
  exports.isStorybookVersion = isStorybookVersion;
11
12
  exports.getStorybookFramework = getStorybookFramework;
12
13
  exports.importStorybookConfig = importStorybookConfig;
@@ -97,17 +98,24 @@ function isStorybookVersionLessThan(major, minor) {
97
98
  return Number(sbMajor) < major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) < minor;
98
99
  }
99
100
 
100
- function isStorybookVersion(major, minor) {
101
+ function isStorybookVersionGreaterThan(major, minor) {
101
102
  var _process$env$__CREEVE2;
102
103
 
103
104
  const [sbMajor, sbMinor] = ((_process$env$__CREEVE2 = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE2 !== void 0 ? _process$env$__CREEVE2 : getStorybookVersion()).split('.');
105
+ return Number(sbMajor) > major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) > minor;
106
+ }
107
+
108
+ function isStorybookVersion(major, minor) {
109
+ var _process$env$__CREEVE3;
110
+
111
+ const [sbMajor, sbMinor] = ((_process$env$__CREEVE3 = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE3 !== void 0 ? _process$env$__CREEVE3 : getStorybookVersion()).split('.');
104
112
  return Number(sbMajor) == major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) == minor;
105
113
  }
106
114
 
107
115
  function getStorybookFramework() {
108
- var _process$env$__CREEVE3;
116
+ var _process$env$__CREEVE4;
109
117
 
110
- const framework = (_process$env$__CREEVE3 = process.env.__CREEVEY_STORYBOOK_FRAMEWORK__) !== null && _process$env$__CREEVE3 !== void 0 ? _process$env$__CREEVE3 : supportedFrameworks.find(framework => {
118
+ const framework = (_process$env$__CREEVE4 = process.env.__CREEVEY_STORYBOOK_FRAMEWORK__) !== null && _process$env$__CREEVE4 !== void 0 ? _process$env$__CREEVE4 : supportedFrameworks.find(framework => {
111
119
  try {
112
120
  return require.resolve(resolveFromStorybook(`@storybook/${framework}`));
113
121
  } catch (_) {
@@ -21,7 +21,7 @@ var _helpers = require("./helpers");
21
21
 
22
22
  var _logger = require("../logger");
23
23
 
24
- var _stories = require("../stories");
24
+ var _shared = require("../../shared");
25
25
 
26
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
27
 
@@ -59,7 +59,7 @@ function watchStories(channel, watcher, initialFiles) {
59
59
  watcher.on('change', filePath => storiesByFiles.set(_path.default.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
60
60
  watcher.on('unlink', filePath => storiesByFiles.set(_path.default.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
61
61
  return data => {
62
- const stories = (0, _helpers.isStorybookVersionLessThan)(6) ? data.stories : (0, _stories.flatStories)(data);
62
+ const stories = (0, _helpers.isStorybookVersionLessThan)(6) || (0, _helpers.isStorybookVersionGreaterThan)(6, 3) ? data.stories : (0, _shared.denormalizeStoryParameters)(data);
63
63
  const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
64
64
  const addedFiles = Array.from(files).filter(filePath => !watchingFiles.has(filePath));
65
65
  const removedFiles = Array.from(watchingFiles).filter(filePath => !files.has(filePath));
@@ -104,7 +104,8 @@ async function loadStoriesDirectly(config, {
104
104
  debug
105
105
  }) {
106
106
  const {
107
- toRequireContext
107
+ toRequireContext,
108
+ normalizeStoriesEntry
108
109
  } = await (0, _helpers.importStorybookCoreCommon)();
109
110
  const {
110
111
  addParameters,
@@ -123,12 +124,16 @@ async function loadStoriesDirectly(config, {
123
124
  const {
124
125
  stories
125
126
  } = await (0, _helpers.importStorybookConfig)();
126
- const contexts = stories.map(input => {
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
+ });
127
132
  const {
128
133
  path: storiesPath,
129
134
  recursive,
130
135
  match
131
- } = toRequireContext(input);
136
+ } = toRequireContext(normalizedEntry);
132
137
  watcher === null || watcher === void 0 ? void 0 : watcher.add(_path.default.resolve(config.storybookDir, storiesPath));
133
138
  return () => requireContext(storiesPath, recursive, new RegExp(match));
134
139
  });
@@ -201,7 +206,7 @@ async function loadStories(config, {
201
206
  });
202
207
  const loadPromise = new Promise(resolve => {
203
208
  channel.once(Events.SET_STORIES, data => {
204
- const stories = (0, _helpers.isStorybookVersionLessThan)(6) ? data.stories : (0, _stories.flatStories)(data);
209
+ const stories = (0, _helpers.isStorybookVersionLessThan)(6) || (0, _helpers.isStorybookVersionGreaterThan)(6, 3) ? data.stories : (0, _shared.denormalizeStoryParameters)(data);
205
210
  const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
206
211
  if (watcher) channel.on(Events.SET_STORIES, watchStories(channel, watcher, files));
207
212
  resolve(data);
@@ -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,
@@ -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
+ }
@@ -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
@@ -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, {
@@ -1,10 +1,11 @@
1
1
  import path from 'path';
2
2
  import { mkdirSync, writeFileSync } from 'fs';
3
3
  import { createHash } from 'crypto';
4
- import { mapValues, mergeWith, pick } from 'lodash';
4
+ import { mapValues, pick } from 'lodash';
5
5
  import { isDefined, isFunction, isObject } from '../types';
6
6
  import { shouldSkip, removeProps } from './utils';
7
- import { isStorybookVersionLessThan } from './storybook/helpers';
7
+ import { isStorybookVersionGreaterThan, isStorybookVersionLessThan } from './storybook/helpers';
8
+ import { denormalizeStoryParameters } from '../shared';
8
9
 
9
10
  function storyTestFabric(delay, testFn) {
10
11
  return async function storyTest() {
@@ -76,20 +77,8 @@ function convertStories(browsers, stories) {
76
77
  });
77
78
  });
78
79
  return tests;
79
- } // TODO use the storybook version, after the fix of skip option API
80
-
81
-
82
- export function flatStories({
83
- globalParameters,
84
- kindParameters,
85
- stories
86
- }) {
87
- Object.values(stories).forEach(story => {
88
- // NOTE: Copy-paste merge parameters from storybook
89
- story.parameters = mergeWith({}, globalParameters, kindParameters[story.kind], story.parameters, (objValue, srcValue) => Array.isArray(objValue) ? objValue.concat(srcValue) : undefined);
90
- });
91
- return stories;
92
80
  }
81
+
93
82
  export async function loadTestsFromStories(browsers, provider, update) {
94
83
  const testIdsByFiles = new Map();
95
84
  const data = await provider(storiesByFiles => {
@@ -106,7 +95,7 @@ export async function loadTestsFromStories(browsers, provider, update) {
106
95
  });
107
96
  update === null || update === void 0 ? void 0 : update(testsDiff);
108
97
  });
109
- const stories = isStorybookVersionLessThan(6) ? data.stories : flatStories(data);
98
+ const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
110
99
  const tests = convertStories(browsers, stories);
111
100
  Object.values(tests).filter(isDefined).forEach(({
112
101
  id,
@@ -1,5 +1,6 @@
1
1
  var _api$channel, _api$context;
2
2
 
3
+ import { addons } from '@storybook/addons';
3
4
  import { getStorybookFramework, isStorybookVersionLessThan, resolveFromStorybook } from './helpers';
4
5
  const framework = getStorybookFramework(); // eslint-disable-next-line @typescript-eslint/no-var-requires
5
6
 
@@ -8,10 +9,8 @@ const core = require(resolveFromStorybook('@storybook/core')); //@ts-expect-erro
8
9
 
9
10
 
10
11
  const start = isStorybookVersionLessThan(6, 2) ? core.default.start : core.start;
11
- const api = start(() => void 0); //@ts-expect-error: 6.x has { channel }, but 5.x has { context: { channel } }
12
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
13
-
14
- export const channel = (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel;
12
+ const api = start(() => void 0);
13
+ export const channel = isStorybookVersionLessThan(6, 4) ? (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel : addons.getChannel();
15
14
  export const clientApi = api.clientApi;
16
15
  export const forceReRender = api.forceReRender;
17
16
  export const storiesOf = (kind, m) => {
@@ -23,6 +22,7 @@ export const configure = (...args) => {
23
22
  if (isStorybookVersionLessThan(5, 2)) {
24
23
  //NOTE: Storybook <= 5.1 pass args as is
25
24
  //@ts-expect-error: ignore it
25
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
26
26
  return api.configApi.configure(...args);
27
27
  }
28
28
 
@@ -45,16 +45,22 @@ export function isStorybookVersionLessThan(major, minor) {
45
45
  const [sbMajor, sbMinor] = ((_process$env$__CREEVE = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE !== void 0 ? _process$env$__CREEVE : getStorybookVersion()).split('.');
46
46
  return Number(sbMajor) < major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) < minor;
47
47
  }
48
- export function isStorybookVersion(major, minor) {
48
+ export function isStorybookVersionGreaterThan(major, minor) {
49
49
  var _process$env$__CREEVE2;
50
50
 
51
51
  const [sbMajor, sbMinor] = ((_process$env$__CREEVE2 = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE2 !== void 0 ? _process$env$__CREEVE2 : getStorybookVersion()).split('.');
52
+ return Number(sbMajor) > major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) > minor;
53
+ }
54
+ export function isStorybookVersion(major, minor) {
55
+ var _process$env$__CREEVE3;
56
+
57
+ const [sbMajor, sbMinor] = ((_process$env$__CREEVE3 = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE3 !== void 0 ? _process$env$__CREEVE3 : getStorybookVersion()).split('.');
52
58
  return Number(sbMajor) == major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) == minor;
53
59
  }
54
60
  export function getStorybookFramework() {
55
- var _process$env$__CREEVE3;
61
+ var _process$env$__CREEVE4;
56
62
 
57
- const framework = (_process$env$__CREEVE3 = process.env.__CREEVEY_STORYBOOK_FRAMEWORK__) !== null && _process$env$__CREEVE3 !== void 0 ? _process$env$__CREEVE3 : supportedFrameworks.find(framework => {
63
+ const framework = (_process$env$__CREEVE4 = process.env.__CREEVEY_STORYBOOK_FRAMEWORK__) !== null && _process$env$__CREEVE4 !== void 0 ? _process$env$__CREEVE4 : supportedFrameworks.find(framework => {
58
64
  try {
59
65
  return require.resolve(resolveFromStorybook(`@storybook/${framework}`));
60
66
  } catch (_) {
@@ -5,9 +5,9 @@ import chokidar from 'chokidar';
5
5
  import { noop } from '../../types';
6
6
  import { getCreeveyCache } from '../utils';
7
7
  import { subscribeOn } from '../messages';
8
- import { importStorybookClientLogger, importStorybookConfig, importStorybookCoreCommon, importStorybookCoreEvents, isStorybookVersionLessThan } from './helpers';
8
+ import { importStorybookClientLogger, importStorybookConfig, importStorybookCoreCommon, importStorybookCoreEvents, isStorybookVersionGreaterThan, isStorybookVersionLessThan } from './helpers';
9
9
  import { logger } from '../logger';
10
- import { flatStories } from '../stories';
10
+ import { denormalizeStoryParameters } from '../../shared';
11
11
 
12
12
  async function initStorybookEnvironment() {
13
13
  // @ts-ignore
@@ -39,7 +39,7 @@ function watchStories(channel, watcher, initialFiles) {
39
39
  watcher.on('change', filePath => storiesByFiles.set(path.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
40
40
  watcher.on('unlink', filePath => storiesByFiles.set(path.isAbsolute(filePath) ? filePath : `./${filePath.replace(/\\/g, '/')}`, []));
41
41
  return data => {
42
- const stories = isStorybookVersionLessThan(6) ? data.stories : flatStories(data);
42
+ const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
43
43
  const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
44
44
  const addedFiles = Array.from(files).filter(filePath => !watchingFiles.has(filePath));
45
45
  const removedFiles = Array.from(watchingFiles).filter(filePath => !files.has(filePath));
@@ -84,7 +84,8 @@ async function loadStoriesDirectly(config, {
84
84
  debug
85
85
  }) {
86
86
  const {
87
- toRequireContext
87
+ toRequireContext,
88
+ normalizeStoriesEntry
88
89
  } = await importStorybookCoreCommon();
89
90
  const {
90
91
  addParameters,
@@ -103,12 +104,16 @@ async function loadStoriesDirectly(config, {
103
104
  const {
104
105
  stories
105
106
  } = await importStorybookConfig();
106
- const contexts = stories.map(input => {
107
+ const contexts = stories.map(entry => {
108
+ const normalizedEntry = isStorybookVersionLessThan(6, 4) ? entry : normalizeStoriesEntry(entry, {
109
+ configDir: config.storybookDir,
110
+ workingDir: process.cwd()
111
+ });
107
112
  const {
108
113
  path: storiesPath,
109
114
  recursive,
110
115
  match
111
- } = toRequireContext(input);
116
+ } = toRequireContext(normalizedEntry);
112
117
  watcher === null || watcher === void 0 ? void 0 : watcher.add(path.resolve(config.storybookDir, storiesPath));
113
118
  return () => requireContext(storiesPath, recursive, new RegExp(match));
114
119
  });
@@ -181,7 +186,7 @@ export async function loadStories(config, {
181
186
  });
182
187
  const loadPromise = new Promise(resolve => {
183
188
  channel.once(Events.SET_STORIES, data => {
184
- const stories = isStorybookVersionLessThan(6) ? data.stories : flatStories(data);
189
+ const stories = isStorybookVersionLessThan(6) || isStorybookVersionGreaterThan(6, 3) ? data.stories : denormalizeStoryParameters(data);
185
190
  const files = new Set(Object.values(stories).map(story => story.parameters.fileName));
186
191
  if (watcher) channel.on(Events.SET_STORIES, watchStories(channel, watcher, files));
187
192
  resolve(data);
@@ -9,6 +9,7 @@ export const isShuttingDown = {
9
9
  };
10
10
  export const LOCALHOST_REGEXP = /(localhost|127\.0\.0\.1)/i;
11
11
  export const extensions = ['.js', '.jsx', '.ts', '.tsx'];
12
+ export const skipOptionKeys = ['in', 'kinds', 'stories', 'tests', 'reason'];
12
13
 
13
14
  function matchBy(pattern, value) {
14
15
  return typeof pattern == 'string' && pattern == value || Array.isArray(pattern) && pattern.includes(value) || pattern instanceof RegExp && pattern.test(value) || !isDefined(pattern);
@@ -20,9 +21,30 @@ export function shouldSkip(browser, meta, skipOptions, test) {
20
21
  }
21
22
 
22
23
  if (Array.isArray(skipOptions)) {
23
- return skipOptions.map(skipOption => shouldSkip(browser, meta, skipOption, test)).find(Boolean) || false;
24
+ for (const skip of skipOptions) {
25
+ const reason = shouldSkip(browser, meta, skip, test);
26
+ if (reason) return reason;
27
+ }
28
+
29
+ return false;
30
+ }
31
+
32
+ let hasSkipOptionKeys = false;
33
+
34
+ for (const skipKey in skipOptions) {
35
+ if (skipOptionKeys.includes(skipKey)) {
36
+ hasSkipOptionKeys = true;
37
+ continue;
38
+ }
39
+
40
+ const reason = shouldSkip(browser, meta, {
41
+ reason: skipKey,
42
+ ...skipOptions[skipKey]
43
+ }, test);
44
+ if (reason) return reason;
24
45
  }
25
46
 
47
+ if (!hasSkipOptionKeys) return false;
26
48
  const {
27
49
  in: browsers,
28
50
  kinds,
@@ -0,0 +1,22 @@
1
+ import { mapValues, mergeWith } from 'lodash';
2
+ // NOTE: Copy-paste from storybook/api
3
+ export const combineParameters = (...parameterSets) => // eslint-disable-next-line @typescript-eslint/no-unsafe-return
4
+ mergeWith({}, ...parameterSets, (_, srcValue) => {
5
+ // Treat arrays as scalars:
6
+ if (Array.isArray(srcValue)) return srcValue;
7
+ return undefined;
8
+ }); // NOTE: Copy-paste from storybook/api
9
+
10
+ export const denormalizeStoryParameters = ({
11
+ globalParameters,
12
+ kindParameters,
13
+ stories
14
+ }) => {
15
+ return mapValues(stories, storyData => {
16
+ var _kindParameters$story;
17
+
18
+ return { ...storyData,
19
+ parameters: combineParameters(globalParameters, (_kindParameters$story = kindParameters[storyData.kind]) !== null && _kindParameters$story !== void 0 ? _kindParameters$story : {}, storyData.parameters)
20
+ };
21
+ });
22
+ };
@@ -1 +1 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node