@applitools/eyes-cypress 3.60.5 → 3.60.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 +82 -0
- package/package.json +7 -7
- package/src/browser/commands.js +78 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,87 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.60.7](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.60.6...js/eyes-cypress@3.60.7) (2026-06-18)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* attribute diff failures to correct test when failCypressOnDiff=true | FLD-4628 ([#3923](https://github.com/Applitools-Dev/sdk/issues/3923)) ([0e3af19](https://github.com/Applitools-Dev/sdk/commit/0e3af19421a08d83d35e1d36c0e3879eeabc6378))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* @applitools/utils bumped to 1.15.0
|
|
14
|
+
#### Features
|
|
15
|
+
|
|
16
|
+
* one-time per-execution summary logEvent in storybook | AD-14305 ([#3911](https://github.com/Applitools-Dev/sdk/issues/3911)) ([59e3a5d](https://github.com/Applitools-Dev/sdk/commit/59e3a5dccf74aa1ac1158024316bd305e3515afa))
|
|
17
|
+
* @applitools/req bumped to 1.11.1
|
|
18
|
+
#### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* bundle node-fetch into dist to drop node-domexception dep warning | FLD-4197 ([#3899](https://github.com/Applitools-Dev/sdk/issues/3899)) ([9c3dc52](https://github.com/Applitools-Dev/sdk/commit/9c3dc52866a4a665f1578c39ff43cd0ee5f63492))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
* @applitools/logger bumped to 2.2.13
|
|
25
|
+
|
|
26
|
+
* @applitools/dom-snapshot bumped to 4.17.4
|
|
27
|
+
|
|
28
|
+
* @applitools/socket bumped to 1.3.14
|
|
29
|
+
|
|
30
|
+
* @applitools/image bumped to 1.2.12
|
|
31
|
+
|
|
32
|
+
* @applitools/dom-capture bumped to 11.8.2
|
|
33
|
+
|
|
34
|
+
* @applitools/driver bumped to 1.26.4
|
|
35
|
+
|
|
36
|
+
* @applitools/spec-driver-webdriver bumped to 1.6.4
|
|
37
|
+
|
|
38
|
+
* @applitools/spec-driver-selenium bumped to 1.8.4
|
|
39
|
+
|
|
40
|
+
* @applitools/spec-driver-playwright bumped to 1.9.4
|
|
41
|
+
|
|
42
|
+
* @applitools/spec-driver-puppeteer bumped to 1.8.4
|
|
43
|
+
|
|
44
|
+
* @applitools/screenshoter bumped to 3.12.23
|
|
45
|
+
|
|
46
|
+
* @applitools/nml-client bumped to 1.11.33
|
|
47
|
+
|
|
48
|
+
* @applitools/tunnel-client bumped to 1.12.1
|
|
49
|
+
|
|
50
|
+
* @applitools/ufg-client bumped to 1.22.4
|
|
51
|
+
|
|
52
|
+
* @applitools/core-base bumped to 1.35.3
|
|
53
|
+
|
|
54
|
+
* @applitools/ec-client bumped to 1.12.35
|
|
55
|
+
|
|
56
|
+
* @applitools/core bumped to 4.65.2
|
|
57
|
+
|
|
58
|
+
* @applitools/core-universal bumped to 1.0.21
|
|
59
|
+
|
|
60
|
+
* @applitools/eyes bumped to 1.43.4
|
|
61
|
+
|
|
62
|
+
* @applitools/test-server bumped to 1.4.5
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## [3.60.6](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.60.5...js/eyes-cypress@3.60.6) (2026-06-15)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Dependencies
|
|
69
|
+
|
|
70
|
+
* @applitools/core-base bumped to 1.35.2
|
|
71
|
+
#### Bug Fixes
|
|
72
|
+
|
|
73
|
+
* re-trigger release for packages missed in the AD-14089 release | AD-14089 ([#3925](https://github.com/Applitools-Dev/sdk/issues/3925)) ([0880c34](https://github.com/Applitools-Dev/sdk/commit/0880c34b66221025e70ca7e3e3fab7b45a9f8d9e))
|
|
74
|
+
* @applitools/nml-client bumped to 1.11.32
|
|
75
|
+
|
|
76
|
+
* @applitools/ec-client bumped to 1.12.34
|
|
77
|
+
|
|
78
|
+
* @applitools/core bumped to 4.65.1
|
|
79
|
+
|
|
80
|
+
* @applitools/core-universal bumped to 1.0.20
|
|
81
|
+
|
|
82
|
+
* @applitools/eyes bumped to 1.43.3
|
|
83
|
+
|
|
84
|
+
|
|
3
85
|
## [3.60.5](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.60.4...js/eyes-cypress@3.60.5) (2026-06-14)
|
|
4
86
|
|
|
5
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/eyes-cypress",
|
|
3
|
-
"version": "3.60.
|
|
3
|
+
"version": "3.60.7",
|
|
4
4
|
"homepage": "https://applitools.com/tutorials/sdks/cypress",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"setup": "run --top-level xvfb:setup"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@applitools/core": "4.65.
|
|
56
|
-
"@applitools/core-universal": "1.0.
|
|
57
|
-
"@applitools/eyes": "1.43.
|
|
55
|
+
"@applitools/core": "4.65.2",
|
|
56
|
+
"@applitools/core-universal": "1.0.21",
|
|
57
|
+
"@applitools/eyes": "1.43.4",
|
|
58
58
|
"@applitools/functional-commons": "1.6.0",
|
|
59
|
-
"@applitools/logger": "2.2.
|
|
60
|
-
"@applitools/utils": "1.
|
|
59
|
+
"@applitools/logger": "2.2.13",
|
|
60
|
+
"@applitools/utils": "1.15.0",
|
|
61
61
|
"boxen": "5.1.2",
|
|
62
62
|
"chalk": "3.0.0",
|
|
63
63
|
"semver": "7.6.2",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"@applitools/bongo": "^5.10.0",
|
|
70
70
|
"@applitools/generic": "^3.9.2",
|
|
71
71
|
"@applitools/snaptdout": "^1.1.1",
|
|
72
|
-
"@applitools/test-server": "^1.4.
|
|
72
|
+
"@applitools/test-server": "^1.4.5",
|
|
73
73
|
"@applitools/test-utils": "^1.5.17",
|
|
74
74
|
"@types/he": "^1",
|
|
75
75
|
"@types/node": "^12.20.55",
|
package/src/browser/commands.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* global Cypress,cy,after */
|
|
1
|
+
/* global Cypress,cy,after,afterEach */
|
|
2
2
|
'use strict'
|
|
3
3
|
const spec = require('../../dist/browser/spec-driver')
|
|
4
4
|
const Refer = require('../../dist/browser/refer')
|
|
@@ -26,10 +26,39 @@ let manager,
|
|
|
26
26
|
_summary,
|
|
27
27
|
connectedToUniversal,
|
|
28
28
|
openAndGlobalConfig,
|
|
29
|
-
isOpen = false
|
|
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
|
|
30
33
|
|
|
31
34
|
const deleteTest = options => socket.request('Core.deleteTest', options)
|
|
32
35
|
|
|
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
|
+
|
|
33
62
|
async function getSummary() {
|
|
34
63
|
if (_summary) return _summary
|
|
35
64
|
await Promise.all(closePromiseArr)
|
|
@@ -67,6 +96,10 @@ const shouldCallAfterHook =
|
|
|
67
96
|
|
|
68
97
|
const notFailCypressAfterAllSpecs = !Cypress.config('appliConfFile').failCypressAfterAllSpecs
|
|
69
98
|
|
|
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
|
+
|
|
70
103
|
Cypress.Commands.add('eyesGetAllTestResults', () => {
|
|
71
104
|
Cypress.log({name: 'Eyes: getAllTestResults'})
|
|
72
105
|
printToLog(
|
|
@@ -112,12 +145,26 @@ if (shouldCallAfterHook) {
|
|
|
112
145
|
isCurrentTestDisabled = false
|
|
113
146
|
return
|
|
114
147
|
}
|
|
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.
|
|
115
151
|
const summary = await getSummary()
|
|
116
|
-
await throwErrorIfExistsInSummary(summary, Cypress.config('eyesFailCypressOnDiff'), false)
|
|
152
|
+
await throwErrorIfExistsInSummary(summary, Cypress.config('eyesFailCypressOnDiff'), false, perTestDiffAttribution)
|
|
117
153
|
})
|
|
118
154
|
})
|
|
119
155
|
}
|
|
120
156
|
|
|
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
|
+
|
|
121
168
|
let isCurrentTestDisabled
|
|
122
169
|
|
|
123
170
|
Cypress.Commands.add('eyesOpen', function (args = {}) {
|
|
@@ -169,6 +216,8 @@ Cypress.Commands.add('eyesOpen', function (args = {}) {
|
|
|
169
216
|
|
|
170
217
|
eyes = await socket.request('EyesManager.openEyes', {manager, target, config: openAndGlobalConfig})
|
|
171
218
|
isOpen = true
|
|
219
|
+
eyesOpenedInTest = true
|
|
220
|
+
currentTestHandled = false
|
|
172
221
|
})
|
|
173
222
|
})
|
|
174
223
|
|
|
@@ -191,22 +240,25 @@ Cypress.Commands.add('eyesCheckWindow', (args = {}) => {
|
|
|
191
240
|
})
|
|
192
241
|
|
|
193
242
|
Cypress.Commands.add('eyesClose', () => {
|
|
194
|
-
return cy.then({timeout: 86400000}, () => {
|
|
195
|
-
if (isCurrentTestDisabled) return
|
|
196
|
-
if (!isOpen) throw new EyesNotOpenError('eyesClose')
|
|
197
|
-
|
|
198
|
-
Cypress.log({name: 'Eyes: close'})
|
|
243
|
+
return cy.then({timeout: 86400000}, async () => {
|
|
199
244
|
if (isCurrentTestDisabled) {
|
|
200
245
|
isCurrentTestDisabled = false
|
|
201
246
|
return
|
|
202
247
|
}
|
|
248
|
+
if (!isOpen) throw new EyesNotOpenError('eyesClose')
|
|
203
249
|
|
|
204
|
-
|
|
250
|
+
Cypress.log({name: 'Eyes: close'})
|
|
251
|
+
|
|
252
|
+
// Eyes.close in core no longer waits on results, so await it explicitly.
|
|
205
253
|
const p = socket.request('Eyes.close', {eyes, config: openAndGlobalConfig}).catch(err => {
|
|
206
254
|
console.log('Error in cy.eyesClose', err)
|
|
207
255
|
})
|
|
208
256
|
closePromiseArr.push(p)
|
|
209
|
-
|
|
257
|
+
await p
|
|
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()
|
|
210
262
|
})
|
|
211
263
|
})
|
|
212
264
|
|
|
@@ -243,15 +295,24 @@ function isNonVisualTestError(testResult) {
|
|
|
243
295
|
return result
|
|
244
296
|
}
|
|
245
297
|
|
|
246
|
-
|
|
247
|
-
|
|
298
|
+
function makeResultConfig({shouldThrowError = true, shouldCreateTapFile}) {
|
|
299
|
+
return {
|
|
248
300
|
showLogs: Cypress.config('appliConfFile').showLogs,
|
|
249
|
-
shouldThrowError
|
|
301
|
+
shouldThrowError,
|
|
250
302
|
isTextTerminal: Cypress.config('isTextTerminal'),
|
|
251
303
|
tapDirPath: Cypress.config('appliConfFile').tapDirPath,
|
|
252
304
|
tapFileName: Cypress.config('appliConfFile').tapFileName,
|
|
253
|
-
shouldCreateTapFile
|
|
305
|
+
shouldCreateTapFile,
|
|
254
306
|
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
async function throwErrorIfExistsInSummary(
|
|
310
|
+
summary,
|
|
311
|
+
shouldThrowError,
|
|
312
|
+
shouldDisplayCriticalErrors,
|
|
313
|
+
suppressDiffThrow = false,
|
|
314
|
+
) {
|
|
315
|
+
const resultConfig = makeResultConfig({shouldThrowError, shouldCreateTapFile: shouldDoPostSpecTasks})
|
|
255
316
|
const testResults = summary.results?.map(({result}) => result) ?? []
|
|
256
317
|
const filteredTestResults = shouldDisplayCriticalErrors
|
|
257
318
|
? testResults.filter(testResult => testResult.error && isNonVisualTestError(testResult))
|
|
@@ -263,9 +324,10 @@ async function throwErrorIfExistsInSummary(summary, shouldThrowError, shouldDisp
|
|
|
263
324
|
}, results message: ${message}`,
|
|
264
325
|
)
|
|
265
326
|
if (
|
|
266
|
-
(
|
|
327
|
+
(!suppressDiffThrow &&
|
|
328
|
+
!!getGlobalConfigProperty('eyesFailCypressOnDiff') &&
|
|
267
329
|
message &&
|
|
268
|
-
message.includes(
|
|
330
|
+
message.includes(DIFFS_OR_ERRORS_MESSAGE)) ||
|
|
269
331
|
(shouldDisplayCriticalErrors && filteredTestResults.length > 0 && message)
|
|
270
332
|
) {
|
|
271
333
|
printToLog('Eyes: throwErrorIfExistsInSummary throwing error')
|