@applitools/eyes-storybook 3.26.1 → 3.27.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 +5 -0
- package/README.md +3 -13
- package/package.json +1 -1
- package/src/addVariationStories.js +104 -0
- package/src/eyesStorybook.js +4 -4
- package/src/getStoryBaselineName.js +9 -3
- package/src/getStoryData.js +22 -23
- package/src/getStoryTitle.js +3 -4
- package/src/getStoryUrl.js +6 -3
- package/src/renderStory.js +6 -6
- package/src/addParametrizedStories.js +0 -81
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -28,7 +28,6 @@ Applitools Eyes SDK for [Storybook](http://storybook.js.org).
|
|
|
28
28
|
- [global](#global)
|
|
29
29
|
- [component](#component)
|
|
30
30
|
- [`variations`](#variations)
|
|
31
|
-
- [`queryParams`](#queryparams)
|
|
32
31
|
- [`waitBeforeCapture`](#waitbeforecapture)
|
|
33
32
|
- [`properties`](#properties)
|
|
34
33
|
- [`ignoreRegions`](#ignoreregions)
|
|
@@ -181,7 +180,6 @@ In addition to command-line arguments, it's possible to define the following con
|
|
|
181
180
|
| `waitBeforeCapture` | undefined | Selector, function or timeout.<br/>If ```number``` then the argument is treated as time in milliseconds to wait before all screenshots.<br/>If ```string``` then the argument is treated as a selector for elements to wait for before all screenshots.<br/>If ```function```, then the argument is treated as a predicate to wait for before all screenshots.<br/><hr/>For per component configuration see [waitBeforeCapture.](#waitBeforeCapture)<br/>Note that we use Puppeteer's [page.waitForTimeout()](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagewaitfortimeoutmilliseconds), [page.waitForSelector()](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagewaitforselectorselector-options), [page.waitForXPath()](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagewaitforxpathxpath-options) and [page.waitForFunction()](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagewaitforfunctionpagefunction-options-args), checkout it's API for more details. |
|
|
182
181
|
| `include` | true | A predicate function, a string or a regular expression specifying which stories should be visually tested.<br/>Visual baselines will be created only for the components specified.<br/>The function receives an object with ```name```, ```kind```, ```storyTitle``` and ```parameters``` properties.<br/>For example (exclude all stories with a name that start with [SKIP]):<br/>```({name, kind, storyTitle, parameters}) => !/^\[SKIP\]/.test(name)```<br/>For more information, see [per component configuration - include](#include). |
|
|
183
182
|
| `variations` | undefined | Specifies additional variations for all or some of the stories. For example, RTL. For more information, see [per component configuration - variations](#variations).|
|
|
184
|
-
| `queryParam` | undefined | Specifies additional query parameters for all or some of the stories. For more information, see [per component configuration - queryParams](#queryParams).|
|
|
185
183
|
| `notifyOnCompletion` | false | If `true` batch completion notifications are sent. |
|
|
186
184
|
| `dontCloseBatches` | false | If true, batches are not closed for notifyOnCompletion.|
|
|
187
185
|
| `testConcurrency` | 5 | The maximum number of tests that can run concurrently. The default value is the allowed amount for free accounts. For paid accounts, set this number to the quota set for your account. |
|
|
@@ -425,10 +423,9 @@ storiesOf('Some kind', module)
|
|
|
425
423
|
|
|
426
424
|
### `variations`
|
|
427
425
|
|
|
428
|
-
An array of
|
|
426
|
+
An array of object values, which specifies which variations to add for this story. For each value, an additional visual test will be executed for the component. Each variation could contain `queryParams` and `properties` fields to specifies custom query parameters and eyes properties respectfully. Variation tests will have the same name.
|
|
429
427
|
|
|
430
|
-
This can accommodate many use cases, for example
|
|
431
|
-
It's now possible for the component to render its variation version when the relevant URL param is present. For Example, here's a storybook that handles an RTL variation:
|
|
428
|
+
This can accommodate many use cases, for example `@storybook/addon-contexts`. With addons like this it is possible to render components in a different way depends on query parameters in URL. For Example, here's a storybook that handles an RTL variation:
|
|
432
429
|
|
|
433
430
|
```js
|
|
434
431
|
const isRTL = new URL(window.location).searchParams.get('eyes-variation') === 'RTL';
|
|
@@ -445,17 +442,10 @@ storiesOf('Components that support RTL', module)
|
|
|
445
442
|
<span>I am visually perfect!</span>
|
|
446
443
|
<span>{isRTL ? ' and rendered right to left as well :)' : ''}</span>
|
|
447
444
|
</div>,
|
|
448
|
-
{eyes: {variations: ['RTL']}}
|
|
445
|
+
{eyes: {variations: [{queryParams: {'eyes-variation': 'RTL'}, properties: {name: 'isRTL', value: 'true'}, {properties: {name: 'isRTL', value: 'false'}}]}}
|
|
449
446
|
)
|
|
450
447
|
```
|
|
451
448
|
|
|
452
|
-
### `queryParams`
|
|
453
|
-
|
|
454
|
-
An array of object values, which specifies `name` and `value` of query parameter which will be added to the story. For each value, an additional visual test will be executed for the component. It will have the same name display name, but still generate a different baseline.
|
|
455
|
-
|
|
456
|
-
This can accommodate many use cases, for example `@storybook/addon-contexts`.
|
|
457
|
-
With addons like this it is possible to render components in a different way depends on query parameters in URL.
|
|
458
|
-
|
|
459
449
|
### `waitBeforeCapture`
|
|
460
450
|
|
|
461
451
|
Selector or timeout, see [advanced configuration](#advanced-configuration) for more details.
|
package/package.json
CHANGED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function addVariationStories({stories, config}) {
|
|
4
|
+
const defaultStories = [];
|
|
5
|
+
const variationStories = {};
|
|
6
|
+
for (const story of stories) {
|
|
7
|
+
const variations = getStoryVariations(story, config);
|
|
8
|
+
if (variations) {
|
|
9
|
+
for (const variation of variations) {
|
|
10
|
+
const variationKey = stringifyVariation(variation);
|
|
11
|
+
const variationStoriesArray =
|
|
12
|
+
variationStories[variationKey] || (variationStories[variationKey] = []);
|
|
13
|
+
const variationStory = {...story};
|
|
14
|
+
if (variation.queryParams || variation.properties) {
|
|
15
|
+
variationStory.parameters = addVariation(story.parameters, variation);
|
|
16
|
+
}
|
|
17
|
+
variationStoriesArray.push(variationStory);
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
defaultStories.push(story);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return Object.values(variationStories).reduce((allStories, variationStories) => {
|
|
25
|
+
return allStories.concat(variationStories);
|
|
26
|
+
}, defaultStories);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getStoryVariations(story, config) {
|
|
30
|
+
if (story.parameters && story.parameters.eyes && story.parameters.eyes.variations) {
|
|
31
|
+
if (!Array.isArray(story.parameters.eyes.variations)) {
|
|
32
|
+
throw new Error('variations should be an array');
|
|
33
|
+
}
|
|
34
|
+
return normalizeVariations(story.parameters.eyes.variations);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (config.variations) {
|
|
38
|
+
if (Array.isArray(config.variations)) {
|
|
39
|
+
return normalizeVariations(config.variations);
|
|
40
|
+
} else if (typeof config.variations === 'function') {
|
|
41
|
+
const variations = config.variations(story);
|
|
42
|
+
if (variations) {
|
|
43
|
+
if (!Array.isArray(variations)) {
|
|
44
|
+
throw new Error('global variations should be a function that returns array');
|
|
45
|
+
}
|
|
46
|
+
return normalizeVariations(variations);
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
throw new Error('global variations should be an array or a function that returns array');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizeVariations(variations) {
|
|
55
|
+
let shouldHasDefault = false; // default variation is one without query params
|
|
56
|
+
const normalizedVariations = variations.map(variation => {
|
|
57
|
+
if (typeof variation === 'string') {
|
|
58
|
+
shouldHasDefault = true;
|
|
59
|
+
return {
|
|
60
|
+
queryParams: {'eyes-variation': variation},
|
|
61
|
+
properties: [{name: 'eyes-variation', value: variation}],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (variation.queryParams && (!variation.properties || variation.properties.length === 0)) {
|
|
65
|
+
return {
|
|
66
|
+
...variation,
|
|
67
|
+
properties: Object.entries(variation.queryParams).map(([name, value]) => ({name, value})),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return variation;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// if it should has default variation and it is not already there
|
|
74
|
+
if (shouldHasDefault && !normalizedVariations.some(variation => !variation.queryParams)) {
|
|
75
|
+
normalizedVariations.unshift({});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return normalizedVariations;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function stringifyVariation(variation) {
|
|
82
|
+
if (!variation.queryParams) return '';
|
|
83
|
+
return Object.keys(variation.queryParams)
|
|
84
|
+
.sort()
|
|
85
|
+
.map(name => `${name}=${variation.queryParams[name]}`)
|
|
86
|
+
.join('&');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function addVariation(parameters, variation) {
|
|
90
|
+
parameters = {...parameters};
|
|
91
|
+
parameters.eyes = {...parameters.eyes};
|
|
92
|
+
if (variation.queryParams) {
|
|
93
|
+
parameters.eyes.queryParams = variation.queryParams;
|
|
94
|
+
}
|
|
95
|
+
if (variation.properties) {
|
|
96
|
+
parameters.eyes.properties = [
|
|
97
|
+
...(parameters.eyes.properties || []),
|
|
98
|
+
...(variation.properties || []),
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
return parameters;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
module.exports = addVariationStories;
|
package/src/eyesStorybook.js
CHANGED
|
@@ -10,7 +10,7 @@ const makeRenderStories = require('./renderStories');
|
|
|
10
10
|
const makeGetStoryData = require('./getStoryData');
|
|
11
11
|
const ora = require('ora');
|
|
12
12
|
const filterStories = require('./filterStories');
|
|
13
|
-
const
|
|
13
|
+
const addVariationStories = require('./addVariationStories');
|
|
14
14
|
const browserLog = require('./browserLog');
|
|
15
15
|
const memoryLog = require('./memoryLog');
|
|
16
16
|
const getIframeUrl = require('./getIframeUrl');
|
|
@@ -116,12 +116,12 @@ async function eyesStorybook({
|
|
|
116
116
|
);
|
|
117
117
|
|
|
118
118
|
const filteredStories = filterStories({stories, config});
|
|
119
|
-
const
|
|
119
|
+
const storiesIncludingVariations = addVariationStories({
|
|
120
120
|
stories: filteredStories,
|
|
121
121
|
config,
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
-
logger.log(`starting to run ${
|
|
124
|
+
logger.log(`starting to run ${storiesIncludingVariations.length} stories`);
|
|
125
125
|
|
|
126
126
|
const getStoryData = makeGetStoryData({
|
|
127
127
|
logger,
|
|
@@ -158,7 +158,7 @@ async function eyesStorybook({
|
|
|
158
158
|
setRenderIE,
|
|
159
159
|
setTransitioningIntoIE,
|
|
160
160
|
configs,
|
|
161
|
-
stories:
|
|
161
|
+
stories: storiesIncludingVariations,
|
|
162
162
|
pagePool,
|
|
163
163
|
logger,
|
|
164
164
|
timeItAsync,
|
|
@@ -3,11 +3,17 @@ const getStoryTitle = require('./getStoryTitle');
|
|
|
3
3
|
|
|
4
4
|
function getStoryBaselineName({name, kind, parameters}) {
|
|
5
5
|
const storyTitle = getStoryTitle({name, kind, parameters});
|
|
6
|
-
const
|
|
6
|
+
const queryParams = parameters && parameters.eyes && parameters.eyes.queryParams;
|
|
7
|
+
if (!queryParams) return storyTitle;
|
|
8
|
+
const customQueryParams = {...queryParams};
|
|
9
|
+
delete customQueryParams['eyes-variation'];
|
|
10
|
+
if (Object.keys(customQueryParams).length === 0) return storyTitle;
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
const queryParamsString = Object.entries(customQueryParams)
|
|
13
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
14
|
+
.join('&');
|
|
9
15
|
|
|
10
|
-
return `${storyTitle} [${
|
|
16
|
+
return `${storyTitle} [${queryParamsString}]`;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
module.exports = getStoryBaselineName;
|
package/src/getStoryData.js
CHANGED
|
@@ -15,19 +15,9 @@ function makeGetStoryData({logger, takeDomSnapshots, waitBeforeCapture, reloadPa
|
|
|
15
15
|
|
|
16
16
|
const eyesParameters = story.parameters && story.parameters.eyes;
|
|
17
17
|
if (story.isApi && !reloadPagePerStory) {
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
? eyesParameters.queryParams.map(queryParam => queryParam.name)
|
|
22
|
-
: undefined,
|
|
23
|
-
);
|
|
24
|
-
if (
|
|
25
|
-
(!actualQueryParam && !expectedQueryParam) ||
|
|
26
|
-
(actualQueryParam &&
|
|
27
|
-
expectedQueryParam &&
|
|
28
|
-
actualQueryParam.value === expectedQueryParam.name &&
|
|
29
|
-
actualQueryParam.value === expectedQueryParam.value)
|
|
30
|
-
) {
|
|
18
|
+
const currentUrl = page.url();
|
|
19
|
+
const expectedQueryParams = eyesParameters ? eyesParameters.queryParams : undefined;
|
|
20
|
+
if (urlQueryParamsEquals(currentUrl, expectedQueryParams)) {
|
|
31
21
|
const err = await page.evaluate(renderStoryWithClientAPI, story.index);
|
|
32
22
|
err && handleRenderStoryError(err);
|
|
33
23
|
} else {
|
|
@@ -84,19 +74,28 @@ function makeGetStoryData({logger, takeDomSnapshots, waitBeforeCapture, reloadPa
|
|
|
84
74
|
}
|
|
85
75
|
}
|
|
86
76
|
|
|
87
|
-
|
|
77
|
+
function urlQueryParamsEquals(url, expectedQueryParams) {
|
|
88
78
|
try {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
url = new URL(url);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
logger.error('Error during parsing page url', err);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
expectedQueryParams = expectedQueryParams || {};
|
|
86
|
+
const expectedQueryParamNames = Object.keys(expectedQueryParams);
|
|
87
|
+
const actualQueryParamNames = [];
|
|
88
|
+
for (const [name, value] of url.searchParams) {
|
|
89
|
+
if (['eyes-storybook', 'selectedKind', 'selectedStory'].includes(name)) continue;
|
|
90
|
+
if (!expectedQueryParams.hasOwnProperty(name) || !expectedQueryParams[name] === value) {
|
|
91
|
+
return false;
|
|
96
92
|
}
|
|
97
|
-
|
|
98
|
-
logger.log('failed to get url from page (in need of eyes-variation param)');
|
|
93
|
+
actualQueryParamNames.push(name);
|
|
99
94
|
}
|
|
95
|
+
|
|
96
|
+
if (actualQueryParamNames.length !== expectedQueryParamNames.length) return false;
|
|
97
|
+
|
|
98
|
+
return true;
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
// TODO (amit): handle this error in the caller (probably renderStories)
|
package/src/getStoryTitle.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function getStoryTitle({name, kind, parameters}) {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
queryParam && queryParam.name === 'eyes-variation' ? queryParam.value : undefined;
|
|
4
|
+
const queryParams = (parameters && parameters.eyes && parameters.eyes.queryParams) || {};
|
|
5
|
+
const eyesVariation = queryParams['eyes-variation'];
|
|
7
6
|
|
|
8
|
-
return `${kind}: ${name}${
|
|
7
|
+
return `${kind}: ${name}${eyesVariation ? ` [${eyesVariation}]` : ''}`;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
module.exports = getStoryTitle;
|
package/src/getStoryUrl.js
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
const getIframeUrl = require('./getIframeUrl');
|
|
3
3
|
|
|
4
4
|
function getStoryUrl({name, kind, parameters}, baseUrl) {
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const queryParams = (parameters && parameters.eyes && parameters.eyes.queryParams) || {};
|
|
6
|
+
const queryString = Object.entries(queryParams).reduce(
|
|
7
|
+
(queryString, [name, value]) => queryString + `&${name}=${value}`,
|
|
8
|
+
'',
|
|
9
|
+
);
|
|
7
10
|
|
|
8
11
|
return `${getIframeUrl(baseUrl)}&selectedKind=${encodeURIComponent(
|
|
9
12
|
kind,
|
|
10
|
-
)}&selectedStory=${encodeURIComponent(name)}${
|
|
13
|
+
)}&selectedStory=${encodeURIComponent(name)}${queryString}`;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
module.exports = getStoryUrl;
|
package/src/renderStory.js
CHANGED
|
@@ -8,7 +8,12 @@ function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
|
|
|
8
8
|
const {name, kind, parameters} = story;
|
|
9
9
|
const baselineName = getStoryBaselineName({name, kind, parameters});
|
|
10
10
|
const title = getStoryTitle({name, kind, parameters});
|
|
11
|
-
const
|
|
11
|
+
const eyesParameters = (parameters && parameters.eyes) || {};
|
|
12
|
+
const eyesOptions = {
|
|
13
|
+
...config,
|
|
14
|
+
...eyesParameters,
|
|
15
|
+
properties: [...(config.properties || []), ...(eyesParameters.properties || [])],
|
|
16
|
+
};
|
|
12
17
|
const {
|
|
13
18
|
ignoreDisplacements,
|
|
14
19
|
ignoreRegions,
|
|
@@ -31,7 +36,6 @@ function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
|
|
|
31
36
|
visualGridOptions,
|
|
32
37
|
useDom,
|
|
33
38
|
enablePatterns,
|
|
34
|
-
queryParam,
|
|
35
39
|
} = eyesOptions;
|
|
36
40
|
|
|
37
41
|
if (sizeMode) {
|
|
@@ -52,10 +56,6 @@ function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
|
|
|
52
56
|
...(properties || []),
|
|
53
57
|
];
|
|
54
58
|
|
|
55
|
-
if (queryParam) {
|
|
56
|
-
storyProperties.push(queryParam);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
59
|
const openParams = {
|
|
60
60
|
testName: baselineName,
|
|
61
61
|
displayName: title,
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function addParametrizedStories({stories, config}) {
|
|
4
|
-
const parametrizedStories = {};
|
|
5
|
-
for (const story of stories) {
|
|
6
|
-
const queryParams = getStoryQueryParams(story, config);
|
|
7
|
-
if (!queryParams) continue;
|
|
8
|
-
for (const queryParam of queryParams) {
|
|
9
|
-
const queryParamString = `${queryParam.name}=${queryParam.value}`;
|
|
10
|
-
const parametrizeStoriesArray =
|
|
11
|
-
parametrizedStories[queryParamString] || (parametrizedStories[queryParamString] = []);
|
|
12
|
-
parametrizeStoriesArray.push({
|
|
13
|
-
...story,
|
|
14
|
-
parameters: addQueryParam(story.parameters, queryParam),
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return Object.values(parametrizedStories).reduce((allStories, parametrizedStories) => {
|
|
20
|
-
return allStories.concat(parametrizedStories);
|
|
21
|
-
}, stories);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function getStoryQueryParams(story, config) {
|
|
25
|
-
let queryParams;
|
|
26
|
-
if (story.parameters && story.parameters.eyes && story.parameters.eyes.queryParams) {
|
|
27
|
-
if (!Array.isArray(story.parameters.eyes.queryParams)) {
|
|
28
|
-
throw new Error('queryParams should be an array');
|
|
29
|
-
}
|
|
30
|
-
queryParams = [...story.parameters.eyes.queryParams];
|
|
31
|
-
}
|
|
32
|
-
if (story.parameters && story.parameters.eyes && story.parameters.eyes.variations) {
|
|
33
|
-
if (!Array.isArray(story.parameters.eyes.variations)) {
|
|
34
|
-
throw new Error('variations should be an array');
|
|
35
|
-
}
|
|
36
|
-
queryParams = [
|
|
37
|
-
...(queryParams || []),
|
|
38
|
-
...variationsToQueryParams(story.parameters.eyes.variations),
|
|
39
|
-
];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (queryParams) return queryParams;
|
|
43
|
-
|
|
44
|
-
if (config.queryParams) {
|
|
45
|
-
if (!Array.isArray(config.queryParams)) {
|
|
46
|
-
throw new Error('global queryParams should be an array');
|
|
47
|
-
}
|
|
48
|
-
queryParams = [...config.queryParams];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (config.variations) {
|
|
52
|
-
if (Array.isArray(config.variations)) {
|
|
53
|
-
queryParams = [...(queryParams || []), ...variationsToQueryParams(config.variations)];
|
|
54
|
-
} else if (typeof config.variations === 'function') {
|
|
55
|
-
const variations = config.variations(story);
|
|
56
|
-
if (variations) {
|
|
57
|
-
if (!Array.isArray(variations)) {
|
|
58
|
-
throw new Error('global variations should be a function that returns array');
|
|
59
|
-
}
|
|
60
|
-
queryParams = [...(queryParams || []), ...variationsToQueryParams(variations)];
|
|
61
|
-
}
|
|
62
|
-
} else {
|
|
63
|
-
throw new Error('global variations should be an array or a function that returns array');
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (queryParams) return queryParams;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function variationsToQueryParams(variations) {
|
|
71
|
-
return variations.map(variation => ({name: 'eyes-variation', value: variation}));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function addQueryParam(parameters, queryParam) {
|
|
75
|
-
parameters = {...parameters};
|
|
76
|
-
parameters.eyes = {...parameters.eyes};
|
|
77
|
-
parameters.eyes.queryParam = queryParam;
|
|
78
|
-
return parameters;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
module.exports = addParametrizedStories;
|