@applitools/eyes-storybook 3.53.5 → 3.53.7

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 CHANGED
@@ -1,5 +1,85 @@
1
1
  # Changelog
2
2
 
3
+ ## [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
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * remove deprecated postinstall script ([#2729](https://github.com/Applitools-Dev/sdk/issues/2729)) ([28075c1](https://github.com/Applitools-Dev/sdk/commit/28075c10342c1e169040ac8b720f5c273bc9bf31))
9
+ * respect readStoriesTimeout ([#2776](https://github.com/Applitools-Dev/sdk/issues/2776)) ([8c841f4](https://github.com/Applitools-Dev/sdk/commit/8c841f492641759f056af889dbac68e711782b26))
10
+
11
+
12
+ ### Dependencies
13
+
14
+ * @applitools/ufg-client bumped to 1.16.4
15
+ #### Bug Fixes
16
+
17
+ * environment without type in ios should be considered web ([#2779](https://github.com/Applitools-Dev/sdk/issues/2779)) ([1a0dc18](https://github.com/Applitools-Dev/sdk/commit/1a0dc186d782ee8dacccf4ea9d10b513416b7492))
18
+ * specifying chrome version in UFG chrome emulations ([#2773](https://github.com/Applitools-Dev/sdk/issues/2773)) ([e86af5d](https://github.com/Applitools-Dev/sdk/commit/e86af5d8d616fb54a6cbe0a23db691d0b190b0f6))
19
+ * @applitools/core bumped to 4.31.2
20
+ #### Bug Fixes
21
+
22
+ * environment without type in ios should be considered web ([#2779](https://github.com/Applitools-Dev/sdk/issues/2779)) ([1a0dc18](https://github.com/Applitools-Dev/sdk/commit/1a0dc186d782ee8dacccf4ea9d10b513416b7492))
23
+ * move log line for closing batch in offline cli ([#2768](https://github.com/Applitools-Dev/sdk/issues/2768)) ([bfb51a9](https://github.com/Applitools-Dev/sdk/commit/bfb51a94d8e7d51020aac62dd78038fdeb819a68))
24
+
25
+
26
+
27
+ * @applitools/eyes bumped to 1.32.1
28
+
29
+
30
+ ## [3.53.6](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.53.5...js/eyes-storybook@3.53.6) (2025-01-30)
31
+
32
+
33
+ ### Bug Fixes
34
+
35
+ * storybook exception and add logs ([#2760](https://github.com/Applitools-Dev/sdk/issues/2760)) ([357193a](https://github.com/Applitools-Dev/sdk/commit/357193ad0f18eae729b4064d14d781e2401c70f7))
36
+
37
+
38
+ ### Dependencies
39
+
40
+ * @applitools/dom-snapshot bumped to 4.11.15
41
+
42
+ * @applitools/driver bumped to 1.20.4
43
+ #### Bug Fixes
44
+
45
+ * handle device screen info extraction gracefully ([#2757](https://github.com/Applitools-Dev/sdk/issues/2757)) ([92d0118](https://github.com/Applitools-Dev/sdk/commit/92d0118137b77e49d780092d110973df8ed8b40c))
46
+ * @applitools/eyes bumped to 1.32.0
47
+ #### Features
48
+
49
+ * remove iPhoneX from list of available UFG Safari devices ([#2756](https://github.com/Applitools-Dev/sdk/issues/2756)) ([e24d054](https://github.com/Applitools-Dev/sdk/commit/e24d054328df900fbc4988fdbf8213aadffa9a37))
50
+
51
+
52
+
53
+ * @applitools/spec-driver-webdriver bumped to 1.1.25
54
+
55
+ * @applitools/spec-driver-selenium bumped to 1.5.95
56
+
57
+ * @applitools/spec-driver-puppeteer bumped to 1.4.24
58
+
59
+ * @applitools/screenshoter bumped to 3.10.5
60
+
61
+ * @applitools/nml-client bumped to 1.8.24
62
+
63
+ * @applitools/ufg-client bumped to 1.16.3
64
+ #### Bug Fixes
65
+
66
+ * unthrottle renders in offline mode ([#2754](https://github.com/Applitools-Dev/sdk/issues/2754)) ([b65d816](https://github.com/Applitools-Dev/sdk/commit/b65d81610504ae725b7b52611282a1bb28a049fe))
67
+ * @applitools/ec-client bumped to 1.10.3
68
+
69
+ * @applitools/core bumped to 4.31.0
70
+ #### Features
71
+
72
+ * remove iPhoneX from list of available UFG Safari devices ([#2756](https://github.com/Applitools-Dev/sdk/issues/2756)) ([e24d054](https://github.com/Applitools-Dev/sdk/commit/e24d054328df900fbc4988fdbf8213aadffa9a37))
73
+
74
+
75
+ #### Bug Fixes
76
+
77
+ * handle device screen info extraction gracefully ([#2757](https://github.com/Applitools-Dev/sdk/issues/2757)) ([92d0118](https://github.com/Applitools-Dev/sdk/commit/92d0118137b77e49d780092d110973df8ed8b40c))
78
+ * unthrottle renders in offline mode ([#2754](https://github.com/Applitools-Dev/sdk/issues/2754)) ([b65d816](https://github.com/Applitools-Dev/sdk/commit/b65d81610504ae725b7b52611282a1bb28a049fe))
79
+
80
+
81
+
82
+
3
83
  ## [3.53.5](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.53.4...js/eyes-storybook@3.53.5) (2025-01-23)
4
84
 
5
85
 
@@ -38,7 +38,16 @@ function __getClientAPI(...args) {
38
38
  ) {
39
39
  return API_VERSIONS.v4;
40
40
  } else {
41
- throw new Error("Cannot get client API: couldn't detect storybook version");
41
+ const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key =>
42
+ key.includes('STORYBOOK'),
43
+ );
44
+ throw new Error(
45
+ `Cannot get client API: couldn't detect storybook version.${
46
+ storybookVariablesOnWindow.length
47
+ ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}`
48
+ : ' - no STORYBOOK variables found in global scope'
49
+ }`,
50
+ );
42
51
  }
43
52
  }
44
53
  function onStoryRendered(callback) {
@@ -181,13 +190,18 @@ function __getClientAPI(...args) {
181
190
  throw new Error('Cannot get client API: no frameWindow');
182
191
  }
183
192
 
184
- async function getClientAPIWithRetries() {
193
+ async function getClientAPIWithRetries({timeout = 5000} = {}) {
185
194
  let error = 'Unknown error';
186
- for (let attempt = 1; attempt <= 100; attempt++) {
187
- await new Promise(resolve => setTimeout(resolve, 100));
195
+ const RETRY_INTERVAL = 100;
196
+ const totalAttempts = timeout / RETRY_INTERVAL;
197
+ for (let attempt = 1; attempt <= totalAttempts; attempt++) {
198
+ await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));
188
199
  try {
189
200
  return getClientAPI();
190
201
  } catch (e) {
202
+ if (!(attempt % 10)) {
203
+ console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`);
204
+ }
191
205
  error = e;
192
206
  }
193
207
  }
@@ -38,7 +38,16 @@ function __getStories(...args) {
38
38
  ) {
39
39
  return API_VERSIONS.v4;
40
40
  } else {
41
- throw new Error("Cannot get client API: couldn't detect storybook version");
41
+ const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key =>
42
+ key.includes('STORYBOOK'),
43
+ );
44
+ throw new Error(
45
+ `Cannot get client API: couldn't detect storybook version.${
46
+ storybookVariablesOnWindow.length
47
+ ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}`
48
+ : ' - no STORYBOOK variables found in global scope'
49
+ }`,
50
+ );
42
51
  }
43
52
  }
44
53
  function onStoryRendered(callback) {
@@ -181,13 +190,18 @@ function __getStories(...args) {
181
190
  throw new Error('Cannot get client API: no frameWindow');
182
191
  }
183
192
 
184
- async function getClientAPIWithRetries() {
193
+ async function getClientAPIWithRetries({timeout = 5000} = {}) {
185
194
  let error = 'Unknown error';
186
- for (let attempt = 1; attempt <= 100; attempt++) {
187
- await new Promise(resolve => setTimeout(resolve, 100));
195
+ const RETRY_INTERVAL = 100;
196
+ const totalAttempts = timeout / RETRY_INTERVAL;
197
+ for (let attempt = 1; attempt <= totalAttempts; attempt++) {
198
+ await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));
188
199
  try {
189
200
  return getClientAPI();
190
201
  } catch (e) {
202
+ if (!(attempt % 10)) {
203
+ console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`);
204
+ }
191
205
  error = e;
192
206
  }
193
207
  }
@@ -196,9 +210,7 @@ function __getStories(...args) {
196
210
 
197
211
  var getClientAPI_1 = getClientAPIWithRetries;
198
212
 
199
- const DEFAULT_TIMEOUT = 60000;
200
-
201
- async function getStories({timeout = DEFAULT_TIMEOUT} = {timeout: DEFAULT_TIMEOUT}) {
213
+ async function getStories() {
202
214
  const Stories = {
203
215
  _getStoriesV2: () => {
204
216
  let categories = getCategoriesV2();
@@ -283,7 +295,7 @@ function __getStories(...args) {
283
295
  },
284
296
  };
285
297
 
286
- const clientApi = await waitForClientAPI();
298
+ const clientApi = await getClientAPI_1().catch(() => null);
287
299
 
288
300
  if (clientApi) {
289
301
  console.log(`getting stories from storybook via API. ${clientApi.version}`);
@@ -362,36 +374,6 @@ function __getStories(...args) {
362
374
  s => s.innerText === 'loading story',
363
375
  );
364
376
  }
365
-
366
- function waitForClientAPI() {
367
- return ptimeoutWithValue(_waitForClientAPI, timeout, undefined);
368
-
369
- async function _waitForClientAPI() {
370
- try {
371
- return getClientAPI_1();
372
- } catch (ex) {
373
- await delay(100);
374
- return _waitForClientAPI();
375
- }
376
- }
377
- }
378
-
379
- async function delay(time) {
380
- return new Promise(res => {
381
- setTimeout(res, time);
382
- });
383
- }
384
-
385
- async function ptimeoutWithValue(getPromise, delay, value) {
386
- let _res, _rej;
387
- const result = new Promise((res, rej) => ((_res = res), (_rej = rej)));
388
- const cancel = setTimeout(() => _res(value), delay);
389
- getPromise()
390
- .then(v => _res(v))
391
- .catch(e => _rej(e))
392
- .finally(() => clearTimeout(cancel));
393
- return result;
394
- }
395
377
  }
396
378
 
397
379
  var getStories_1 = getStories;
@@ -38,7 +38,16 @@ function __renderStoryWithClientAPI(...args) {
38
38
  ) {
39
39
  return API_VERSIONS.v4;
40
40
  } else {
41
- throw new Error("Cannot get client API: couldn't detect storybook version");
41
+ const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key =>
42
+ key.includes('STORYBOOK'),
43
+ );
44
+ throw new Error(
45
+ `Cannot get client API: couldn't detect storybook version.${
46
+ storybookVariablesOnWindow.length
47
+ ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}`
48
+ : ' - no STORYBOOK variables found in global scope'
49
+ }`,
50
+ );
42
51
  }
43
52
  }
44
53
  function onStoryRendered(callback) {
@@ -181,13 +190,18 @@ function __renderStoryWithClientAPI(...args) {
181
190
  throw new Error('Cannot get client API: no frameWindow');
182
191
  }
183
192
 
184
- async function getClientAPIWithRetries() {
193
+ async function getClientAPIWithRetries({timeout = 5000} = {}) {
185
194
  let error = 'Unknown error';
186
- for (let attempt = 1; attempt <= 100; attempt++) {
187
- await new Promise(resolve => setTimeout(resolve, 100));
195
+ const RETRY_INTERVAL = 100;
196
+ const totalAttempts = timeout / RETRY_INTERVAL;
197
+ for (let attempt = 1; attempt <= totalAttempts; attempt++) {
198
+ await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));
188
199
  try {
189
200
  return getClientAPI();
190
201
  } catch (e) {
202
+ if (!(attempt % 10)) {
203
+ console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`);
204
+ }
191
205
  error = e;
192
206
  }
193
207
  }
@@ -38,7 +38,16 @@ function __runRunAfterScript(...args) {
38
38
  ) {
39
39
  return API_VERSIONS.v4;
40
40
  } else {
41
- throw new Error("Cannot get client API: couldn't detect storybook version");
41
+ const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key =>
42
+ key.includes('STORYBOOK'),
43
+ );
44
+ throw new Error(
45
+ `Cannot get client API: couldn't detect storybook version.${
46
+ storybookVariablesOnWindow.length
47
+ ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}`
48
+ : ' - no STORYBOOK variables found in global scope'
49
+ }`,
50
+ );
42
51
  }
43
52
  }
44
53
  function onStoryRendered(callback) {
@@ -181,13 +190,18 @@ function __runRunAfterScript(...args) {
181
190
  throw new Error('Cannot get client API: no frameWindow');
182
191
  }
183
192
 
184
- async function getClientAPIWithRetries() {
193
+ async function getClientAPIWithRetries({timeout = 5000} = {}) {
185
194
  let error = 'Unknown error';
186
- for (let attempt = 1; attempt <= 100; attempt++) {
187
- await new Promise(resolve => setTimeout(resolve, 100));
195
+ const RETRY_INTERVAL = 100;
196
+ const totalAttempts = timeout / RETRY_INTERVAL;
197
+ for (let attempt = 1; attempt <= totalAttempts; attempt++) {
198
+ await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));
188
199
  try {
189
200
  return getClientAPI();
190
201
  } catch (e) {
202
+ if (!(attempt % 10)) {
203
+ console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`);
204
+ }
191
205
  error = e;
192
206
  }
193
207
  }
@@ -38,7 +38,16 @@ function __runRunBeforeScript(...args) {
38
38
  ) {
39
39
  return API_VERSIONS.v4;
40
40
  } else {
41
- throw new Error("Cannot get client API: couldn't detect storybook version");
41
+ const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key =>
42
+ key.includes('STORYBOOK'),
43
+ );
44
+ throw new Error(
45
+ `Cannot get client API: couldn't detect storybook version.${
46
+ storybookVariablesOnWindow.length
47
+ ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}`
48
+ : ' - no STORYBOOK variables found in global scope'
49
+ }`,
50
+ );
42
51
  }
43
52
  }
44
53
  function onStoryRendered(callback) {
@@ -181,13 +190,18 @@ function __runRunBeforeScript(...args) {
181
190
  throw new Error('Cannot get client API: no frameWindow');
182
191
  }
183
192
 
184
- async function getClientAPIWithRetries() {
193
+ async function getClientAPIWithRetries({timeout = 5000} = {}) {
185
194
  let error = 'Unknown error';
186
- for (let attempt = 1; attempt <= 100; attempt++) {
187
- await new Promise(resolve => setTimeout(resolve, 100));
195
+ const RETRY_INTERVAL = 100;
196
+ const totalAttempts = timeout / RETRY_INTERVAL;
197
+ for (let attempt = 1; attempt <= totalAttempts; attempt++) {
198
+ await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));
188
199
  try {
189
200
  return getClientAPI();
190
201
  } catch (e) {
202
+ if (!(attempt % 10)) {
203
+ console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`);
204
+ }
191
205
  error = e;
192
206
  }
193
207
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-storybook",
3
- "version": "3.53.5",
3
+ "version": "3.53.7",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "applitools",
@@ -50,18 +50,17 @@
50
50
  "changelog": "git changelog -x -p -f v$npm_package_version > History.md && git add ./History.md && git commit -am 'changelog'",
51
51
  "changelog:init": "git config changelog.format \"* %s [[%h]($(echo $npm_package_repository_url|cut -d+ -f2|cut -d. -f1-2)/commit/%H)]\"",
52
52
  "changelog:install": "sudo apt-get install git-extras",
53
- "postinstall": "node src/postinstall",
54
53
  "up:framework": "cd test/fixtures/storybook-versions/${APPLITOOLS_FRAMEWORK_VERSION} && npm ci"
55
54
  },
56
55
  "dependencies": {
57
- "@applitools/core": "4.30.1",
58
- "@applitools/driver": "1.20.3",
59
- "@applitools/eyes": "1.31.3",
56
+ "@applitools/core": "4.31.2",
57
+ "@applitools/driver": "1.20.4",
58
+ "@applitools/eyes": "1.32.1",
60
59
  "@applitools/functional-commons": "1.6.0",
61
60
  "@applitools/logger": "2.1.0",
62
61
  "@applitools/monitoring-commons": "1.0.19",
63
- "@applitools/spec-driver-puppeteer": "1.4.23",
64
- "@applitools/ufg-client": "1.16.2",
62
+ "@applitools/spec-driver-puppeteer": "1.4.24",
63
+ "@applitools/ufg-client": "1.16.4",
65
64
  "@applitools/utils": "1.7.7",
66
65
  "boxen": "4.2.0",
67
66
  "chalk": "3.0.0",
@@ -35,7 +35,16 @@ function getClientAPI() {
35
35
  ) {
36
36
  return API_VERSIONS.v4;
37
37
  } else {
38
- throw new Error("Cannot get client API: couldn't detect storybook version");
38
+ const storybookVariablesOnWindow = Object.keys(frameWindow).filter(key =>
39
+ key.includes('STORYBOOK'),
40
+ );
41
+ throw new Error(
42
+ `Cannot get client API: couldn't detect storybook version.${
43
+ storybookVariablesOnWindow.length
44
+ ? ` Found the following storybook variables: ${storybookVariablesOnWindow.join(', ')}`
45
+ : ' - no STORYBOOK variables found in global scope'
46
+ }`,
47
+ );
39
48
  }
40
49
  }
41
50
  function onStoryRendered(callback) {
@@ -178,13 +187,18 @@ function getFrameWindow() {
178
187
  throw new Error('Cannot get client API: no frameWindow');
179
188
  }
180
189
 
181
- async function getClientAPIWithRetries() {
190
+ async function getClientAPIWithRetries({timeout = 5000} = {}) {
182
191
  let error = 'Unknown error';
183
- for (let attempt = 1; attempt <= 100; attempt++) {
184
- await new Promise(resolve => setTimeout(resolve, 100));
192
+ const RETRY_INTERVAL = 100;
193
+ const totalAttempts = timeout / RETRY_INTERVAL;
194
+ for (let attempt = 1; attempt <= totalAttempts; attempt++) {
195
+ await new Promise(resolve => setTimeout(resolve, RETRY_INTERVAL));
185
196
  try {
186
197
  return getClientAPI();
187
198
  } catch (e) {
199
+ if (!(attempt % 10)) {
200
+ console.log(`Error in getClientAPI: ${e.message}, attempt ${attempt}/${totalAttempts}`);
201
+ }
188
202
  error = e;
189
203
  }
190
204
  }
@@ -1,8 +1,6 @@
1
1
  const getClientAPI = require('./getClientAPI');
2
2
 
3
- const DEFAULT_TIMEOUT = 60000;
4
-
5
- async function getStories({timeout = DEFAULT_TIMEOUT} = {timeout: DEFAULT_TIMEOUT}) {
3
+ async function getStories() {
6
4
  const Stories = {
7
5
  _getStoriesV2: () => {
8
6
  let categories = getCategoriesV2();
@@ -87,7 +85,7 @@ async function getStories({timeout = DEFAULT_TIMEOUT} = {timeout: DEFAULT_TIMEOU
87
85
  },
88
86
  };
89
87
 
90
- const clientApi = await waitForClientAPI();
88
+ const clientApi = await getClientAPI().catch(() => null);
91
89
 
92
90
  if (clientApi) {
93
91
  console.log(`getting stories from storybook via API. ${clientApi.version}`);
@@ -166,36 +164,6 @@ async function getStories({timeout = DEFAULT_TIMEOUT} = {timeout: DEFAULT_TIMEOU
166
164
  s => s.innerText === 'loading story',
167
165
  );
168
166
  }
169
-
170
- function waitForClientAPI() {
171
- return ptimeoutWithValue(_waitForClientAPI, timeout, undefined);
172
-
173
- async function _waitForClientAPI() {
174
- try {
175
- return getClientAPI();
176
- } catch (ex) {
177
- await delay(100);
178
- return _waitForClientAPI();
179
- }
180
- }
181
- }
182
-
183
- async function delay(time) {
184
- return new Promise(res => {
185
- setTimeout(res, time);
186
- });
187
- }
188
-
189
- async function ptimeoutWithValue(getPromise, delay, value) {
190
- let _res, _rej;
191
- const result = new Promise((res, rej) => ((_res = res), (_rej = rej)));
192
- const cancel = setTimeout(() => _res(value), delay);
193
- getPromise()
194
- .then(v => _res(v))
195
- .catch(e => _rej(e))
196
- .finally(() => clearTimeout(cancel));
197
- return result;
198
- }
199
167
  }
200
168
 
201
169
  module.exports = getStories;
@@ -43,6 +43,7 @@ const configParams = [
43
43
  'notifyOnCompletion',
44
44
  'batchNotify',
45
45
  'dontCloseBatches',
46
+ 'showBrowserLogs',
46
47
  ];
47
48
 
48
49
  module.exports = {configParams};
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
  const puppeteer = require('puppeteer');
3
3
  const getStories = require('../dist/getStories');
4
- const {presult, delay} = require('@applitools/functional-commons');
4
+ const {presult} = require('@applitools/functional-commons');
5
+ const {executeWithRetry} = require('./utils/executeWithRetry');
5
6
  const chalk = require('chalk');
6
7
  const makeInitPage = require('./initPage');
7
8
  const makeRenderStory = require('./renderStory');
@@ -23,9 +24,6 @@ const {extractEnvironment} = require('./extractEnvironment');
23
24
  const {makeCore} = require('@applitools/core');
24
25
  const makeGetStoriesWithConfig = require('./getStoriesWithConfig');
25
26
 
26
- const MAX_RETRIES = 30;
27
- const RETRY_INTERVAL = 1000;
28
-
29
27
  async function eyesStorybook({
30
28
  config,
31
29
  logger,
@@ -166,7 +164,7 @@ async function eyesStorybook({
166
164
  const renderStories = makeRenderStories({
167
165
  getStoryData,
168
166
  renderStory,
169
- getClientAPI,
167
+ sanityCheckForPage,
170
168
  storybookUrl,
171
169
  logger,
172
170
  stream: outputStream,
@@ -234,10 +232,10 @@ async function eyesStorybook({
234
232
  throw new Error();
235
233
  }
236
234
 
237
- const [getStoriesErr, stories] = await readStoriesWithRetry(MAX_RETRIES);
235
+ const [getStoriesErr, stories] = await presult(readStoriesWithRetry());
238
236
 
239
237
  if (getStoriesErr) {
240
- logger.log('Error in getStories:', getStoriesErr);
238
+ logger.log('Error when reading stories:', getStoriesErr);
241
239
  const failMsg = refineErrorMessage({
242
240
  prefix: 'Error when reading stories:',
243
241
  error: getStoriesErr,
@@ -283,20 +281,46 @@ async function eyesStorybook({
283
281
  return transitioning;
284
282
  }
285
283
 
286
- async function readStoriesWithRetry(remainingRetries) {
287
- const [getStoriesErr, stories] = await presult(
288
- page.evaluate(getStories, {timeout: readStoriesTimeout}),
284
+ async function readStoriesWithRetry() {
285
+ return executeWithRetry(
286
+ _readStoriesWithRetry,
287
+ {
288
+ timeout: readStoriesTimeout,
289
+ delayBetweenRetries: 1000,
290
+ initialErrMessage: `Could not get stories since readStoriesTimeout is too short (${readStoriesTimeout}ms)`,
291
+ },
292
+ readStoriesTimeout,
289
293
  );
290
- if (stories?.length > 0 || remainingRetries == 0) {
291
- return [getStoriesErr, stories];
292
- } else {
293
- if (getStoriesErr) {
294
- logger.log('Error in getStories:', getStoriesErr);
295
- } else {
296
- logger.log(`Got 0 stories, retrying to read stories... ${remainingRetries - 1} are left`);
294
+
295
+ async function _readStoriesWithRetry() {
296
+ try {
297
+ const stories = await page.evaluate(getStories);
298
+ if (stories.length > 0) {
299
+ return stories;
300
+ } else {
301
+ throw new Error('Got 0 stories');
302
+ }
303
+ } catch (err) {
304
+ logger.log('Error in _readStoriesWithRetry:', err, ', retrying...');
305
+ throw err;
306
+ }
307
+ }
308
+ }
309
+
310
+ async function sanityCheckForPage(page) {
311
+ return executeWithRetry(_sanityCheckForPage, {
312
+ timeout: readStoriesTimeout,
313
+ delayBetweenRetries: 1000,
314
+ initialErrMessage: `Could not get client API in sanity check since readStoriesTimeout is too short (${readStoriesTimeout}ms)`,
315
+ });
316
+
317
+ async function _sanityCheckForPage() {
318
+ try {
319
+ await page.evaluate(getClientAPI);
320
+ } catch (err) {
321
+ logger.log('Error in getClientAPI during sanity check:', err, ', retrying...');
322
+ throw err;
297
323
  }
298
- await delay(RETRY_INTERVAL);
299
- return await readStoriesWithRetry(remainingRetries - 1);
300
324
  }
301
325
  }
302
326
  }
@@ -13,9 +13,9 @@ const DOM_SNAPSHOTS_TIMEOUT = 5 * 60 * 1000;
13
13
  const utils = require('@applitools/utils');
14
14
 
15
15
  function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigationWaitUntil}) {
16
- return async function getStoryData({story, storyUrl, page}) {
16
+ return async function getStoryData({story, storyUrl, page, pageId = 'mock'}) {
17
17
  const title = getStoryBaselineName(story);
18
- logger.log(`getting data from story`, title);
18
+ logger.log(`[page ${pageId}] getting data from story`, title);
19
19
 
20
20
  const eyesParameters = story.parameters && story.parameters.eyes;
21
21
  if (story.isApi && !reloadPagePerStory) {
@@ -26,9 +26,9 @@ function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigat
26
26
  const err = await ptimeoutWithError(
27
27
  page.evaluate(renderStoryWithClientAPI, story.index, story.id),
28
28
  PAGE_EVALUATE_TIMEOUT,
29
- new Error('page evaluate timed out!'),
29
+ new Error(`[page ${pageId}] page evaluate timed out!`),
30
30
  );
31
- logger.log(`[story data] done with page evaluate for story ${title}`);
31
+ logger.log(`[page ${pageId}] done with page evaluate for story ${title}`);
32
32
  err && handleRenderStoryError(err);
33
33
  } catch (ex) {
34
34
  if (ex.message && !ex.message.includes('Eyes could not render stories properly'))
@@ -53,17 +53,17 @@ function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigat
53
53
 
54
54
  if (eyesParameters && eyesParameters.runBefore) {
55
55
  await page.evaluate(runRunBeforeScript, story.index).catch(err => {
56
- logger.log(`error during runBefore: ${err}`); // it might be good to aggregate these errors and output them at the end of the run
56
+ logger.log(`[page ${pageId}] error during runBefore: ${err}`); // it might be good to aggregate these errors and output them at the end of the run
57
57
  });
58
58
  }
59
59
 
60
- logger.log(`running takeDomSnapshot(s) for story ${title}`);
60
+ logger.log(`[page ${pageId}] running takeDomSnapshot(s) for story ${title}`);
61
61
  const domSnapshotsPromise = takeDomSnapshots({
62
62
  page,
63
63
  ...storyToCheckSettings({story}),
64
64
  waitBeforeCapture: wait
65
65
  ? async () => {
66
- logger.log(`waiting before screenshot of ${title} ${wait}`);
66
+ logger.log(`[page ${pageId}] waiting before screenshot of ${title} ${wait}`);
67
67
  await waitFor(page, wait);
68
68
  }
69
69
  : undefined,
@@ -72,27 +72,27 @@ function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigat
72
72
  const result = await ptimeoutWithError(
73
73
  domSnapshotsPromise,
74
74
  DOM_SNAPSHOTS_TIMEOUT,
75
- new Error(`timeout reached when trying to take DOM for story ${title}`),
75
+ new Error(`[page ${pageId}] timeout reached when trying to take DOM for story ${title}`),
76
76
  );
77
77
 
78
- logger.log(`done getting DOM for story ${title}`);
78
+ logger.log(`[page ${pageId}] done getting DOM for story ${title}`);
79
79
 
80
80
  if (eyesParameters && eyesParameters.runAfter) {
81
81
  await page.evaluate(runRunAfterScript, story.index).catch(err => {
82
- logger.log(`error during runAfter: ${err}`);
82
+ logger.log(`[page ${pageId}] error during runAfter: ${err}`);
83
83
  });
84
84
  }
85
85
 
86
- logger.log(`done getting data from story`, title);
86
+ logger.log(`[page ${pageId}] done getting data from story`, title);
87
87
  return result;
88
88
 
89
89
  async function renderStoryLegacy() {
90
- logger.log(`getting data from story ${storyUrl}`);
90
+ logger.log(`[page ${pageId}] getting data from story ${storyUrl}`);
91
91
  const [err] = await presult(
92
92
  page.goto(storyUrl, {timeout: PAGE_EVALUATE_TIMEOUT, waitUntil: navigationWaitUntil}),
93
93
  );
94
94
  if (err) {
95
- logger.log(`error navigating to story ${storyUrl}`, err);
95
+ logger.log(`[page ${pageId}] error navigating to story ${storyUrl}`, err);
96
96
  throw err;
97
97
  }
98
98
  }
@@ -101,7 +101,7 @@ function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigat
101
101
  try {
102
102
  url = new URL(url);
103
103
  } catch (err) {
104
- logger.error('Error during parsing page url', err);
104
+ logger.error(`[page ${pageId}] Error during parsing page url`, err);
105
105
  return false;
106
106
  }
107
107
 
@@ -124,7 +124,7 @@ function makeGetStoryData({logger, takeDomSnapshots, reloadPagePerStory, navigat
124
124
 
125
125
  // TODO (amit): handle this error in the caller (probably renderStories)
126
126
  function handleRenderStoryError(error) {
127
- logger.log(error.message);
127
+ logger.log(`[page ${pageId}] ${error.message}`);
128
128
  const versionMsg = error.version
129
129
  ? ` The detected version of storybook is ${error.version}.`
130
130
  : '';
package/src/initPage.js CHANGED
@@ -16,7 +16,9 @@ function makeInitPage({iframeUrl, config, browser, logger, getTransitiongIntoIE,
16
16
  browserLog({
17
17
  page,
18
18
  onLog: text => {
19
- if (text.match(/\[dom-snapshot\]/)) {
19
+ if (config.showBrowserLogs) {
20
+ logger.log(`tab ${pageId}: ${text}`);
21
+ } else if (text.match(/\[dom-snapshot\]/)) {
20
22
  logger.log(`tab ${pageId}: ${text}`);
21
23
  }
22
24
  },
package/src/pagePool.js CHANGED
@@ -86,6 +86,7 @@ function createPagePool({initPage, logger}) {
86
86
  };
87
87
 
88
88
  function markPageAsFree() {
89
+ logger.log('[page pool] marking page as free', pageId);
89
90
  resolveWork();
90
91
  }
91
92
 
@@ -4,9 +4,6 @@ const getStoryBaselineName = require('./getStoryBaselineName');
4
4
  const ora = require('ora');
5
5
  const {presult} = require('@applitools/functional-commons');
6
6
 
7
- const MAX_RETRIES = 30;
8
- const RETRY_INTERVAL = 1000;
9
-
10
7
  function makeRenderStories({
11
8
  getStoryData,
12
9
  pagePool,
@@ -14,7 +11,7 @@ function makeRenderStories({
14
11
  storybookUrl,
15
12
  logger,
16
13
  stream,
17
- getClientAPI,
14
+ sanityCheckForPage,
18
15
  maxPageTTL = 60000,
19
16
  }) {
20
17
  let newPageIdToAdd;
@@ -67,6 +64,7 @@ function makeRenderStories({
67
64
  story,
68
65
  storyUrl,
69
66
  page,
67
+ pageId,
70
68
  }),
71
69
  );
72
70
 
@@ -91,6 +89,7 @@ function makeRenderStories({
91
89
  story,
92
90
  storyUrl,
93
91
  page: newPageObj.page,
92
+ pageId: newPageObj.pageId,
94
93
  }),
95
94
  );
96
95
  error = newError;
@@ -152,31 +151,19 @@ function makeRenderStories({
152
151
 
153
152
  const {pageId, page} = pageObj;
154
153
  logger.log(`[prepareNewPage] new page is ready: ${pageId}`);
155
- const [errorInSanity] = await getClientAPIWithRetry(page, MAX_RETRIES);
156
- if (errorInSanity) {
154
+ try {
155
+ await sanityCheckForPage(page);
156
+ logger.log(`[prepareNewPage] setting new page for replacement: ${pageId}`);
157
+ newPageIdToAdd = pageId;
158
+ } catch (errorInSanity) {
157
159
  logger.log(
158
- `[prepareNewPage] new page ${pageId} is corrupted. preparing new page. ${errorInSanity}`,
160
+ `[prepareNewPage] new page ${pageId} is corrupted. preparing new page.`,
161
+ errorInSanity,
159
162
  );
160
163
  prepareNewPage();
161
- return;
162
164
  }
163
-
164
- logger.log(`[prepareNewPage] setting new page for replacement: ${pageId}`);
165
-
166
- newPageIdToAdd = pageId;
167
165
  }
168
166
  };
169
-
170
- async function getClientAPIWithRetry(page, remainingRetries) {
171
- const [err] = await presult(page.evaluate(getClientAPI));
172
- if (!err || remainingRetries == 0) {
173
- return [err];
174
- } else if (err) {
175
- logger.log('Error in getClientAPI:', err, `retrying... ${remainingRetries - 1} are left`);
176
- await delay(RETRY_INTERVAL);
177
- return await getClientAPIWithRetry(page, remainingRetries - 1);
178
- }
179
- }
180
167
  }
181
168
 
182
169
  module.exports = makeRenderStories;
@@ -0,0 +1,22 @@
1
+ const {delay, ptimeoutWithFunction} = require('@applitools/functional-commons');
2
+
3
+ async function executeWithRetry(fn, {timeout, initialErrMessage, delayBetweenRetries}) {
4
+ let err = new Error(initialErrMessage);
5
+
6
+ return ptimeoutWithFunction(_executeWithRetry, timeout, () => Promise.reject(err));
7
+
8
+ async function _executeWithRetry(hasAborted) {
9
+ try {
10
+ return await fn();
11
+ } catch (fnErr) {
12
+ err = fnErr;
13
+ }
14
+
15
+ if (!hasAborted()) {
16
+ await delay(delayBetweenRetries);
17
+ return await _executeWithRetry(hasAborted);
18
+ }
19
+ }
20
+ }
21
+
22
+ module.exports = {executeWithRetry};
@@ -1,16 +0,0 @@
1
- const chalk = require('chalk');
2
- const boxen = require('boxen');
3
- console.log(
4
- boxen(
5
- `This is version 3 of ${chalk.cyan('@applitools/eyes-storybook')}.
6
- This version includes a wide variety of performance improvements and features.
7
- We recommend checking out the release notes:
8
- ${chalk.yellow('https://github.com/applitools/eyes-storybook/blob/v3.0.1/docs/release-notes-v3.md')}
9
-
10
- If you experience a difference in behavior between v2 and v3, it's possible to opt out of the optimization
11
- by configuring ${chalk.cyan('reloadPagePerStory')} to ${chalk.cyan(
12
- 'true',
13
- )}. And, do read the release notes - they explain it perfectly :-)`,
14
- {padding: 1, borderColor: 'cyan', align: 'center'},
15
- ),
16
- );