@applitools/eyes-storybook 3.27.4 → 3.28.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 CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+
6
+ ## 3.28.0 - 2022/5/26
7
+
8
+ ### Features
9
+ - Support [Storybook interactions](https://storybook.js.org/docs/react/essentials/interactions). For stories which have a `Play` function defined, the screenshot will be taken automatically after the `Play` flow is done.
10
+ ### Bug fixes
11
+ - added `properties` and `notifyOnCompletion` as optional Types of Batch (for TS)
12
+ - Allow running with self-signed certificates
13
+
14
+ ## 3.27.6 - 2022/4/13
15
+
16
+ ### Features
17
+ ### Bug fixes
18
+ - Support data urls in iframes
19
+
20
+ ## 3.27.5 - 2022/3/29
21
+
22
+ ### Features
23
+ - Preserve search parameters in Storybook URLs
24
+ ### Bug fixes
25
+
5
26
  ## 3.27.4 - 2022/2/9
6
27
 
7
28
  - updated to @applitools/driver@1.4.9 (from 1.4.7)
package/README.md CHANGED
@@ -49,6 +49,7 @@ Applitools Eyes SDK for [Storybook](http://storybook.js.org).
49
49
  - [`layoutBreakpoints`](#layoutbreakpoints)
50
50
  - [Running Eyes-Storybook in Docker](#running-eyes-storybook-in-docker)
51
51
  - [Dealing with dynamic data](#dealing-with-dynamic-data)
52
+ - [Storybook interactions Play functionality](#storybook-interactions-play-functionality)
52
53
 
53
54
  ## Installation
54
55
 
@@ -848,3 +849,11 @@ const date = new Date(isBeingTested ? SOME_FIXED_DATE : undefined)
848
849
 
849
850
  storiesOf('Some kind', module).add('Date', () => <div>{date}</div>)
850
851
  ```
852
+
853
+ ## Storybook interactions Play functionality
854
+
855
+ Since version 3.27.7, there is a support for Storybooks' Interactions Play functionality: Stories who use 'Play', screenshot will be taken _automatically_ after the 'Play' flow is done.
856
+ This will replace the existing point of taking screenshots, it should not affect any new or existing Stories which are **not** using the 'Play' functionality.
857
+ Tests that use the _`waitBeforeCapture`_ property, the wait period will begin **after** the 'Play' flow is done.
858
+ You can read more at Storybook interactions documentation:
859
+ https://storybook.js.org/docs/react/essentials/interactions
@@ -38,7 +38,15 @@ function __getClientAPI(...args) {
38
38
  throw new Error("Cannot get client API: couldn't detect storybook version");
39
39
  }
40
40
  }
41
-
41
+ function onStoryRendered(callback) {
42
+ if (addons && addons.channel && addons.channel.once) {
43
+ addons.channel.once('storyRendered', () => {
44
+ setTimeout(callback, 0);
45
+ });
46
+ } else {
47
+ callback();
48
+ }
49
+ }
42
50
  function getAPI(version) {
43
51
  if (version) {
44
52
  let api;
@@ -57,6 +65,7 @@ function __getClientAPI(...args) {
57
65
  const {kind, name: story} = api.getStories()[i];
58
66
  addons.channel._listeners.setCurrentStory[0]({kind, story});
59
67
  },
68
+ onStoryRendered,
60
69
  };
61
70
  break;
62
71
  }
@@ -69,6 +78,7 @@ function __getClientAPI(...args) {
69
78
  selectStory: i => {
70
79
  clientAPI._storyStore.setSelection(clientAPI.raw()[i]);
71
80
  },
81
+ onStoryRendered,
72
82
  };
73
83
  break;
74
84
  }
@@ -81,6 +91,7 @@ function __getClientAPI(...args) {
81
91
  selectStory: i => {
82
92
  frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id});
83
93
  },
94
+ onStoryRendered,
84
95
  };
85
96
  break;
86
97
  }
@@ -96,6 +107,7 @@ function __getClientAPI(...args) {
96
107
  });
97
108
  await frameWindow.__STORYBOOK_PREVIEW__.renderSelection();
98
109
  },
110
+ onStoryRendered,
99
111
  };
100
112
  break;
101
113
  }
@@ -38,7 +38,15 @@ function __getStories(...args) {
38
38
  throw new Error("Cannot get client API: couldn't detect storybook version");
39
39
  }
40
40
  }
41
-
41
+ function onStoryRendered(callback) {
42
+ if (addons && addons.channel && addons.channel.once) {
43
+ addons.channel.once('storyRendered', () => {
44
+ setTimeout(callback, 0);
45
+ });
46
+ } else {
47
+ callback();
48
+ }
49
+ }
42
50
  function getAPI(version) {
43
51
  if (version) {
44
52
  let api;
@@ -57,6 +65,7 @@ function __getStories(...args) {
57
65
  const {kind, name: story} = api.getStories()[i];
58
66
  addons.channel._listeners.setCurrentStory[0]({kind, story});
59
67
  },
68
+ onStoryRendered,
60
69
  };
61
70
  break;
62
71
  }
@@ -69,6 +78,7 @@ function __getStories(...args) {
69
78
  selectStory: i => {
70
79
  clientAPI._storyStore.setSelection(clientAPI.raw()[i]);
71
80
  },
81
+ onStoryRendered,
72
82
  };
73
83
  break;
74
84
  }
@@ -81,6 +91,7 @@ function __getStories(...args) {
81
91
  selectStory: i => {
82
92
  frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id});
83
93
  },
94
+ onStoryRendered,
84
95
  };
85
96
  break;
86
97
  }
@@ -96,6 +107,7 @@ function __getStories(...args) {
96
107
  });
97
108
  await frameWindow.__STORYBOOK_PREVIEW__.renderSelection();
98
109
  },
110
+ onStoryRendered,
99
111
  };
100
112
  break;
101
113
  }
@@ -259,9 +271,10 @@ function __getStories(...args) {
259
271
  }
260
272
  }
261
273
  }
262
-
274
+ const hasPlayFunction = !!story.playFunction;
263
275
  return {
264
276
  isApi: true,
277
+ hasPlayFunction,
265
278
  index,
266
279
  name,
267
280
  kind,
@@ -38,7 +38,15 @@ function __renderStoryWithClientAPI(...args) {
38
38
  throw new Error("Cannot get client API: couldn't detect storybook version");
39
39
  }
40
40
  }
41
-
41
+ function onStoryRendered(callback) {
42
+ if (addons && addons.channel && addons.channel.once) {
43
+ addons.channel.once('storyRendered', () => {
44
+ setTimeout(callback, 0);
45
+ });
46
+ } else {
47
+ callback();
48
+ }
49
+ }
42
50
  function getAPI(version) {
43
51
  if (version) {
44
52
  let api;
@@ -57,6 +65,7 @@ function __renderStoryWithClientAPI(...args) {
57
65
  const {kind, name: story} = api.getStories()[i];
58
66
  addons.channel._listeners.setCurrentStory[0]({kind, story});
59
67
  },
68
+ onStoryRendered,
60
69
  };
61
70
  break;
62
71
  }
@@ -69,6 +78,7 @@ function __renderStoryWithClientAPI(...args) {
69
78
  selectStory: i => {
70
79
  clientAPI._storyStore.setSelection(clientAPI.raw()[i]);
71
80
  },
81
+ onStoryRendered,
72
82
  };
73
83
  break;
74
84
  }
@@ -81,6 +91,7 @@ function __renderStoryWithClientAPI(...args) {
81
91
  selectStory: i => {
82
92
  frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id});
83
93
  },
94
+ onStoryRendered,
84
95
  };
85
96
  break;
86
97
  }
@@ -96,6 +107,7 @@ function __renderStoryWithClientAPI(...args) {
96
107
  });
97
108
  await frameWindow.__STORYBOOK_PREVIEW__.renderSelection();
98
109
  },
110
+ onStoryRendered,
99
111
  };
100
112
  break;
101
113
  }
@@ -130,14 +142,17 @@ function __renderStoryWithClientAPI(...args) {
130
142
 
131
143
  var getClientAPI_1 = getClientAPI;
132
144
 
133
- async function renderStoryWithClientAPI(index) {
134
- let api;
135
- try {
136
- api = getClientAPI_1();
137
- await api.selectStory(index);
138
- } catch (ex) {
139
- return {message: ex.message, version: api ? api.version : undefined};
140
- }
145
+ function renderStoryWithClientAPI(index) {
146
+ return new Promise(resolve => {
147
+ let api;
148
+ try {
149
+ api = getClientAPI_1();
150
+ api.selectStory(index);
151
+ api.onStoryRendered(resolve);
152
+ } catch (ex) {
153
+ resolve({message: ex.message, version: api ? api.version : undefined});
154
+ }
155
+ });
141
156
  }
142
157
 
143
158
  var renderStoryWithClientAPI_1 = renderStoryWithClientAPI;
@@ -38,7 +38,15 @@ function __runRunAfterScript(...args) {
38
38
  throw new Error("Cannot get client API: couldn't detect storybook version");
39
39
  }
40
40
  }
41
-
41
+ function onStoryRendered(callback) {
42
+ if (addons && addons.channel && addons.channel.once) {
43
+ addons.channel.once('storyRendered', () => {
44
+ setTimeout(callback, 0);
45
+ });
46
+ } else {
47
+ callback();
48
+ }
49
+ }
42
50
  function getAPI(version) {
43
51
  if (version) {
44
52
  let api;
@@ -57,6 +65,7 @@ function __runRunAfterScript(...args) {
57
65
  const {kind, name: story} = api.getStories()[i];
58
66
  addons.channel._listeners.setCurrentStory[0]({kind, story});
59
67
  },
68
+ onStoryRendered,
60
69
  };
61
70
  break;
62
71
  }
@@ -69,6 +78,7 @@ function __runRunAfterScript(...args) {
69
78
  selectStory: i => {
70
79
  clientAPI._storyStore.setSelection(clientAPI.raw()[i]);
71
80
  },
81
+ onStoryRendered,
72
82
  };
73
83
  break;
74
84
  }
@@ -81,6 +91,7 @@ function __runRunAfterScript(...args) {
81
91
  selectStory: i => {
82
92
  frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id});
83
93
  },
94
+ onStoryRendered,
84
95
  };
85
96
  break;
86
97
  }
@@ -96,6 +107,7 @@ function __runRunAfterScript(...args) {
96
107
  });
97
108
  await frameWindow.__STORYBOOK_PREVIEW__.renderSelection();
98
109
  },
110
+ onStoryRendered,
99
111
  };
100
112
  break;
101
113
  }
@@ -38,7 +38,15 @@ function __runRunBeforeScript(...args) {
38
38
  throw new Error("Cannot get client API: couldn't detect storybook version");
39
39
  }
40
40
  }
41
-
41
+ function onStoryRendered(callback) {
42
+ if (addons && addons.channel && addons.channel.once) {
43
+ addons.channel.once('storyRendered', () => {
44
+ setTimeout(callback, 0);
45
+ });
46
+ } else {
47
+ callback();
48
+ }
49
+ }
42
50
  function getAPI(version) {
43
51
  if (version) {
44
52
  let api;
@@ -57,6 +65,7 @@ function __runRunBeforeScript(...args) {
57
65
  const {kind, name: story} = api.getStories()[i];
58
66
  addons.channel._listeners.setCurrentStory[0]({kind, story});
59
67
  },
68
+ onStoryRendered,
60
69
  };
61
70
  break;
62
71
  }
@@ -69,6 +78,7 @@ function __runRunBeforeScript(...args) {
69
78
  selectStory: i => {
70
79
  clientAPI._storyStore.setSelection(clientAPI.raw()[i]);
71
80
  },
81
+ onStoryRendered,
72
82
  };
73
83
  break;
74
84
  }
@@ -81,6 +91,7 @@ function __runRunBeforeScript(...args) {
81
91
  selectStory: i => {
82
92
  frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id});
83
93
  },
94
+ onStoryRendered,
84
95
  };
85
96
  break;
86
97
  }
@@ -96,6 +107,7 @@ function __runRunBeforeScript(...args) {
96
107
  });
97
108
  await frameWindow.__STORYBOOK_PREVIEW__.renderSelection();
98
109
  },
110
+ onStoryRendered,
99
111
  };
100
112
  break;
101
113
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-storybook",
3
- "version": "3.27.4",
3
+ "version": "3.28.0",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=8.6.0"
@@ -15,15 +15,20 @@
15
15
  },
16
16
  "scripts": {
17
17
  "test": "yarn build && yarn test:mocha && yarn lint",
18
- "test:mocha": "mocha --no-timeouts --trace-warnings 'test/unit/*.test.js' 'test/it/*.test.js' 'test/e2e/*.test.js'",
19
- "test:unit": "mocha --no-timeouts --trace-warnings 'test/unit/*.test.js'",
20
- "test:it": "mocha --no-timeouts --trace-warnings 'test/it/*.test.js'",
21
- "test:e2e": "mocha --no-timeouts --trace-warnings 'test/e2e/*.test.js'",
18
+ "test:versions": "yarn build && yarn test:e2e:versions && yarn lint",
19
+ "test:mocha": "yarn test:unit && yarn test:it && yarn test:e2e",
20
+ "test:unit": "STDOUT_LEVEL=0 mocha --no-timeouts --trace-warnings 'test/unit/*.test.js'",
21
+ "test:it": "STDOUT_LEVEL=1 mocha --no-timeouts --trace-warnings 'test/it/*.test.js'",
22
+ "test:e2e": "mocha --no-timeouts --trace-warnings 'test/e2e/*.e2e.test.js'",
23
+ "test:e2e:versions": "npx mocha --no-timeouts --trace-warnings --require test/fixtures/storybook-versions/mochaHooks.js test/e2e/*.e2e.versions.test.js",
24
+ "test:e2e:versions_local": "STORYBOOK_VERSION=latest npx mocha --no-timeouts --trace-warnings --require test/fixtures/storybook-versions/mochaHooks.js test/e2e/*.e2e.versions.test.js",
22
25
  "build": "rollup -c rollup.config.js",
23
26
  "build:heavy": "node scripts/bitmap.js",
24
27
  "lint": "eslint '**/*.js'",
25
28
  "storybook": "start-storybook -c test/fixtures/appWithStorybook -p 9001 -s test/fixtures",
26
29
  "storybook:jslayout": "start-storybook -c test/fixtures/jsLayoutStorybookLocal -p 9001 -s test/fixtures",
30
+ "storybook:csf": "yarn storybook:csf-service && start-storybook -c test/fixtures/storybookCSF/.storybook-temp -p 9001",
31
+ "storybook:csf-service": "cp -r test/fixtures/storybookCSF/.storybook/. test/fixtures/storybookCSF/.storybook-temp && rm test/fixtures/storybookCSF/.storybook-temp/config.js",
27
32
  "storybook:heavy": "start-storybook -c test/fixtures/heavyStorybook -p 9002 -s test/fixtures",
28
33
  "storybook:zeroStories": "start-storybook -c test/fixtures/zeroStoriesRetry -p 9003 -s test/fixtures",
29
34
  "eyes-storybook": "node bin/eyes-storybook.js -f test/fixtures/applitools.config.js",
@@ -36,8 +41,8 @@
36
41
  "changelog:install": "sudo apt-get install git-extras",
37
42
  "gh:publish": "gh workflow run publish-storybook.yml --ref $(git rev-parse --abbrev-ref HEAD)",
38
43
  "postinstall": "node src/postinstall",
39
- "preversion": "bongo preversion",
40
- "version": "bongo version",
44
+ "preversion": "bongo preversion --verifyPendingChanges",
45
+ "version": "bongo version --withPendingChanges",
41
46
  "postversion": "bongo postversion --skip-release-notification",
42
47
  "deps": "bongo deps",
43
48
  "prepublish:setup": "echo 'setup is a no-op. Move along, nothing to see here.'"
@@ -59,15 +64,15 @@
59
64
  "directory": "packages/eyes-storybook"
60
65
  },
61
66
  "dependencies": {
62
- "@applitools/driver": "1.4.12",
63
- "@applitools/eyes-sdk-core": "13.0.2",
67
+ "@applitools/driver": "1.8.12",
68
+ "@applitools/eyes-sdk-core": "13.6.21",
64
69
  "@applitools/functional-commons": "1.6.0",
65
- "@applitools/logger": "1.0.10",
70
+ "@applitools/logger": "1.1.5",
66
71
  "@applitools/monitoring-commons": "1.0.19",
67
- "@applitools/spec-driver-puppeteer": "1.1.0",
68
- "@applitools/test-server": "1.0.8",
69
- "@applitools/utils": "1.2.12",
70
- "@applitools/visual-grid-client": "15.8.63",
72
+ "@applitools/spec-driver-puppeteer": "1.1.2",
73
+ "@applitools/test-server": "1.0.9",
74
+ "@applitools/utils": "1.3.0",
75
+ "@applitools/visual-grid-client": "15.12.33",
71
76
  "boxen": "4.2.0",
72
77
  "chalk": "3.0.0",
73
78
  "detect-port": "1.3.0",
@@ -79,11 +84,13 @@
79
84
  "yargs": "15.4.1"
80
85
  },
81
86
  "devDependencies": {
87
+ "@applitools/bongo": "^2.1.0",
82
88
  "@applitools/scripts": "^1.1.0",
83
- "@applitools/sdk-release-kit": "0.13.11",
84
89
  "@applitools/sdk-shared": "0.9.11",
85
90
  "@applitools/snaptdout": "^1.0.1",
86
- "@storybook/react": "^6.4.0",
91
+ "@storybook/addon-interactions": "^6.4.18",
92
+ "@storybook/react": "^6.4.18",
93
+ "@storybook/testing-library": "^0.0.9",
87
94
  "@testing-library/dom": "^5.6.1",
88
95
  "babel-core": "^6.26.3",
89
96
  "babel-loader": "^8.0.6",
@@ -35,7 +35,15 @@ function getClientAPI() {
35
35
  throw new Error("Cannot get client API: couldn't detect storybook version");
36
36
  }
37
37
  }
38
-
38
+ function onStoryRendered(callback) {
39
+ if (addons && addons.channel && addons.channel.once) {
40
+ addons.channel.once('storyRendered', () => {
41
+ setTimeout(callback, 0);
42
+ });
43
+ } else {
44
+ callback();
45
+ }
46
+ }
39
47
  function getAPI(version) {
40
48
  if (version) {
41
49
  let api;
@@ -54,6 +62,7 @@ function getClientAPI() {
54
62
  const {kind, name: story} = api.getStories()[i];
55
63
  addons.channel._listeners.setCurrentStory[0]({kind, story});
56
64
  },
65
+ onStoryRendered,
57
66
  };
58
67
  break;
59
68
  }
@@ -66,6 +75,7 @@ function getClientAPI() {
66
75
  selectStory: i => {
67
76
  clientAPI._storyStore.setSelection(clientAPI.raw()[i]);
68
77
  },
78
+ onStoryRendered,
69
79
  };
70
80
  break;
71
81
  }
@@ -78,6 +88,7 @@ function getClientAPI() {
78
88
  selectStory: i => {
79
89
  frameWindow.__STORYBOOK_STORY_STORE__.setSelection({storyId: clientAPI.raw()[i].id});
80
90
  },
91
+ onStoryRendered,
81
92
  };
82
93
  break;
83
94
  }
@@ -93,6 +104,7 @@ function getClientAPI() {
93
104
  });
94
105
  await frameWindow.__STORYBOOK_PREVIEW__.renderSelection();
95
106
  },
107
+ onStoryRendered,
96
108
  };
97
109
  break;
98
110
  }
@@ -129,9 +129,10 @@ async function getStories({timeout = DEFAULT_TIMEOUT} = {timeout: DEFAULT_TIMEOU
129
129
  }
130
130
  }
131
131
  }
132
-
132
+ const hasPlayFunction = !!story.playFunction;
133
133
  return {
134
134
  isApi: true,
135
+ hasPlayFunction,
135
136
  index,
136
137
  name,
137
138
  kind,
@@ -1,13 +1,16 @@
1
1
  const getClientAPI = require('./getClientAPI');
2
2
 
3
- async function renderStoryWithClientAPI(index) {
4
- let api;
5
- try {
6
- api = getClientAPI();
7
- await api.selectStory(index);
8
- } catch (ex) {
9
- return {message: ex.message, version: api ? api.version : undefined};
10
- }
3
+ function renderStoryWithClientAPI(index) {
4
+ return new Promise(resolve => {
5
+ let api;
6
+ try {
7
+ api = getClientAPI();
8
+ api.selectStory(index);
9
+ api.onStoryRendered(resolve);
10
+ } catch (ex) {
11
+ resolve({message: ex.message, version: api ? api.version : undefined});
12
+ }
13
+ });
11
14
  }
12
15
 
13
16
  module.exports = renderStoryWithClientAPI;
@@ -65,7 +65,7 @@ async function eyesStorybook({
65
65
  } = makeVisualGridClient({
66
66
  userAgent,
67
67
  ...config,
68
- logger: logger.extend('vgc'),
68
+ logger: logger.extend({label: 'vgc'}),
69
69
  });
70
70
 
71
71
  const initPage = makeInitPage({
@@ -130,7 +130,7 @@ async function eyesStorybook({
130
130
  });
131
131
 
132
132
  const renderStory = makeRenderStory({
133
- logger: logger.extend('renderStory'),
133
+ logger: logger.extend({label: 'renderStory'}),
134
134
  testWindow,
135
135
  performance,
136
136
  timeItAsync,
@@ -2,7 +2,8 @@
2
2
  const {URL} = require('url');
3
3
 
4
4
  function getIframeUrl(baseUrl) {
5
- const {origin, pathname} = new URL(baseUrl);
5
+ const {origin, pathname, search} = new URL(baseUrl);
6
+ const searchParam = search && search.replace(/^\?/, '&');
6
7
 
7
8
  let baseUrlFixed = `${origin}${pathname.replace(/\/[^\/]+\.html/, '')}`;
8
9
 
@@ -10,7 +11,10 @@ function getIframeUrl(baseUrl) {
10
11
  baseUrlFixed += '/';
11
12
  }
12
13
 
13
- const url = new URL(`iframe.html?eyes-storybook=true`, baseUrlFixed);
14
+ const url = new URL(
15
+ `iframe.html?eyes-storybook=true${searchParam ? searchParam : ''}`,
16
+ baseUrlFixed,
17
+ );
14
18
  return url.href;
15
19
  }
16
20
 
@@ -5,7 +5,7 @@ const {deprecationWarning} = require('@applitools/eyes-sdk-core').GeneralUtils;
5
5
 
6
6
  function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
7
7
  return function renderStory({config, story, snapshot, url}) {
8
- const {name, kind, parameters} = story;
8
+ const {name, kind, parameters, hasPlayFunction} = story;
9
9
  const baselineName = getStoryBaselineName({name, kind, parameters});
10
10
  const title = getStoryTitle({name, kind, parameters});
11
11
  const eyesParameters = (parameters && parameters.eyes) || {};
@@ -55,6 +55,9 @@ function makeRenderStory({logger, testWindow, performance, timeItAsync}) {
55
55
  {name: 'State', value: name},
56
56
  ...(properties || []),
57
57
  ];
58
+ if (hasPlayFunction) {
59
+ storyProperties.push({name: 'Storybook play function', value: 'true'});
60
+ }
58
61
 
59
62
  const openParams = {
60
63
  testName: baselineName,