@applitools/eyes-cypress 3.60.8 → 3.60.10
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 +88 -0
- package/package.json +4 -4
- package/src/browser/commands.js +16 -78
- package/types/expose.d.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.60.10](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.60.9...js/eyes-cypress@3.60.10) (2026-07-21)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* revert per-test diff-attribution afterEach getResults | FLD-4628 ([#4001](https://github.com/Applitools-Dev/sdk/issues/4001)) ([9bb8811](https://github.com/Applitools-Dev/sdk/commit/9bb88118532ed60ea985e77f7d93e147a72caa12))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* @applitools/dom-shared bumped to 1.2.2
|
|
14
|
+
#### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* CSP-safe sandbox opt-out for the MV3 extension content script | AD-14808 ([#3969](https://github.com/Applitools-Dev/sdk/issues/3969)) ([772aefa](https://github.com/Applitools-Dev/sdk/commit/772aefaa3e2bc1eb345fa8d3f6c91ad0913f82e7))
|
|
17
|
+
* @applitools/core-base bumped to 1.36.2
|
|
18
|
+
#### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* guard logEventBatch against a logger-less event ([#4007](https://github.com/Applitools-Dev/sdk/issues/4007)) ([bb8c9b2](https://github.com/Applitools-Dev/sdk/commit/bb8c9b242801e08dd573a77e261d5fb4540cd68e))
|
|
21
|
+
* @applitools/dom-snapshot bumped to 4.17.6
|
|
22
|
+
|
|
23
|
+
* @applitools/snippets bumped to 2.9.4
|
|
24
|
+
#### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* bound lazyLoad scroll loop to prevent poll-timeout abort | FLD-4680 ([#3972](https://github.com/Applitools-Dev/sdk/issues/3972)) ([4deea6b](https://github.com/Applitools-Dev/sdk/commit/4deea6b1f6f8ec53bd989cd6bbd021cac2ee3c1e))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
* @applitools/dom-capture bumped to 11.8.4
|
|
31
|
+
|
|
32
|
+
* @applitools/driver bumped to 1.26.6
|
|
33
|
+
|
|
34
|
+
* @applitools/spec-driver-webdriver bumped to 1.6.6
|
|
35
|
+
|
|
36
|
+
* @applitools/spec-driver-selenium bumped to 1.8.6
|
|
37
|
+
|
|
38
|
+
* @applitools/spec-driver-playwright bumped to 1.9.6
|
|
39
|
+
|
|
40
|
+
* @applitools/spec-driver-puppeteer bumped to 1.8.6
|
|
41
|
+
|
|
42
|
+
* @applitools/screenshoter bumped to 3.12.25
|
|
43
|
+
|
|
44
|
+
* @applitools/nml-client bumped to 1.11.36
|
|
45
|
+
|
|
46
|
+
* @applitools/ec-client bumped to 1.12.38
|
|
47
|
+
|
|
48
|
+
* @applitools/core bumped to 4.66.2
|
|
49
|
+
#### Bug Fixes
|
|
50
|
+
|
|
51
|
+
* bound lazyLoad scroll loop to prevent poll-timeout abort | FLD-4680 ([#3972](https://github.com/Applitools-Dev/sdk/issues/3972)) ([4deea6b](https://github.com/Applitools-Dev/sdk/commit/4deea6b1f6f8ec53bd989cd6bbd021cac2ee3c1e))
|
|
52
|
+
* send the old-infra retry in its check's slot | AD-14675 ([#3968](https://github.com/Applitools-Dev/sdk/issues/3968)) ([946b926](https://github.com/Applitools-Dev/sdk/commit/946b92632a511f1ed23f2f65d0382ef8d7177ea7))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
* @applitools/core-universal bumped to 1.0.24
|
|
57
|
+
|
|
58
|
+
* @applitools/eyes bumped to 1.43.7
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## [3.60.9](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.60.8...js/eyes-cypress@3.60.9) (2026-07-08)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Dependencies
|
|
65
|
+
|
|
66
|
+
* @applitools/core-base bumped to 1.36.1
|
|
67
|
+
#### Bug Fixes
|
|
68
|
+
|
|
69
|
+
* forward Exact match-level tuning to the server across JS + Java | FLD-4685 ([#3974](https://github.com/Applitools-Dev/sdk/issues/3974)) ([fea351c](https://github.com/Applitools-Dev/sdk/commit/fea351c76c80f63bf658d9573b3d34e0537e0cce))
|
|
70
|
+
* @applitools/eyes bumped to 1.43.6
|
|
71
|
+
#### Bug Fixes
|
|
72
|
+
|
|
73
|
+
* forward Exact match-level tuning to the server across JS + Java | FLD-4685 ([#3974](https://github.com/Applitools-Dev/sdk/issues/3974)) ([fea351c](https://github.com/Applitools-Dev/sdk/commit/fea351c76c80f63bf658d9573b3d34e0537e0cce))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
* @applitools/nml-client bumped to 1.11.35
|
|
78
|
+
|
|
79
|
+
* @applitools/ec-client bumped to 1.12.37
|
|
80
|
+
|
|
81
|
+
* @applitools/core bumped to 4.66.1
|
|
82
|
+
#### Bug Fixes
|
|
83
|
+
|
|
84
|
+
* stop UFG old-infra retry after a retry fails | AD-14675 ([#3970](https://github.com/Applitools-Dev/sdk/issues/3970)) ([1531893](https://github.com/Applitools-Dev/sdk/commit/1531893cc9c098f3ade329ceae7164600c184fa5))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
* @applitools/core-universal bumped to 1.0.23
|
|
89
|
+
|
|
90
|
+
|
|
3
91
|
## [3.60.8](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.60.7...js/eyes-cypress@3.60.8) (2026-06-28)
|
|
4
92
|
|
|
5
93
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/eyes-cypress",
|
|
3
|
-
"version": "3.60.
|
|
3
|
+
"version": "3.60.10",
|
|
4
4
|
"homepage": "https://applitools.com/tutorials/sdks/cypress",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"setup": "run --top-level xvfb:setup"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@applitools/core": "4.66.
|
|
56
|
-
"@applitools/core-universal": "1.0.
|
|
57
|
-
"@applitools/eyes": "1.43.
|
|
55
|
+
"@applitools/core": "4.66.2",
|
|
56
|
+
"@applitools/core-universal": "1.0.24",
|
|
57
|
+
"@applitools/eyes": "1.43.7",
|
|
58
58
|
"@applitools/functional-commons": "1.6.0",
|
|
59
59
|
"@applitools/logger": "2.3.0",
|
|
60
60
|
"@applitools/utils": "1.15.1",
|
package/src/browser/commands.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* global Cypress,cy,after
|
|
1
|
+
/* global Cypress,cy,after */
|
|
2
2
|
'use strict'
|
|
3
3
|
const spec = require('../../dist/browser/spec-driver')
|
|
4
4
|
const Refer = require('../../dist/browser/refer')
|
|
@@ -26,39 +26,10 @@ let manager,
|
|
|
26
26
|
_summary,
|
|
27
27
|
connectedToUniversal,
|
|
28
28
|
openAndGlobalConfig,
|
|
29
|
-
isOpen = false
|
|
30
|
-
// Per-test diff-attribution state: did the current test open Eyes, and has it already been checked.
|
|
31
|
-
eyesOpenedInTest = false,
|
|
32
|
-
currentTestHandled = false
|
|
29
|
+
isOpen = false
|
|
33
30
|
|
|
34
31
|
const deleteTest = options => socket.request('Core.deleteTest', options)
|
|
35
32
|
|
|
36
|
-
const DIFFS_OR_ERRORS_MESSAGE = 'Eyes-Cypress detected diffs or errors'
|
|
37
|
-
|
|
38
|
-
// When per-test attribution is on, throws on a diff/error from within the current test's own execution
|
|
39
|
-
// context so Cypress blames the test that produced it. Called from eyesClose() (after it closes Eyes)
|
|
40
|
-
// and from the afterEach() hook; currentTestHandled makes it run once per test. It does NOT close Eyes —
|
|
41
|
-
// closing would change abort / duplicate-removal semantics for tests that intentionally leave Eyes open,
|
|
42
|
-
// and the results are available from the checks alone.
|
|
43
|
-
async function throwOnDiffForCurrentTest() {
|
|
44
|
-
if (currentTestHandled || !isOpen) return
|
|
45
|
-
currentTestHandled = true
|
|
46
|
-
|
|
47
|
-
if (!perTestDiffAttribution) return
|
|
48
|
-
|
|
49
|
-
// Awaiting the results blocks the test until its UFG render completes — required for correct attribution.
|
|
50
|
-
const results = await socket.request('Eyes.getResults', {eyes, settings: {throwErr: false}})
|
|
51
|
-
if (results && results.length > 0) {
|
|
52
|
-
// TAP files are written once in the after() hook, not here.
|
|
53
|
-
const resultConfig = makeResultConfig({shouldCreateTapFile: false})
|
|
54
|
-
const message = await socket.request('Test.printTestResults', {testResults: results, resultConfig})
|
|
55
|
-
printToLog(`Eyes: per-test diff check message: ${message}`)
|
|
56
|
-
if (message && message.includes(DIFFS_OR_ERRORS_MESSAGE)) {
|
|
57
|
-
throw new Error(message)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
33
|
async function getSummary() {
|
|
63
34
|
if (_summary) return _summary
|
|
64
35
|
await Promise.all(closePromiseArr)
|
|
@@ -96,10 +67,6 @@ const shouldCallAfterHook =
|
|
|
96
67
|
|
|
97
68
|
const notFailCypressAfterAllSpecs = !Cypress.config('appliConfFile').failCypressAfterAllSpecs
|
|
98
69
|
|
|
99
|
-
// True when diffs are attributed per-test (thrown from the test's own context) instead of batched into
|
|
100
|
-
// the spec-level after() hook.
|
|
101
|
-
const perTestDiffAttribution = Cypress.config('eyesFailCypressOnDiff') && notFailCypressAfterAllSpecs
|
|
102
|
-
|
|
103
70
|
Cypress.Commands.add('eyesGetAllTestResults', () => {
|
|
104
71
|
Cypress.log({name: 'Eyes: getAllTestResults'})
|
|
105
72
|
printToLog(
|
|
@@ -145,26 +112,12 @@ if (shouldCallAfterHook) {
|
|
|
145
112
|
isCurrentTestDisabled = false
|
|
146
113
|
return
|
|
147
114
|
}
|
|
148
|
-
// Always finalize results and run post-spec tasks (e.g. writing TAP files) here. With per-test
|
|
149
|
-
// attribution on, the afterEach() hook below already throws diffs against the correct test, so
|
|
150
|
-
// suppress the throw here — throwing in this spec-level after() hook would re-blame the last test.
|
|
151
115
|
const summary = await getSummary()
|
|
152
|
-
await throwErrorIfExistsInSummary(summary, Cypress.config('eyesFailCypressOnDiff'), false
|
|
116
|
+
await throwErrorIfExistsInSummary(summary, Cypress.config('eyesFailCypressOnDiff'), false)
|
|
153
117
|
})
|
|
154
118
|
})
|
|
155
119
|
}
|
|
156
120
|
|
|
157
|
-
// With per-test attribution on, check each test's Eyes from an afterEach() hook — which runs in that
|
|
158
|
-
// test's own context — so a diff is blamed on the test that produced it. Covers the common case where
|
|
159
|
-
// the test relies on the SDK's automatic post-spec close. (Does not close Eyes — see throwOnDiffForCurrentTest.)
|
|
160
|
-
if (perTestDiffAttribution) {
|
|
161
|
-
afterEach(() => {
|
|
162
|
-
if (!eyesOpenedInTest) return
|
|
163
|
-
eyesOpenedInTest = false
|
|
164
|
-
return cy.then({timeout: 86400000}, () => throwOnDiffForCurrentTest())
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
121
|
let isCurrentTestDisabled
|
|
169
122
|
|
|
170
123
|
Cypress.Commands.add('eyesOpen', function (args = {}) {
|
|
@@ -216,8 +169,6 @@ Cypress.Commands.add('eyesOpen', function (args = {}) {
|
|
|
216
169
|
|
|
217
170
|
eyes = await socket.request('EyesManager.openEyes', {manager, target, config: openAndGlobalConfig})
|
|
218
171
|
isOpen = true
|
|
219
|
-
eyesOpenedInTest = true
|
|
220
|
-
currentTestHandled = false
|
|
221
172
|
})
|
|
222
173
|
})
|
|
223
174
|
|
|
@@ -240,25 +191,22 @@ Cypress.Commands.add('eyesCheckWindow', (args = {}) => {
|
|
|
240
191
|
})
|
|
241
192
|
|
|
242
193
|
Cypress.Commands.add('eyesClose', () => {
|
|
243
|
-
return cy.then({timeout: 86400000},
|
|
194
|
+
return cy.then({timeout: 86400000}, () => {
|
|
195
|
+
if (isCurrentTestDisabled) return
|
|
196
|
+
if (!isOpen) throw new EyesNotOpenError('eyesClose')
|
|
197
|
+
|
|
198
|
+
Cypress.log({name: 'Eyes: close'})
|
|
244
199
|
if (isCurrentTestDisabled) {
|
|
245
200
|
isCurrentTestDisabled = false
|
|
246
201
|
return
|
|
247
202
|
}
|
|
248
|
-
if (!isOpen) throw new EyesNotOpenError('eyesClose')
|
|
249
203
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
// Eyes.close in core no longer waits on results, so await it explicitly.
|
|
204
|
+
// Eyes.close in core is not waiting on results anymore. So we should return it in order to await it
|
|
253
205
|
const p = socket.request('Eyes.close', {eyes, config: openAndGlobalConfig}).catch(err => {
|
|
254
206
|
console.log('Error in cy.eyesClose', err)
|
|
255
207
|
})
|
|
256
208
|
closePromiseArr.push(p)
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
// Run the per-test diff check inside the test's own context (the afterEach() hook does the same for
|
|
260
|
-
// tests that don't call eyesClose(); currentTestHandled prevents doing it twice).
|
|
261
|
-
await throwOnDiffForCurrentTest()
|
|
209
|
+
return p
|
|
262
210
|
})
|
|
263
211
|
})
|
|
264
212
|
|
|
@@ -295,24 +243,15 @@ function isNonVisualTestError(testResult) {
|
|
|
295
243
|
return result
|
|
296
244
|
}
|
|
297
245
|
|
|
298
|
-
function
|
|
299
|
-
|
|
246
|
+
async function throwErrorIfExistsInSummary(summary, shouldThrowError, shouldDisplayCriticalErrors) {
|
|
247
|
+
const resultConfig = {
|
|
300
248
|
showLogs: Cypress.config('appliConfFile').showLogs,
|
|
301
|
-
shouldThrowError,
|
|
249
|
+
shouldThrowError: shouldThrowError,
|
|
302
250
|
isTextTerminal: Cypress.config('isTextTerminal'),
|
|
303
251
|
tapDirPath: Cypress.config('appliConfFile').tapDirPath,
|
|
304
252
|
tapFileName: Cypress.config('appliConfFile').tapFileName,
|
|
305
|
-
shouldCreateTapFile,
|
|
253
|
+
shouldCreateTapFile: shouldDoPostSpecTasks,
|
|
306
254
|
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
async function throwErrorIfExistsInSummary(
|
|
310
|
-
summary,
|
|
311
|
-
shouldThrowError,
|
|
312
|
-
shouldDisplayCriticalErrors,
|
|
313
|
-
suppressDiffThrow = false,
|
|
314
|
-
) {
|
|
315
|
-
const resultConfig = makeResultConfig({shouldThrowError, shouldCreateTapFile: shouldDoPostSpecTasks})
|
|
316
255
|
const testResults = summary.results?.map(({result}) => result) ?? []
|
|
317
256
|
const filteredTestResults = shouldDisplayCriticalErrors
|
|
318
257
|
? testResults.filter(testResult => testResult.error && isNonVisualTestError(testResult))
|
|
@@ -324,10 +263,9 @@ async function throwErrorIfExistsInSummary(
|
|
|
324
263
|
}, results message: ${message}`,
|
|
325
264
|
)
|
|
326
265
|
if (
|
|
327
|
-
(
|
|
328
|
-
!!getGlobalConfigProperty('eyesFailCypressOnDiff') &&
|
|
266
|
+
(!!getGlobalConfigProperty('eyesFailCypressOnDiff') &&
|
|
329
267
|
message &&
|
|
330
|
-
message.includes(
|
|
268
|
+
message.includes('Eyes-Cypress detected diffs or errors')) ||
|
|
331
269
|
(shouldDisplayCriticalErrors && filteredTestResults.length > 0 && message)
|
|
332
270
|
) {
|
|
333
271
|
printToLog('Eyes: throwErrorIfExistsInSummary throwing error')
|
package/types/expose.d.ts
CHANGED
|
@@ -123,6 +123,7 @@ export type CypressCheckSettings = {
|
|
|
123
123
|
name?: string;
|
|
124
124
|
region?: LegacyRegion;
|
|
125
125
|
matchLevel?: "None" | "Layout1" | "Layout" | "Layout2" | "Content" | "IgnoreColors" | "Strict" | "Dynamic" | "Exact";
|
|
126
|
+
exact?: { minDiffIntensity?: number; minDiffWidth?: number; minDiffHeight?: number; matchThreshold?: number; };
|
|
126
127
|
useDom?: boolean;
|
|
127
128
|
sendDom?: boolean;
|
|
128
129
|
enablePatterns?: boolean;
|
|
@@ -296,7 +297,7 @@ export type CypressEyesConfig = {
|
|
|
296
297
|
cut?: { top: number; right: number; bottom: number; left: number; } | { x: number; y: number; width: number; height: number; };
|
|
297
298
|
debugScreenshots?: { save: boolean; path?: string; prefix?: string; };
|
|
298
299
|
defaultMatchSettings?: {
|
|
299
|
-
exact?: { minDiffIntensity
|
|
300
|
+
exact?: { minDiffIntensity?: number; minDiffWidth?: number; minDiffHeight?: number; matchThreshold?: number; };
|
|
300
301
|
matchLevel?: "None" | "Layout1" | "Layout" | "Layout2" | "Content" | "IgnoreColors" | "Strict" | "Dynamic" | "Exact";
|
|
301
302
|
ignoreCaret?: boolean;
|
|
302
303
|
useDom?: boolean;
|
|
@@ -447,7 +448,7 @@ export type appliConfFile = {
|
|
|
447
448
|
cut?: { top: number; right: number; bottom: number; left: number; } | { x: number; y: number; width: number; height: number; };
|
|
448
449
|
debugScreenshots?: { save: boolean; path?: string; prefix?: string; };
|
|
449
450
|
defaultMatchSettings?: {
|
|
450
|
-
exact?: { minDiffIntensity
|
|
451
|
+
exact?: { minDiffIntensity?: number; minDiffWidth?: number; minDiffHeight?: number; matchThreshold?: number; };
|
|
451
452
|
matchLevel?: "None" | "Layout1" | "Layout" | "Layout2" | "Content" | "IgnoreColors" | "Strict" | "Dynamic" | "Exact";
|
|
452
453
|
ignoreCaret?: boolean;
|
|
453
454
|
useDom?: boolean;
|