@applitools/eyes-storybook 3.53.7 → 3.53.9
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 +31 -0
- package/package.json +10 -10
- package/src/eyesStorybook.js +42 -14
- package/src/pagePool.js +34 -12
- package/src/renderStories.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.53.9](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.53.8...js/eyes-storybook@3.53.9) (2025-02-23)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* page pool hang ([#2803](https://github.com/Applitools-Dev/sdk/issues/2803)) ([249043a](https://github.com/Applitools-Dev/sdk/commit/249043a4a31b358cbc3a06728d0fc493156d3c83))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* @applitools/ufg-client bumped to 1.16.5
|
|
14
|
+
#### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* fix offline - url was replaced before resource fetched for url resources ([#2802](https://github.com/Applitools-Dev/sdk/issues/2802)) ([a67f86a](https://github.com/Applitools-Dev/sdk/commit/a67f86aabd56c59fb6cfa58578b1e8b3c31d2197))
|
|
17
|
+
* @applitools/core bumped to 4.31.3
|
|
18
|
+
#### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* fix offline - url was replaced before resource fetched for url resources ([#2802](https://github.com/Applitools-Dev/sdk/issues/2802)) ([a67f86a](https://github.com/Applitools-Dev/sdk/commit/a67f86aabd56c59fb6cfa58578b1e8b3c31d2197))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
* @applitools/eyes bumped to 1.32.2
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## [3.53.8](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.53.7...js/eyes-storybook@3.53.8) (2025-02-11)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
* add logs to page sanity check ([#2783](https://github.com/Applitools-Dev/sdk/issues/2783)) ([056c5bc](https://github.com/Applitools-Dev/sdk/commit/056c5bc0b91babd82a406e1ef57ca7ded8dcffdd))
|
|
33
|
+
|
|
3
34
|
## [3.53.7](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.53.6...js/eyes-storybook@3.53.7) (2025-02-10)
|
|
4
35
|
|
|
5
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/eyes-storybook",
|
|
3
|
-
"version": "3.53.
|
|
3
|
+
"version": "3.53.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"applitools",
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"build": "rollup -c rollup.config.js",
|
|
26
26
|
"build:heavy": "node scripts/bitmap.js",
|
|
27
27
|
"test": "yarn build && yarn test:mocha",
|
|
28
|
-
"test:mocha": "run --top-level mocha
|
|
29
|
-
"test:unit": "run --top-level mocha
|
|
30
|
-
"test:it": "run --top-level mocha
|
|
28
|
+
"test:mocha": "run --top-level mocha 'test/{unit,it,e2e}/*.test.js'",
|
|
29
|
+
"test:unit": "run --top-level mocha 'test/unit/*.test.js'",
|
|
30
|
+
"test:it": "run --top-level mocha 'test/it/*.test.js'",
|
|
31
31
|
"test:versions": "yarn build && yarn test:e2e:versions && yarn lint",
|
|
32
|
-
"test:e2e": "MOCHA_GROUP=e2e run --top-level mocha
|
|
33
|
-
"test:e2e:versions": "MOCHA_GROUP=e2e_versions run --top-level mocha
|
|
34
|
-
"test:sanity": "run --top-level mocha
|
|
32
|
+
"test:e2e": "MOCHA_GROUP=e2e run --top-level mocha 'test/e2e/*.e2e.test.js'",
|
|
33
|
+
"test:e2e:versions": "MOCHA_GROUP=e2e_versions run --top-level mocha test/versions/*.e2e.versions.test.js",
|
|
34
|
+
"test:sanity": "run --top-level mocha 'test/sanity/*.test.js'",
|
|
35
35
|
"test:heavy": "node bin/eyes-storybook.js -f test/fixtures/heavyStorybook/applitools.config.js",
|
|
36
36
|
"storybook": "start-storybook -c test/fixtures/appWithStorybook -p 9001 -s test/fixtures",
|
|
37
37
|
"storybook:httpHeaders": "start-storybook -c test/fixtures/appWithCustomHttpHeaders -p 9007",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"up:framework": "cd test/fixtures/storybook-versions/${APPLITOOLS_FRAMEWORK_VERSION} && npm ci"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@applitools/core": "4.31.
|
|
56
|
+
"@applitools/core": "4.31.3",
|
|
57
57
|
"@applitools/driver": "1.20.4",
|
|
58
|
-
"@applitools/eyes": "1.32.
|
|
58
|
+
"@applitools/eyes": "1.32.2",
|
|
59
59
|
"@applitools/functional-commons": "1.6.0",
|
|
60
60
|
"@applitools/logger": "2.1.0",
|
|
61
61
|
"@applitools/monitoring-commons": "1.0.19",
|
|
62
62
|
"@applitools/spec-driver-puppeteer": "1.4.24",
|
|
63
|
-
"@applitools/ufg-client": "1.16.
|
|
63
|
+
"@applitools/ufg-client": "1.16.5",
|
|
64
64
|
"@applitools/utils": "1.7.7",
|
|
65
65
|
"boxen": "4.2.0",
|
|
66
66
|
"chalk": "3.0.0",
|
package/src/eyesStorybook.js
CHANGED
|
@@ -45,6 +45,7 @@ async function eyesStorybook({
|
|
|
45
45
|
let iframeUrl;
|
|
46
46
|
try {
|
|
47
47
|
iframeUrl = getIframeUrl(storybookUrl);
|
|
48
|
+
logger.log('iframeUrl:', iframeUrl);
|
|
48
49
|
} catch (ex) {
|
|
49
50
|
logger.log(ex);
|
|
50
51
|
throw new Error(`Storybook URL is not valid: ${storybookUrl}`);
|
|
@@ -118,13 +119,6 @@ async function eyesStorybook({
|
|
|
118
119
|
try {
|
|
119
120
|
const stories = await getStoriesWithSpinner();
|
|
120
121
|
|
|
121
|
-
await Promise.all(
|
|
122
|
-
Array.from({length: CONCURRENT_TABS}, async () => {
|
|
123
|
-
const {pageId} = await pagePool.createPage();
|
|
124
|
-
pagePool.addToPool(pageId);
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
127
|
-
|
|
128
122
|
const filteredStories = filterStories({stories, config});
|
|
129
123
|
const storiesIncludingVariations = addVariationStories({
|
|
130
124
|
stories: filteredStories,
|
|
@@ -173,6 +167,8 @@ async function eyesStorybook({
|
|
|
173
167
|
|
|
174
168
|
logger.log('finished creating functions');
|
|
175
169
|
|
|
170
|
+
await initializeTabs();
|
|
171
|
+
|
|
176
172
|
const [error, results] = await presult(
|
|
177
173
|
executeRenders({
|
|
178
174
|
renderStories,
|
|
@@ -307,22 +303,54 @@ async function eyesStorybook({
|
|
|
307
303
|
}
|
|
308
304
|
}
|
|
309
305
|
|
|
310
|
-
async function sanityCheckForPage(page) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
306
|
+
async function sanityCheckForPage({page, pageId}) {
|
|
307
|
+
try {
|
|
308
|
+
await executeWithRetry(_sanityCheckForPage, {
|
|
309
|
+
timeout: readStoriesTimeout,
|
|
310
|
+
delayBetweenRetries: 1000,
|
|
311
|
+
initialErrMessage: `Could not get client API in sanity check since readStoriesTimeout is too short (${readStoriesTimeout}ms)`,
|
|
312
|
+
});
|
|
313
|
+
} catch (err) {
|
|
314
|
+
logger.log(`[page ${pageId}] Sanity check failed. Getting page HTML for inspection`);
|
|
315
|
+
try {
|
|
316
|
+
const html = await page.content();
|
|
317
|
+
logger.log(`[page ${pageId}] Page HTML: ${html}`);
|
|
318
|
+
} catch (htmlErr) {
|
|
319
|
+
logger.log(`[page ${pageId}] Error getting page HTML:`, htmlErr);
|
|
320
|
+
}
|
|
321
|
+
throw err;
|
|
322
|
+
}
|
|
316
323
|
|
|
317
324
|
async function _sanityCheckForPage() {
|
|
318
325
|
try {
|
|
319
326
|
await page.evaluate(getClientAPI);
|
|
320
327
|
} catch (err) {
|
|
321
|
-
logger.log(
|
|
328
|
+
logger.log(`[page ${pageId}] Error in getClientAPI during sanity check. Retrying...`, err);
|
|
322
329
|
throw err;
|
|
323
330
|
}
|
|
324
331
|
}
|
|
325
332
|
}
|
|
333
|
+
|
|
334
|
+
async function initializeTabs() {
|
|
335
|
+
logger.log('initializing tabs');
|
|
336
|
+
try {
|
|
337
|
+
await Promise.all(
|
|
338
|
+
Array.from({length: CONCURRENT_TABS}, async () => {
|
|
339
|
+
const {page, pageId} = await pagePool.createPage();
|
|
340
|
+
await sanityCheckForPage({page, pageId});
|
|
341
|
+
pagePool.addToPool(pageId);
|
|
342
|
+
}),
|
|
343
|
+
);
|
|
344
|
+
} catch (initializeTabsError) {
|
|
345
|
+
const msg = refineErrorMessage({
|
|
346
|
+
prefix: 'Error initializing browser tabs with storybook:',
|
|
347
|
+
error: initializeTabsError,
|
|
348
|
+
});
|
|
349
|
+
logger.log(msg);
|
|
350
|
+
ora({text: msg, stream: outputStream}).fail();
|
|
351
|
+
throw new Error();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
326
354
|
}
|
|
327
355
|
|
|
328
356
|
module.exports = eyesStorybook;
|
package/src/pagePool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
function createPagePool({initPage, logger}) {
|
|
3
|
+
function createPagePool({initPage, logger, freePageTimeout = 300_000}) {
|
|
4
4
|
let counter = 0;
|
|
5
5
|
const fullPageObjs = [];
|
|
6
6
|
logger.log(`[page pool] created`);
|
|
@@ -48,22 +48,38 @@ function createPagePool({initPage, logger}) {
|
|
|
48
48
|
pagePool.addToPool(newPageId);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
async function getFreePage() {
|
|
52
|
-
logger.log(`[page pool] waiting for free page`);
|
|
51
|
+
async function getFreePage(tryCount = 0) {
|
|
52
|
+
logger.log(`[page pool] waiting for free page, tryCount=${tryCount}`);
|
|
53
53
|
await currWaitOnFreePage;
|
|
54
|
+
const availablePages = fullPageObjs.filter(p => p.isInPool());
|
|
55
|
+
// wait up to 5 minutes
|
|
56
|
+
if (availablePages.length === 0) {
|
|
57
|
+
const INTERVAL = 500;
|
|
58
|
+
if (tryCount < freePageTimeout / INTERVAL) {
|
|
59
|
+
logger.log(`[page pool] no available pages, retrying to get free page...`);
|
|
60
|
+
await new Promise(r => setTimeout(r, INTERVAL));
|
|
61
|
+
return getFreePage(tryCount + 1);
|
|
62
|
+
} else {
|
|
63
|
+
throw new Error('Could not find free page, timed out after waiting 5 minutes');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
logger.log(`[page pool] waiting on pages ${availablePages.map(({pageId}) => pageId)}`);
|
|
54
67
|
currWaitOnFreePage = Promise.race(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return p;
|
|
60
|
-
}),
|
|
68
|
+
availablePages.map(async p => {
|
|
69
|
+
await p.waitUntilFree();
|
|
70
|
+
return p;
|
|
71
|
+
}),
|
|
61
72
|
);
|
|
62
73
|
|
|
63
74
|
const fullPageObj = await currWaitOnFreePage;
|
|
64
|
-
fullPageObj.
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
if (fullPageObj.isInPool()) {
|
|
76
|
+
fullPageObj.occupyPage();
|
|
77
|
+
logger.log(`[page pool] free page found: ${fullPageObj.pageId}`);
|
|
78
|
+
return toSmallPageObj(fullPageObj);
|
|
79
|
+
} else {
|
|
80
|
+
logger.log(`[page pool] free page found, but it is no longer in pool: ${fullPageObj.pageId}`);
|
|
81
|
+
return getFreePage(tryCount + 1);
|
|
82
|
+
}
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
async function createPage() {
|
|
@@ -91,7 +107,9 @@ function createPagePool({initPage, logger}) {
|
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
async function waitUntilFree() {
|
|
110
|
+
logger.log(`[page ${pageId}] waitUntilFree before`);
|
|
94
111
|
await workPromise;
|
|
112
|
+
logger.log(`[page ${pageId}] waitUntilFree after`);
|
|
95
113
|
}
|
|
96
114
|
|
|
97
115
|
function occupyPage() {
|
|
@@ -101,10 +119,13 @@ function createPagePool({initPage, logger}) {
|
|
|
101
119
|
}
|
|
102
120
|
|
|
103
121
|
function removePage() {
|
|
122
|
+
logger.log(`[page ${pageId}] removePage`);
|
|
104
123
|
fullPageObjs.splice(
|
|
105
124
|
fullPageObjs.findIndex(p => p.pageId === pageId),
|
|
106
125
|
1,
|
|
107
126
|
);
|
|
127
|
+
isActive = false;
|
|
128
|
+
resolveWork && resolveWork();
|
|
108
129
|
}
|
|
109
130
|
|
|
110
131
|
function isInPool() {
|
|
@@ -112,6 +133,7 @@ function createPagePool({initPage, logger}) {
|
|
|
112
133
|
}
|
|
113
134
|
|
|
114
135
|
function addToPool() {
|
|
136
|
+
logger.log(`[page ${pageId}] addToPool`);
|
|
115
137
|
isActive = true;
|
|
116
138
|
createdAt = Date.now();
|
|
117
139
|
}
|
package/src/renderStories.js
CHANGED
|
@@ -152,7 +152,7 @@ function makeRenderStories({
|
|
|
152
152
|
const {pageId, page} = pageObj;
|
|
153
153
|
logger.log(`[prepareNewPage] new page is ready: ${pageId}`);
|
|
154
154
|
try {
|
|
155
|
-
await sanityCheckForPage(page);
|
|
155
|
+
await sanityCheckForPage({page, pageId});
|
|
156
156
|
logger.log(`[prepareNewPage] setting new page for replacement: ${pageId}`);
|
|
157
157
|
newPageIdToAdd = pageId;
|
|
158
158
|
} catch (errorInSanity) {
|