@koenvanbelle/cypress-soft-assertions 2.4.3 → 2.4.4
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/dist/index.js +37 -22
- package/dist/utils.js +3 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -81,7 +81,13 @@ function patchChaiAssertions() {
|
|
|
81
81
|
assertionProto.assert = patchedAssertionAssert;
|
|
82
82
|
}
|
|
83
83
|
function resolveStableToken(assertionContext, args) {
|
|
84
|
-
|
|
84
|
+
const assertionToken = (0, utils_1.getAssertionToken)(assertionContext, args);
|
|
85
|
+
if (assertionToken)
|
|
86
|
+
return assertionToken;
|
|
87
|
+
const commandId = getRetryableCommandId();
|
|
88
|
+
if (commandId)
|
|
89
|
+
return (0, utils_1.resolveToken)('', commandId, args);
|
|
90
|
+
return '';
|
|
85
91
|
}
|
|
86
92
|
function isRunningHookContext() {
|
|
87
93
|
var _a;
|
|
@@ -95,23 +101,24 @@ function isRunningHookContext() {
|
|
|
95
101
|
}
|
|
96
102
|
}
|
|
97
103
|
function patchedAssertionAssert(...args) {
|
|
104
|
+
var _a;
|
|
98
105
|
if (!originalChaiAssert)
|
|
99
106
|
return;
|
|
107
|
+
// Fast path for non-soft tests: avoid try/catch and token logic entirely.
|
|
108
|
+
if (!isInSoftTest) {
|
|
109
|
+
return originalChaiAssert.apply(this, args);
|
|
110
|
+
}
|
|
100
111
|
try {
|
|
101
112
|
const result = originalChaiAssert.apply(this, args);
|
|
102
113
|
// Assertion passed — clear any staged failure for this token.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
retryFirstSeen.delete(token);
|
|
108
|
-
}
|
|
114
|
+
const token = resolveStableToken(this, args);
|
|
115
|
+
if (token) {
|
|
116
|
+
retryAssertionFailures.delete(token);
|
|
117
|
+
retryFirstSeen.delete(token);
|
|
109
118
|
}
|
|
110
119
|
return result;
|
|
111
120
|
}
|
|
112
121
|
catch (error) {
|
|
113
|
-
if (!isInSoftTest)
|
|
114
|
-
throw error;
|
|
115
122
|
if (isRunningHookContext())
|
|
116
123
|
throw error;
|
|
117
124
|
const errorEntry = {
|
|
@@ -120,22 +127,30 @@ function patchedAssertionAssert(...args) {
|
|
|
120
127
|
};
|
|
121
128
|
const token = resolveStableToken(this, args);
|
|
122
129
|
if (token) {
|
|
123
|
-
// Track when we first saw this failure.
|
|
124
|
-
if (!retryFirstSeen.has(token)) {
|
|
125
|
-
retryFirstSeen.set(token, Date.now());
|
|
126
|
-
}
|
|
127
130
|
// Stage the failure so it can be cleared if a later retry succeeds.
|
|
128
131
|
retryAssertionFailures.set(token, errorEntry);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// Cypress retries every ~50ms, so subtracting 100ms ensures we
|
|
132
|
-
// catch at least 1-2 more retries before the deadline.
|
|
133
|
-
const elapsed = Date.now() - retryFirstSeen.get(token);
|
|
132
|
+
const current = cy.state('current');
|
|
133
|
+
const wallClockStartedAt = (_a = current === null || current === void 0 ? void 0 : current.get) === null || _a === void 0 ? void 0 : _a.call(current, 'wallClockStartedAt');
|
|
134
134
|
const timeout = getEffectiveTimeout();
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
//
|
|
138
|
-
|
|
135
|
+
if (typeof wallClockStartedAt === 'number') {
|
|
136
|
+
const totalElapsed = Date.now() - wallClockStartedAt;
|
|
137
|
+
// Swallow only when very close to the actual command timeout.
|
|
138
|
+
// A 20ms buffer maximizes retry attempts while still preventing
|
|
139
|
+
// Cypress's global fail handler from aborting the test queue.
|
|
140
|
+
if (totalElapsed < timeout - 20) {
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Fallback for cases where wallClockStartedAt is missing.
|
|
146
|
+
if (!retryFirstSeen.has(token)) {
|
|
147
|
+
retryFirstSeen.set(token, Date.now());
|
|
148
|
+
}
|
|
149
|
+
const elapsed = Date.now() - retryFirstSeen.get(token);
|
|
150
|
+
const swallowAt = Math.max(timeout - 100, timeout * 0.9);
|
|
151
|
+
if (elapsed < swallowAt) {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
139
154
|
}
|
|
140
155
|
// Retry window expired. Swallow the error: Cypress considers the
|
|
141
156
|
// assertion "passed", the command resolves, and the queue continues.
|
package/dist/utils.js
CHANGED
|
@@ -84,10 +84,11 @@ function appendUniqueError(errors, message, stack) {
|
|
|
84
84
|
*/
|
|
85
85
|
function mergeRetryFailures(softErrors, retryFailures) {
|
|
86
86
|
const result = [...softErrors];
|
|
87
|
+
const seenMessages = new Set(result.map(e => e.message));
|
|
87
88
|
for (const entry of retryFailures.values()) {
|
|
88
|
-
|
|
89
|
-
if (!isDuplicate) {
|
|
89
|
+
if (!seenMessages.has(entry.message)) {
|
|
90
90
|
result.push(entry);
|
|
91
|
+
seenMessages.add(entry.message);
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
return result;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koenvanbelle/cypress-soft-assertions",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.4",
|
|
4
4
|
"description": "A Cypress plugin that provides soft_it() for soft assertions - all assertions continue on failure and are reported together",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|