@applitools/eyes-storybook 3.62.3 → 3.63.2

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,96 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.63.2](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.63.1...js/eyes-storybook@3.63.2) (2025-12-07)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * @applitools/dom-snapshot bumped to 4.15.3
9
+ #### Bug Fixes
10
+
11
+ * capture JavaScript-modified CSS selectors in nested [@layer](https://github.com/layer) rules ([#3391](https://github.com/Applitools-Dev/sdk/issues/3391)) ([b3bceb5](https://github.com/Applitools-Dev/sdk/commit/b3bceb5bfe894f3548173d23942e09d0e04b7e04))
12
+ * @applitools/core bumped to 4.53.2
13
+ #### Bug Fixes
14
+
15
+ * Upgrade core version ([#3398](https://github.com/Applitools-Dev/sdk/issues/3398)) ([68858c7](https://github.com/Applitools-Dev/sdk/commit/68858c7024e0413c1cc6af68752b1c3a9a04bb0b))
16
+
17
+
18
+
19
+ * @applitools/eyes bumped to 1.36.17
20
+ #### Bug Fixes
21
+
22
+ * capture JavaScript-modified CSS selectors in nested [@layer](https://github.com/layer) rules ([#3391](https://github.com/Applitools-Dev/sdk/issues/3391)) ([b3bceb5](https://github.com/Applitools-Dev/sdk/commit/b3bceb5bfe894f3548173d23942e09d0e04b7e04))
23
+
24
+
25
+
26
+
27
+ ## [3.63.1](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.63.0...js/eyes-storybook@3.63.1) (2025-12-01)
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * client detection ([#3390](https://github.com/Applitools-Dev/sdk/issues/3390)) ([b4c11d8](https://github.com/Applitools-Dev/sdk/commit/b4c11d822ea9d176093f539313ce54942343249c))
33
+ * setup script compatibility with ESM | AD-11756 ([#3363](https://github.com/Applitools-Dev/sdk/issues/3363)) ([d1222f4](https://github.com/Applitools-Dev/sdk/commit/d1222f40a74ab62782bebeeb0cf899aac3f3d3b6))
34
+ * stories detection | FLD-3856 ([#3382](https://github.com/Applitools-Dev/sdk/issues/3382)) ([5fdf25a](https://github.com/Applitools-Dev/sdk/commit/5fdf25ab738a3e852b290d2ae96614bb5c18f7c7))
35
+ * storybook started detection | AD-12069 ([#3387](https://github.com/Applitools-Dev/sdk/issues/3387)) ([8f06ab1](https://github.com/Applitools-Dev/sdk/commit/8f06ab10e191a7f0602db07b4cb6925f4b403607))
36
+
37
+
38
+ ### Dependencies
39
+
40
+ * @applitools/utils bumped to 1.14.1
41
+ #### Bug Fixes
42
+
43
+ * setup script compatibility with ESM | AD-11756 ([#3363](https://github.com/Applitools-Dev/sdk/issues/3363)) ([d1222f4](https://github.com/Applitools-Dev/sdk/commit/d1222f40a74ab62782bebeeb0cf899aac3f3d3b6))
44
+ * @applitools/logger bumped to 2.2.7
45
+
46
+ * @applitools/dom-snapshot bumped to 4.15.2
47
+ #### Bug Fixes
48
+
49
+ * handle CSS variables in Shadow DOM adopted stylesheets | FLD-3790 ([#3381](https://github.com/Applitools-Dev/sdk/issues/3381)) ([b2bfca3](https://github.com/Applitools-Dev/sdk/commit/b2bfca3cd706cd996d78d51c6242148fbb8ce741))
50
+
51
+
52
+
53
+ * @applitools/socket bumped to 1.3.8
54
+
55
+ * @applitools/req bumped to 1.8.7
56
+
57
+ * @applitools/image bumped to 1.2.6
58
+
59
+ * @applitools/driver bumped to 1.24.3
60
+
61
+ * @applitools/spec-driver-webdriver bumped to 1.5.3
62
+
63
+ * @applitools/spec-driver-selenium bumped to 1.7.9
64
+
65
+ * @applitools/spec-driver-puppeteer bumped to 1.6.9
66
+
67
+ * @applitools/screenshoter bumped to 3.12.10
68
+
69
+ * @applitools/nml-client bumped to 1.11.12
70
+
71
+ * @applitools/tunnel-client bumped to 1.11.5
72
+
73
+ * @applitools/ufg-client bumped to 1.18.3
74
+
75
+ * @applitools/core-base bumped to 1.30.1
76
+
77
+ * @applitools/ec-client bumped to 1.12.14
78
+
79
+ * @applitools/core bumped to 4.53.1
80
+ #### Bug Fixes
81
+
82
+ * handle CSS variables in Shadow DOM adopted stylesheets | FLD-3790 ([#3381](https://github.com/Applitools-Dev/sdk/issues/3381)) ([b2bfca3](https://github.com/Applitools-Dev/sdk/commit/b2bfca3cd706cd996d78d51c6242148fbb8ce741))
83
+
84
+
85
+
86
+
87
+ ## [3.63.0](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.62.3...js/eyes-storybook@3.63.0) (2025-11-24)
88
+
89
+
90
+ ### Features
91
+
92
+ * "Story" custom property | AD-10146 ([#3372](https://github.com/Applitools-Dev/sdk/issues/3372)) ([af2e5fe](https://github.com/Applitools-Dev/sdk/commit/af2e5fe8beb7beeb6bbf13e364138894ee27a866))
93
+
3
94
  ## [3.62.3](https://github.com/Applitools-Dev/sdk/compare/js/eyes-storybook@3.62.2...js/eyes-storybook@3.62.3) (2025-11-19)
4
95
 
5
96
 
@@ -169,13 +169,19 @@ function __getClientAPI(...args) {
169
169
  }
170
170
 
171
171
  function getFrameWindow() {
172
- if (/iframe.html/.test(window.location.href)) {
172
+ if (
173
+ (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) ||
174
+ /iframe\.html/.test(window.location.href)
175
+ ) {
173
176
  return window;
174
177
  }
175
178
 
176
179
  const innerFrameWindow = Array.prototype.find.call(window.frames, frame => {
177
180
  try {
178
- return /\/iframe.html/.test(frame.location.href);
181
+ return (
182
+ (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) ||
183
+ /\/iframe\.html/.test(frame.location.href)
184
+ );
179
185
  } catch (e) {}
180
186
  });
181
187
 
@@ -183,7 +189,8 @@ function __getClientAPI(...args) {
183
189
  return innerFrameWindow;
184
190
  }
185
191
 
186
- if (window.__STORYBOOK_CLIENT_API__) {
192
+ // frame.location.href might not be 'iframe' but still be the correct one
193
+ if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) {
187
194
  return window;
188
195
  }
189
196
 
@@ -169,13 +169,19 @@ function __getStories(...args) {
169
169
  }
170
170
 
171
171
  function getFrameWindow() {
172
- if (/iframe.html/.test(window.location.href)) {
172
+ if (
173
+ (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) ||
174
+ /iframe\.html/.test(window.location.href)
175
+ ) {
173
176
  return window;
174
177
  }
175
178
 
176
179
  const innerFrameWindow = Array.prototype.find.call(window.frames, frame => {
177
180
  try {
178
- return /\/iframe.html/.test(frame.location.href);
181
+ return (
182
+ (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) ||
183
+ /\/iframe\.html/.test(frame.location.href)
184
+ );
179
185
  } catch (e) {}
180
186
  });
181
187
 
@@ -183,7 +189,8 @@ function __getStories(...args) {
183
189
  return innerFrameWindow;
184
190
  }
185
191
 
186
- if (window.__STORYBOOK_CLIENT_API__) {
192
+ // frame.location.href might not be 'iframe' but still be the correct one
193
+ if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) {
187
194
  return window;
188
195
  }
189
196
 
@@ -169,13 +169,19 @@ function __renderStoryWithClientAPI(...args) {
169
169
  }
170
170
 
171
171
  function getFrameWindow() {
172
- if (/iframe.html/.test(window.location.href)) {
172
+ if (
173
+ (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) ||
174
+ /iframe\.html/.test(window.location.href)
175
+ ) {
173
176
  return window;
174
177
  }
175
178
 
176
179
  const innerFrameWindow = Array.prototype.find.call(window.frames, frame => {
177
180
  try {
178
- return /\/iframe.html/.test(frame.location.href);
181
+ return (
182
+ (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) ||
183
+ /\/iframe\.html/.test(frame.location.href)
184
+ );
179
185
  } catch (e) {}
180
186
  });
181
187
 
@@ -183,7 +189,8 @@ function __renderStoryWithClientAPI(...args) {
183
189
  return innerFrameWindow;
184
190
  }
185
191
 
186
- if (window.__STORYBOOK_CLIENT_API__) {
192
+ // frame.location.href might not be 'iframe' but still be the correct one
193
+ if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) {
187
194
  return window;
188
195
  }
189
196
 
@@ -169,13 +169,19 @@ function __runRunAfterScript(...args) {
169
169
  }
170
170
 
171
171
  function getFrameWindow() {
172
- if (/iframe.html/.test(window.location.href)) {
172
+ if (
173
+ (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) ||
174
+ /iframe\.html/.test(window.location.href)
175
+ ) {
173
176
  return window;
174
177
  }
175
178
 
176
179
  const innerFrameWindow = Array.prototype.find.call(window.frames, frame => {
177
180
  try {
178
- return /\/iframe.html/.test(frame.location.href);
181
+ return (
182
+ (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) ||
183
+ /\/iframe\.html/.test(frame.location.href)
184
+ );
179
185
  } catch (e) {}
180
186
  });
181
187
 
@@ -183,7 +189,8 @@ function __runRunAfterScript(...args) {
183
189
  return innerFrameWindow;
184
190
  }
185
191
 
186
- if (window.__STORYBOOK_CLIENT_API__) {
192
+ // frame.location.href might not be 'iframe' but still be the correct one
193
+ if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) {
187
194
  return window;
188
195
  }
189
196
 
@@ -169,13 +169,19 @@ function __runRunBeforeScript(...args) {
169
169
  }
170
170
 
171
171
  function getFrameWindow() {
172
- if (/iframe.html/.test(window.location.href)) {
172
+ if (
173
+ (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) ||
174
+ /iframe\.html/.test(window.location.href)
175
+ ) {
173
176
  return window;
174
177
  }
175
178
 
176
179
  const innerFrameWindow = Array.prototype.find.call(window.frames, frame => {
177
180
  try {
178
- return /\/iframe.html/.test(frame.location.href);
181
+ return (
182
+ (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) ||
183
+ /\/iframe\.html/.test(frame.location.href)
184
+ );
179
185
  } catch (e) {}
180
186
  });
181
187
 
@@ -183,7 +189,8 @@ function __runRunBeforeScript(...args) {
183
189
  return innerFrameWindow;
184
190
  }
185
191
 
186
- if (window.__STORYBOOK_CLIENT_API__) {
192
+ // frame.location.href might not be 'iframe' but still be the correct one
193
+ if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) {
187
194
  return window;
188
195
  }
189
196
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-storybook",
3
- "version": "3.62.3",
3
+ "version": "3.63.2",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "applitools",
@@ -59,15 +59,15 @@
59
59
  "up:framework": "cd test/fixtures/storybook-versions/${APPLITOOLS_FRAMEWORK_VERSION} && npm ci"
60
60
  },
61
61
  "dependencies": {
62
- "@applitools/core": "4.53.0",
63
- "@applitools/driver": "1.24.2",
64
- "@applitools/eyes": "1.36.16",
62
+ "@applitools/core": "4.53.2",
63
+ "@applitools/driver": "1.24.3",
64
+ "@applitools/eyes": "1.36.17",
65
65
  "@applitools/functional-commons": "1.6.0",
66
- "@applitools/logger": "2.2.6",
66
+ "@applitools/logger": "2.2.7",
67
67
  "@applitools/monitoring-commons": "1.0.19",
68
- "@applitools/spec-driver-puppeteer": "1.6.8",
69
- "@applitools/ufg-client": "1.18.2",
70
- "@applitools/utils": "1.14.0",
68
+ "@applitools/spec-driver-puppeteer": "1.6.9",
69
+ "@applitools/ufg-client": "1.18.3",
70
+ "@applitools/utils": "1.14.1",
71
71
  "@inquirer/prompts": "7.0.1",
72
72
  "boxen": "4.2.0",
73
73
  "chalk": "3.0.0",
@@ -166,13 +166,19 @@ function getClientAPI() {
166
166
  }
167
167
 
168
168
  function getFrameWindow() {
169
- if (/iframe.html/.test(window.location.href)) {
169
+ if (
170
+ (/iframe/.test(window.location.href) && window.__STORYBOOK_PREVIEW__) ||
171
+ /iframe\.html/.test(window.location.href)
172
+ ) {
170
173
  return window;
171
174
  }
172
175
 
173
176
  const innerFrameWindow = Array.prototype.find.call(window.frames, frame => {
174
177
  try {
175
- return /\/iframe.html/.test(frame.location.href);
178
+ return (
179
+ (/\/iframe/.test(frame.location.href) && frame.__STORYBOOK_PREVIEW__) ||
180
+ /\/iframe\.html/.test(frame.location.href)
181
+ );
176
182
  } catch (e) {}
177
183
  });
178
184
 
@@ -180,7 +186,8 @@ function getFrameWindow() {
180
186
  return innerFrameWindow;
181
187
  }
182
188
 
183
- if (window.__STORYBOOK_CLIENT_API__) {
189
+ // frame.location.href might not be 'iframe' but still be the correct one
190
+ if (window.__STORYBOOK_CLIENT_API__ || window.__STORYBOOK_PREVIEW__) {
184
191
  return window;
185
192
  }
186
193
 
package/src/eyes-setup.js CHANGED
@@ -42,7 +42,7 @@ function handleError(asyncFunc) {
42
42
  async function init(args) {
43
43
  log(chalk.yellow('Setting up Eyes-Storybook for your project:'));
44
44
 
45
- let {config, fileName, isCorrupted} = await loadExistingConfig();
45
+ let {config, fileName, isCorrupted, isESM} = await loadExistingConfig();
46
46
 
47
47
  if (isCorrupted) {
48
48
  log(chalk.yellow(`\nWarning: Your configuration file '${fileName}' appears to be corrupted.`));
@@ -118,7 +118,7 @@ async function init(args) {
118
118
  showLogs: false,
119
119
  };
120
120
 
121
- const fileContent = generateConfigContent();
121
+ const fileContent = generateConfigContent(isESM);
122
122
  await fs.writeFile(fileName, fileContent, 'utf8');
123
123
  }
124
124
 
@@ -138,24 +138,35 @@ async function init(args) {
138
138
  try {
139
139
  const fileUrl = pathToFileURL(file).href;
140
140
  const module = await import(`${fileUrl}?t=${Date.now()}`); // Append timestamp to bypass cache
141
+ const isESM = file.endsWith('.mjs');
141
142
 
142
- return {config: module.default || module, fileName: file, isCorrupted: false};
143
+ return {config: module.default || module, fileName: file, isCorrupted: false, isESM};
143
144
  } catch (err) {
144
145
  if (err.code === 'ERR_MODULE_NOT_FOUND') {
145
- // This file doesn't exist, so we continue searching for the one that does.
146
146
  continue;
147
147
  }
148
-
149
148
  return {config: null, fileName: file, isCorrupted: true};
150
149
  }
151
150
  }
152
151
 
153
152
  // No file was found in any of the possible locations.
154
- // We return a default filename for a new file to be created.
155
- return {config: null, fileName: 'applitools.config.js', isCorrupted: false};
153
+ // Check if type: module is set in package.json in cwd
154
+ let fileName = 'applitools.config.js';
155
+ let isESM = false;
156
+ try {
157
+ const pkgRaw = await fs.readFile('./package.json', 'utf8');
158
+ const pkg = JSON.parse(pkgRaw);
159
+ if (pkg.type === 'module') {
160
+ isESM = true;
161
+ fileName = 'applitools.config.mjs';
162
+ }
163
+ } catch (e) {
164
+ // ignore if package.json not found or invalid
165
+ }
166
+ return {config: null, fileName, isCorrupted: false, isESM};
156
167
  }
157
168
 
158
- function generateConfigContent() {
169
+ function generateConfigContent(isESM) {
159
170
  const envConfigMap = {
160
171
  batchName: 'APPLITOOLS_BATCH_NAME',
161
172
  batchId: 'APPLITOOLS_BATCH_ID',
@@ -169,7 +180,7 @@ async function init(args) {
169
180
 
170
181
  const configLines = [];
171
182
 
172
- // Handle apiKey
183
+ // apiKey
173
184
  if (apiKey === 'process.env.APPLITOOLS_API_KEY') {
174
185
  configLines.push('apiKey: process.env.APPLITOOLS_API_KEY,');
175
186
  } else if (apiKey) {
@@ -177,17 +188,17 @@ async function init(args) {
177
188
  `apiKey: '${apiKey}', // Warning: 'apiKey' is not obscured, consider setting it via environment variable APPLITOOLS_API_KEY`,
178
189
  );
179
190
  } else {
180
- configLines.push(`// apiKey: '',`);
191
+ configLines.push("// apiKey: '',");
181
192
  }
182
193
 
183
- // Handle serverUrl
194
+ // serverUrl
184
195
  if (serverUrl && serverUrl.startsWith('process.env.')) {
185
196
  configLines.push(`serverUrl: ${serverUrl},`);
186
197
  } else if (serverUrl) {
187
198
  configLines.push(`serverUrl: '${serverUrl}',`);
188
199
  }
189
200
 
190
- // Handle other config lines by prioritizing env vars over defaults
201
+ // other config
191
202
  const otherKeys = [
192
203
  'appName',
193
204
  'batchName',
@@ -200,35 +211,34 @@ async function init(args) {
200
211
  'navigationWaitUntil',
201
212
  'waitBeforeCapture',
202
213
  ];
203
-
204
214
  for (const key of otherKeys) {
205
215
  const envVar = envConfigMap[key];
206
- // Check if an environment variable for this key is set
207
216
  if (envVar && utils.general.getEnvValue(envVar.replace('APPLITOOLS_', ''))) {
208
217
  configLines.push(`${key}: process.env.${envVar},`);
209
218
  } else if (Object.prototype.hasOwnProperty.call(config, key)) {
210
- // Otherwise, use the default value from the config object
211
219
  const value = config[key];
212
220
  if (value !== undefined) {
213
- const line = typeof value === 'string' ? `${key}: '${value}',` : `${key}: ${value},`;
214
- configLines.push(line);
221
+ configLines.push(typeof value === 'string' ? `${key}: '${value}',` : `${key}: ${value},`);
215
222
  }
216
223
  }
217
224
  }
218
225
 
219
- return `/**
220
- * @type {import('@applitools/eyes-storybook').ApplitoolsConfig}
221
- **/
222
- module.exports = {
223
- ${configLines.join('\n ')}
224
- // browsersInfo: [
226
+ configLines.push(`// browsersInfo: [
225
227
  // {width: 1024, height: 768, name: 'firefox'},
226
228
  // {width: 1024, height: 768, name: 'chrome'},
227
229
  // {iosDeviceInfo: {deviceName: 'iPhone 16'}},
228
230
  // {chromeEmulationInfo: {deviceName: 'Galaxy S20'}},
229
- // ]
230
- };
231
- `;
231
+ // ]`);
232
+
233
+ const configObject = `{
234
+ ${configLines.join('\n ')}
235
+ }`;
236
+
237
+ if (isESM) {
238
+ return `/**\n * @type {import('@applitools/eyes-storybook').ApplitoolsConfig}\n */\nconst config = ${configObject};\nexport default config;\n`;
239
+ } else {
240
+ return `/**\n * @type {import('@applitools/eyes-storybook').ApplitoolsConfig}\n **/\nmodule.exports = ${configObject};\n`;
241
+ }
232
242
  }
233
243
 
234
244
  function printPostlude() {
@@ -77,7 +77,7 @@ class StorybookConnector extends EventEmitter {
77
77
 
78
78
  const successMessageListener = str => {
79
79
  const isReady = stripAnsi(str).match(
80
- /Storybook \d{1,2}\.\d{1,2}\.\d{1,2}(.+)? started|Storybook started on =>/,
80
+ /Storybook \d{1,2}\.\d{1,2}\.\d{1,2}(.+)? started|Storybook started on =>|Storybook ready/,
81
81
  );
82
82
 
83
83
  if (isReady) {
@@ -21,6 +21,7 @@ function storyToOpenSettings({story, appName, serverSettings, concurrency}) {
21
21
  const storyProperties = [
22
22
  {name: 'Component name', value: kind},
23
23
  {name: 'State', value: name},
24
+ {name: 'Story', value: name},
24
25
  ...(properties || []),
25
26
  ];
26
27
  if (hasPlayFunction) {
@@ -84,10 +84,14 @@ const storybookSpecificKeys = [
84
84
  'packagePath',
85
85
  ];
86
86
 
87
+ // Keys that are automatically added by module systems for ES modules.
88
+ const esModuleSpecificKeys = ['__esModule', 'default'];
89
+
87
90
  // Combine all known keys into a single Set for efficient O(1) lookups.
88
91
  const knownKeys = new Set([
89
92
  ...storybookSpecificKeys,
90
93
  ...applitoolsBaseKeys,
94
+ ...esModuleSpecificKeys,
91
95
  ...Object.keys(defaultConfig),
92
96
  ]);
93
97