@applitools/eyes-storybook 3.25.2 → 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 +23 -0
- package/README.md +3 -4
- package/package.json +10 -8
- package/src/addVariationStories.js +84 -34
- package/src/eyesStorybook.js +27 -9
- package/src/getStoryBaselineName.js +19 -0
- package/src/getStoryData.js +29 -17
- package/src/getStoryTitle.js +3 -3
- package/src/getStoryUrl.js +6 -3
- package/src/renderStories.js +7 -4
- package/src/renderStory.js +20 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,29 @@
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
## 3.27.0 - 2021/12/6
|
|
7
|
+
|
|
8
|
+
- support custom properties and query params
|
|
9
|
+
- remove `queryParams` api from story and global config
|
|
10
|
+
|
|
11
|
+
## 3.26.1 - 2021/11/28
|
|
12
|
+
|
|
13
|
+
- add custom test properties to stories with query params
|
|
14
|
+
|
|
15
|
+
## 3.26.0 - 2021/11/26
|
|
16
|
+
|
|
17
|
+
- add support for `queryParams` config property
|
|
18
|
+
- updated to @applitools/driver@1.3.5 (from 1.2.7)
|
|
19
|
+
- updated to @applitools/eyes-puppeteer@1.9.0 (from 1.8.5)
|
|
20
|
+
- updated to @applitools/eyes-sdk-core@12.24.5 (from 12.23.24)
|
|
21
|
+
- updated to @applitools/logger@1.0.6 (from 1.0.5)
|
|
22
|
+
- updated to @applitools/test-server@1.0.7 (from 1.0.6)
|
|
23
|
+
- updated to @applitools/visual-grid-client@15.8.49 (from 15.8.43)
|
|
24
|
+
|
|
25
|
+
## 3.25.3 - 2021/11/1
|
|
26
|
+
|
|
27
|
+
- add a retry mechanism for cases we get 0 stories
|
|
28
|
+
|
|
6
29
|
## 3.25.2 - 2021/10/30
|
|
7
30
|
|
|
8
31
|
- replace legacy logger construction with new
|
package/README.md
CHANGED
|
@@ -423,10 +423,9 @@ storiesOf('Some kind', module)
|
|
|
423
423
|
|
|
424
424
|
### `variations`
|
|
425
425
|
|
|
426
|
-
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.
|
|
427
427
|
|
|
428
|
-
This can accommodate many use cases, for example
|
|
429
|
-
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:
|
|
430
429
|
|
|
431
430
|
```js
|
|
432
431
|
const isRTL = new URL(window.location).searchParams.get('eyes-variation') === 'RTL';
|
|
@@ -443,7 +442,7 @@ storiesOf('Components that support RTL', module)
|
|
|
443
442
|
<span>I am visually perfect!</span>
|
|
444
443
|
<span>{isRTL ? ' and rendered right to left as well :)' : ''}</span>
|
|
445
444
|
</div>,
|
|
446
|
-
{eyes: {variations: ['RTL']}}
|
|
445
|
+
{eyes: {variations: [{queryParams: {'eyes-variation': 'RTL'}, properties: {name: 'isRTL', value: 'true'}, {properties: {name: 'isRTL', value: 'false'}}]}}
|
|
447
446
|
)
|
|
448
447
|
```
|
|
449
448
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/eyes-storybook",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.27.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=8.6.0"
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
"storybook": "start-storybook -c test/fixtures/appWithStorybook -p 9001 -s test/fixtures",
|
|
26
26
|
"storybook:jslayout": "start-storybook -c test/fixtures/jsLayoutStorybookLocal -p 9001 -s test/fixtures",
|
|
27
27
|
"storybook:heavy": "start-storybook -c test/fixtures/heavyStorybook -p 9002 -s test/fixtures",
|
|
28
|
+
"storybook:zeroStories": "start-storybook -c test/fixtures/zeroStoriesRetry -p 9003 -s test/fixtures",
|
|
28
29
|
"eyes-storybook": "node bin/eyes-storybook.js -f test/fixtures/applitools.config.js",
|
|
29
30
|
"eyes-storybook:jslayout": "node bin/eyes-storybook.js -f test/e2e/happy-config/layout-breakpoints-local.config.js",
|
|
30
31
|
"eyes-storybook:heavy": "node bin/eyes-storybook.js -f test/fixtures/heavyStorybook/applitools.config.js",
|
|
31
32
|
"eyes-storybook:configured": "node bin/eyes-storybook.js -f scripts/preconfigured.config.js",
|
|
33
|
+
"eyes-storybook:zeroStories": "node bin/eyes-storybook.js -f test/fixtures/zeroStoriesRetry/applitools.config.js",
|
|
32
34
|
"changelog": "git changelog -x -p -f v$npm_package_version > History.md && git add ./History.md && git commit -am 'changelog'",
|
|
33
35
|
"changelog:init": "git config changelog.format \"* %s [[%h]($(echo $npm_package_repository_url|cut -d+ -f2|cut -d. -f1-2)/commit/%H)]\"",
|
|
34
36
|
"changelog:install": "sudo apt-get install git-extras",
|
|
@@ -56,14 +58,14 @@
|
|
|
56
58
|
"directory": "packages/eyes-storybook"
|
|
57
59
|
},
|
|
58
60
|
"dependencies": {
|
|
59
|
-
"@applitools/driver": "1.
|
|
60
|
-
"@applitools/eyes-
|
|
61
|
-
"@applitools/eyes-sdk-core": "12.23.24",
|
|
61
|
+
"@applitools/driver": "1.3.5",
|
|
62
|
+
"@applitools/eyes-sdk-core": "12.24.5",
|
|
62
63
|
"@applitools/functional-commons": "1.6.0",
|
|
63
|
-
"@applitools/logger": "1.0.
|
|
64
|
+
"@applitools/logger": "1.0.6",
|
|
64
65
|
"@applitools/monitoring-commons": "1.0.19",
|
|
65
|
-
"@applitools/
|
|
66
|
-
"@applitools/
|
|
66
|
+
"@applitools/spec-driver-puppeteer": "1.1.0",
|
|
67
|
+
"@applitools/test-server": "1.0.7",
|
|
68
|
+
"@applitools/visual-grid-client": "15.8.49",
|
|
67
69
|
"boxen": "4.2.0",
|
|
68
70
|
"chalk": "3.0.0",
|
|
69
71
|
"detect-port": "1.3.0",
|
|
@@ -77,7 +79,7 @@
|
|
|
77
79
|
"devDependencies": {
|
|
78
80
|
"@applitools/scripts": "^1.0.1",
|
|
79
81
|
"@applitools/sdk-release-kit": "0.13.4",
|
|
80
|
-
"@applitools/sdk-shared": "0.9.
|
|
82
|
+
"@applitools/sdk-shared": "0.9.9",
|
|
81
83
|
"@applitools/snaptdout": "^1.0.1",
|
|
82
84
|
"@applitools/utils": "1.2.4",
|
|
83
85
|
"@storybook/addon-options": "^5.2.8",
|
|
@@ -1,54 +1,104 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function addVariationStories({stories, config}) {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
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
|
+
}
|
|
8
23
|
|
|
9
|
-
|
|
24
|
+
return Object.values(variationStories).reduce((allStories, variationStories) => {
|
|
25
|
+
return allStories.concat(variationStories);
|
|
26
|
+
}, defaultStories);
|
|
27
|
+
}
|
|
10
28
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (!Array.isArray(variations)) {
|
|
29
|
+
function getStoryVariations(story, config) {
|
|
30
|
+
if (story.parameters && story.parameters.eyes && story.parameters.eyes.variations) {
|
|
31
|
+
if (!Array.isArray(story.parameters.eyes.variations)) {
|
|
14
32
|
throw new Error('variations should be an array');
|
|
15
33
|
}
|
|
34
|
+
return normalizeVariations(story.parameters.eyes.variations);
|
|
35
|
+
}
|
|
16
36
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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');
|
|
23
50
|
}
|
|
24
51
|
}
|
|
52
|
+
}
|
|
25
53
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
+
};
|
|
33
63
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
+
};
|
|
37
69
|
}
|
|
70
|
+
return variation;
|
|
71
|
+
});
|
|
38
72
|
|
|
39
|
-
|
|
73
|
+
// if it should has default variation and it is not already there
|
|
74
|
+
if (shouldHasDefault && !normalizedVariations.some(variation => !variation.queryParams)) {
|
|
75
|
+
normalizedVariations.unshift({});
|
|
40
76
|
}
|
|
77
|
+
|
|
78
|
+
return normalizedVariations;
|
|
41
79
|
}
|
|
42
80
|
|
|
43
|
-
function
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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;
|
|
52
102
|
}
|
|
53
103
|
|
|
54
104
|
module.exports = addVariationStories;
|
package/src/eyesStorybook.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const puppeteer = require('puppeteer');
|
|
3
3
|
const getStories = require('../dist/getStories');
|
|
4
4
|
const {makeVisualGridClient} = require('@applitools/visual-grid-client');
|
|
5
|
-
const {presult} = require('@applitools/functional-commons');
|
|
5
|
+
const {presult, delay} = require('@applitools/functional-commons');
|
|
6
6
|
const chalk = require('./chalkify');
|
|
7
7
|
const makeInitPage = require('./initPage');
|
|
8
8
|
const makeRenderStory = require('./renderStory');
|
|
@@ -18,12 +18,14 @@ const createPagePool = require('./pagePool');
|
|
|
18
18
|
const getClientAPI = require('../dist/getClientAPI');
|
|
19
19
|
const {takeDomSnapshots} = require('@applitools/eyes-sdk-core');
|
|
20
20
|
const {Driver} = require('@applitools/driver');
|
|
21
|
-
const spec = require('@applitools/
|
|
21
|
+
const spec = require('@applitools/spec-driver-puppeteer');
|
|
22
22
|
const {refineErrorMessage} = require('./errMessages');
|
|
23
23
|
const {splitConfigsByBrowser} = require('./shouldRenderIE');
|
|
24
24
|
const executeRenders = require('./executeRenders');
|
|
25
25
|
|
|
26
26
|
const CONCURRENT_PAGES = 3;
|
|
27
|
+
const MAX_RETRIES = 10;
|
|
28
|
+
const RETRY_INTERVAL = 1000;
|
|
27
29
|
|
|
28
30
|
async function eyesStorybook({
|
|
29
31
|
config,
|
|
@@ -76,14 +78,14 @@ async function eyesStorybook({
|
|
|
76
78
|
});
|
|
77
79
|
const pagePool = createPagePool({initPage, logger});
|
|
78
80
|
|
|
79
|
-
const doTakeDomSnapshots = async ({page, layoutBreakpoints, waitBeforeCapture}) => {
|
|
80
|
-
const driver = new Driver({spec, driver: page, logger});
|
|
81
|
+
const doTakeDomSnapshots = async ({page, browser, layoutBreakpoints, waitBeforeCapture}) => {
|
|
82
|
+
const driver = await new Driver({spec, driver: page, logger}).init();
|
|
81
83
|
const skipResources = getResourceUrlsInCache();
|
|
82
84
|
const result = await takeDomSnapshots({
|
|
83
85
|
logger,
|
|
84
86
|
driver,
|
|
85
87
|
breakpoints: layoutBreakpoints !== undefined ? layoutBreakpoints : config.layoutBreakpoints,
|
|
86
|
-
browsers:
|
|
88
|
+
browsers: browser || [true], // this is a hack, since takeDomSnapshots expects an array. And VGC has a default in case browser is not specified. So we just need an array with length of 1 here.
|
|
87
89
|
skipResources,
|
|
88
90
|
showLogs: !!config.showLogs,
|
|
89
91
|
disableBrowserFetching: !!config.disableBrowserFetching,
|
|
@@ -114,7 +116,10 @@ async function eyesStorybook({
|
|
|
114
116
|
);
|
|
115
117
|
|
|
116
118
|
const filteredStories = filterStories({stories, config});
|
|
117
|
-
const storiesIncludingVariations = addVariationStories({
|
|
119
|
+
const storiesIncludingVariations = addVariationStories({
|
|
120
|
+
stories: filteredStories,
|
|
121
|
+
config,
|
|
122
|
+
});
|
|
118
123
|
|
|
119
124
|
logger.log(`starting to run ${storiesIncludingVariations.length} stories`);
|
|
120
125
|
|
|
@@ -203,9 +208,9 @@ async function eyesStorybook({
|
|
|
203
208
|
spinner.fail(failMsg);
|
|
204
209
|
throw new Error();
|
|
205
210
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
211
|
+
|
|
212
|
+
const [getStoriesErr, stories] = await readStoriesWithRetry(MAX_RETRIES);
|
|
213
|
+
|
|
209
214
|
if (getStoriesErr) {
|
|
210
215
|
logger.log('Error in getStories:', getStoriesErr);
|
|
211
216
|
const failMsg = refineErrorMessage({
|
|
@@ -257,6 +262,19 @@ async function eyesStorybook({
|
|
|
257
262
|
function getTransitiongIntoIE() {
|
|
258
263
|
return transitioning;
|
|
259
264
|
}
|
|
265
|
+
|
|
266
|
+
async function readStoriesWithRetry(remainingRetries) {
|
|
267
|
+
const [getStoriesErr, stories] = await presult(
|
|
268
|
+
page.evaluate(getStories, {timeout: readStoriesTimeout}),
|
|
269
|
+
);
|
|
270
|
+
if (getStoriesErr || stories.length > 0 || remainingRetries == 0) {
|
|
271
|
+
return [getStoriesErr, stories];
|
|
272
|
+
} else {
|
|
273
|
+
logger.log(`Got 0 stories, retrying to read stories... ${remainingRetries - 1} are left`);
|
|
274
|
+
await delay(RETRY_INTERVAL);
|
|
275
|
+
return await readStoriesWithRetry(remainingRetries - 1);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
260
278
|
}
|
|
261
279
|
|
|
262
280
|
module.exports = eyesStorybook;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const getStoryTitle = require('./getStoryTitle');
|
|
3
|
+
|
|
4
|
+
function getStoryBaselineName({name, kind, parameters}) {
|
|
5
|
+
const storyTitle = getStoryTitle({name, kind, parameters});
|
|
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;
|
|
11
|
+
|
|
12
|
+
const queryParamsString = Object.entries(customQueryParams)
|
|
13
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
14
|
+
.join('&');
|
|
15
|
+
|
|
16
|
+
return `${storyTitle} [${queryParamsString}]`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = getStoryBaselineName;
|
package/src/getStoryData.js
CHANGED
|
@@ -3,26 +3,21 @@ const {presult} = require('@applitools/functional-commons');
|
|
|
3
3
|
const {ArgumentGuard} = require('@applitools/eyes-sdk-core');
|
|
4
4
|
const renderStoryWithClientAPI = require('../dist/renderStoryWithClientAPI');
|
|
5
5
|
const runRunBeforeScript = require('../dist/runRunBeforeScript');
|
|
6
|
-
const
|
|
6
|
+
const getStoryBaselineName = require('./getStoryBaselineName');
|
|
7
7
|
const {URL} = require('url');
|
|
8
8
|
const runRunAfterScript = require('../dist/runRunAfterScript');
|
|
9
9
|
const waitFor = require('./waitFor');
|
|
10
10
|
|
|
11
11
|
function makeGetStoryData({logger, takeDomSnapshots, waitBeforeCapture, reloadPagePerStory}) {
|
|
12
|
-
return async function getStoryData({story, storyUrl, page, waitBeforeStory}) {
|
|
13
|
-
const title =
|
|
12
|
+
return async function getStoryData({story, storyUrl, page, browser, waitBeforeStory}) {
|
|
13
|
+
const title = getStoryBaselineName(story);
|
|
14
14
|
logger.log(`getting data from story`, title);
|
|
15
15
|
|
|
16
16
|
const eyesParameters = story.parameters && story.parameters.eyes;
|
|
17
17
|
if (story.isApi && !reloadPagePerStory) {
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
: undefined;
|
|
22
|
-
if (
|
|
23
|
-
(!actualVariationParam && !expectedVariationUrlParam) ||
|
|
24
|
-
actualVariationParam === expectedVariationUrlParam
|
|
25
|
-
) {
|
|
18
|
+
const currentUrl = page.url();
|
|
19
|
+
const expectedQueryParams = eyesParameters ? eyesParameters.queryParams : undefined;
|
|
20
|
+
if (urlQueryParamsEquals(currentUrl, expectedQueryParams)) {
|
|
26
21
|
const err = await page.evaluate(renderStoryWithClientAPI, story.index);
|
|
27
22
|
err && handleRenderStoryError(err);
|
|
28
23
|
} else {
|
|
@@ -49,8 +44,9 @@ function makeGetStoryData({logger, takeDomSnapshots, waitBeforeCapture, reloadPa
|
|
|
49
44
|
|
|
50
45
|
logger.log(`running takeDomSnapshot(s) for story ${title}`);
|
|
51
46
|
|
|
52
|
-
const
|
|
47
|
+
const result = await takeDomSnapshots({
|
|
53
48
|
page,
|
|
49
|
+
browser,
|
|
54
50
|
layoutBreakpoints: eyesParameters ? eyesParameters.layoutBreakpoints : undefined,
|
|
55
51
|
waitBeforeCapture: wait
|
|
56
52
|
? async () => {
|
|
@@ -67,7 +63,7 @@ function makeGetStoryData({logger, takeDomSnapshots, waitBeforeCapture, reloadPa
|
|
|
67
63
|
}
|
|
68
64
|
|
|
69
65
|
logger.log(`done getting data from story`, title);
|
|
70
|
-
return
|
|
66
|
+
return result;
|
|
71
67
|
|
|
72
68
|
async function renderStoryLegacy() {
|
|
73
69
|
logger.log(`getting data from story ${storyUrl}`);
|
|
@@ -78,12 +74,28 @@ function makeGetStoryData({logger, takeDomSnapshots, waitBeforeCapture, reloadPa
|
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
76
|
|
|
81
|
-
|
|
77
|
+
function urlQueryParamsEquals(url, expectedQueryParams) {
|
|
82
78
|
try {
|
|
83
|
-
|
|
84
|
-
} catch (
|
|
85
|
-
logger.
|
|
79
|
+
url = new URL(url);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
logger.error('Error during parsing page url', err);
|
|
82
|
+
return false;
|
|
86
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;
|
|
92
|
+
}
|
|
93
|
+
actualQueryParamNames.push(name);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (actualQueryParamNames.length !== expectedQueryParamNames.length) return false;
|
|
97
|
+
|
|
98
|
+
return true;
|
|
87
99
|
}
|
|
88
100
|
|
|
89
101
|
// TODO (amit): handle this error in the caller (probably renderStories)
|
package/src/getStoryTitle.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
function getStoryTitle({name, kind, parameters}) {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const queryParams = (parameters && parameters.eyes && parameters.eyes.queryParams) || {};
|
|
5
|
+
const eyesVariation = queryParams['eyes-variation'];
|
|
6
6
|
|
|
7
|
-
return `${kind}: ${name}${
|
|
7
|
+
return `${kind}: ${name}${eyesVariation ? ` [${eyesVariation}]` : ''}`;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
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/renderStories.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const getStoryUrl = require('./getStoryUrl');
|
|
3
|
-
const
|
|
3
|
+
const getStoryBaselineName = require('./getStoryBaselineName');
|
|
4
4
|
const ora = require('ora');
|
|
5
5
|
const {presult} = require('@applitools/functional-commons');
|
|
6
6
|
const {shouldRenderIE} = require('./shouldRenderIE');
|
|
@@ -61,7 +61,7 @@ function makeRenderStories({
|
|
|
61
61
|
async function processStory() {
|
|
62
62
|
const story = stories[currIndex++];
|
|
63
63
|
const storyUrl = getStoryUrl(story, storybookUrl);
|
|
64
|
-
const title =
|
|
64
|
+
const title = getStoryBaselineName(story);
|
|
65
65
|
const {waitBeforeCapture} = (story.parameters && story.parameters.eyes) || {};
|
|
66
66
|
|
|
67
67
|
try {
|
|
@@ -69,6 +69,7 @@ function makeRenderStories({
|
|
|
69
69
|
getStoryData({
|
|
70
70
|
story,
|
|
71
71
|
storyUrl,
|
|
72
|
+
browser: config.browser,
|
|
72
73
|
page,
|
|
73
74
|
waitBeforeStory: waitBeforeCapture,
|
|
74
75
|
}),
|
|
@@ -89,6 +90,7 @@ function makeRenderStories({
|
|
|
89
90
|
getStoryData({
|
|
90
91
|
story,
|
|
91
92
|
storyUrl,
|
|
93
|
+
browser: config.browser,
|
|
92
94
|
page: newPageObj.page,
|
|
93
95
|
waitBeforeStory: waitBeforeCapture,
|
|
94
96
|
}),
|
|
@@ -107,7 +109,8 @@ function makeRenderStories({
|
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
const testResults = await renderStory({
|
|
110
|
-
snapshot: storyData,
|
|
112
|
+
snapshot: storyData.snapshots,
|
|
113
|
+
cookies: storyData.cookies,
|
|
111
114
|
url: storyUrl,
|
|
112
115
|
story,
|
|
113
116
|
config,
|
|
@@ -139,7 +142,7 @@ function makeRenderStories({
|
|
|
139
142
|
|
|
140
143
|
function onDoneStory(resultsOrErr, story) {
|
|
141
144
|
spinner.text = updateSpinnerText(++doneStories, stories.length);
|
|
142
|
-
const title =
|
|
145
|
+
const title = getStoryBaselineName(story);
|
|
143
146
|
allTestResults.push({title, resultsOrErr});
|
|
144
147
|
return {title, resultsOrErr};
|
|
145
148
|
}
|
package/src/renderStory.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const getStoryTitle = require('./getStoryTitle');
|
|
3
|
+
const getStoryBaselineName = require('./getStoryBaselineName');
|
|
3
4
|
const {deprecationWarning} = require('@applitools/eyes-sdk-core').GeneralUtils;
|
|
4
5
|
|
|
5
6
|
function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
|
|
6
7
|
return function renderStory({config, story, snapshot, url}) {
|
|
7
8
|
const {name, kind, parameters} = story;
|
|
9
|
+
const baselineName = getStoryBaselineName({name, kind, parameters});
|
|
8
10
|
const title = getStoryTitle({name, kind, parameters});
|
|
9
|
-
const
|
|
11
|
+
const eyesParameters = (parameters && parameters.eyes) || {};
|
|
12
|
+
const eyesOptions = {
|
|
13
|
+
...config,
|
|
14
|
+
...eyesParameters,
|
|
15
|
+
properties: [...(config.properties || []), ...(eyesParameters.properties || [])],
|
|
16
|
+
};
|
|
10
17
|
const {
|
|
11
18
|
ignoreDisplacements,
|
|
12
19
|
ignoreRegions,
|
|
@@ -41,16 +48,19 @@ function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
|
|
|
41
48
|
ignoreRegionsBackCompat = ignore;
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
logger.log(
|
|
51
|
+
logger.log(`running story ${title} with baseline ${baselineName}`);
|
|
52
|
+
|
|
53
|
+
const storyProperties = [
|
|
54
|
+
{name: 'Component name', value: kind},
|
|
55
|
+
{name: 'State', value: name},
|
|
56
|
+
...(properties || []),
|
|
57
|
+
];
|
|
45
58
|
|
|
46
59
|
const openParams = {
|
|
47
|
-
testName:
|
|
60
|
+
testName: baselineName,
|
|
61
|
+
displayName: title,
|
|
48
62
|
browser: config.browser,
|
|
49
|
-
properties:
|
|
50
|
-
{name: 'Component name', value: kind},
|
|
51
|
-
{name: 'State', value: name},
|
|
52
|
-
...(properties || []),
|
|
53
|
-
],
|
|
63
|
+
properties: storyProperties,
|
|
54
64
|
accessibilitySettings: accessibilityValidation,
|
|
55
65
|
};
|
|
56
66
|
|
|
@@ -77,12 +87,12 @@ function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
|
|
|
77
87
|
ignoreDisplacements,
|
|
78
88
|
};
|
|
79
89
|
|
|
80
|
-
return timeItAsync(
|
|
90
|
+
return timeItAsync(baselineName, async () => {
|
|
81
91
|
return testWindow({openParams, checkParams, throwEx: false});
|
|
82
92
|
}).then(onDoneStory);
|
|
83
93
|
|
|
84
94
|
function onDoneStory(results) {
|
|
85
|
-
logger.log('finished story',
|
|
95
|
+
logger.log('finished story', baselineName, 'in', performance[baselineName]);
|
|
86
96
|
return results;
|
|
87
97
|
}
|
|
88
98
|
};
|