@a11y-oracle/cypress-plugin 1.3.0 → 1.3.1
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/lib/commands.d.ts.map +1 -1
- package/dist/lib/commands.js +65 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/lib/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,SAAS,EACT,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,YAAY,EACb,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAIjE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,SAAS;YACjB;;;eAGG;YACH,cAAc,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAEnE;;;;;eAKG;YACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAE1C,+DAA+D;YAC/D,aAAa,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;YAEnC,2EAA2E;YAC3E,mBAAmB,IAAI,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;YAEtD,0EAA0E;YAC1E,qBAAqB,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;YAEnD;;;;;eAKG;YACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;YAE1E,0EAA0E;YAC1E,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;YAElC,sDAAsD;YACtD,oBAAoB,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC;YAElD;;;;;eAKG;YACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,CAAC,eAAe,CAAC,CAAC;YAE9B;;;;;;;;;eASG;YACH,uBAAuB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAE1E;;;;;;;eAOG;YACH,sBAAsB,CACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC9B,SAAS,CAAC,IAAI,CAAC,CAAC;YAEnB;;;eAGG;YACH,iBAAiB,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;SACtC;KACF;CACF;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/lib/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,SAAS,EACT,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,YAAY,EACb,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAIjE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,SAAS;YACjB;;;eAGG;YACH,cAAc,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAEnE;;;;;eAKG;YACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAE1C,+DAA+D;YAC/D,aAAa,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;YAEnC,2EAA2E;YAC3E,mBAAmB,IAAI,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;YAEtD,0EAA0E;YAC1E,qBAAqB,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC;YAEnD;;;;;eAKG;YACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;YAE1E,0EAA0E;YAC1E,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;YAElC,sDAAsD;YACtD,oBAAoB,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC;YAElD;;;;;eAKG;YACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,CAAC,eAAe,CAAC,CAAC;YAE9B;;;;;;;;;eASG;YACH,uBAAuB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;YAE1E;;;;;;;eAOG;YACH,sBAAsB,CACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC9B,SAAS,CAAC,IAAI,CAAC,CAAC;YAEnB;;;eAGG;YACH,iBAAiB,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;SACtC;KACF;CACF;AA8UD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,cAAc,CAAC,CAwCvE"}
|
package/dist/lib/commands.js
CHANGED
|
@@ -38,14 +38,48 @@ let orchestrator = null;
|
|
|
38
38
|
let autFrameId = null;
|
|
39
39
|
let autContextId = null;
|
|
40
40
|
let autIframeBounds = null;
|
|
41
|
+
/**
|
|
42
|
+
* Cached isolated world state for reuse across init/dispose cycles.
|
|
43
|
+
*
|
|
44
|
+
* `Page.createIsolatedWorld` accumulates execution contexts that Chrome
|
|
45
|
+
* never garbage-collects during same-origin navigations. After ~16
|
|
46
|
+
* iterations the browser hangs on subsequent CDP calls. By caching the
|
|
47
|
+
* context ID and verifying it with a cheap `Runtime.evaluate` probe we
|
|
48
|
+
* avoid creating a new world when the previous one is still alive.
|
|
49
|
+
*/
|
|
50
|
+
let _cachedWorldFrameId = null;
|
|
51
|
+
let _cachedWorldContextId = null;
|
|
52
|
+
/** Timeout (ms) applied to every CDP call to surface hangs as errors. */
|
|
53
|
+
const CDP_TIMEOUT_MS = 30_000;
|
|
54
|
+
/**
|
|
55
|
+
* Wrap a promise with a timeout to prevent indefinite hangs.
|
|
56
|
+
*/
|
|
57
|
+
function withTimeout(promise, ms, label) {
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const timer = setTimeout(() => {
|
|
60
|
+
reject(new Error(`A11y-Oracle: CDP call "${label}" timed out after ${ms}ms`));
|
|
61
|
+
}, ms);
|
|
62
|
+
promise.then((value) => {
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
resolve(value);
|
|
65
|
+
}, (error) => {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
reject(error);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
41
71
|
/**
|
|
42
72
|
* Send a raw CDP command through Cypress's automation channel.
|
|
73
|
+
*
|
|
74
|
+
* Every call is guarded by a timeout so that accumulated isolated worlds
|
|
75
|
+
* or other browser-side issues surface as errors instead of silent hangs.
|
|
43
76
|
*/
|
|
44
77
|
function sendCDP(command, params = {}) {
|
|
45
|
-
|
|
78
|
+
const raw = Cypress.automation('remote:debugger:protocol', {
|
|
46
79
|
command,
|
|
47
80
|
params,
|
|
48
81
|
});
|
|
82
|
+
return withTimeout(raw, CDP_TIMEOUT_MS, command);
|
|
49
83
|
}
|
|
50
84
|
/**
|
|
51
85
|
* Create a {@link CDPSessionLike} adapter that routes CDP calls through
|
|
@@ -131,6 +165,29 @@ async function findAUTFrameId() {
|
|
|
131
165
|
* calls execute in the AUT, not the Cypress runner.
|
|
132
166
|
*/
|
|
133
167
|
async function findAUTContextId(frameId) {
|
|
168
|
+
// Try to reuse the context that was handed off by the previous
|
|
169
|
+
// disposeA11yOracle() call. A lightweight Runtime.evaluate probe
|
|
170
|
+
// confirms the context is still alive (Chrome destroys isolated worlds
|
|
171
|
+
// on cross-origin navigation but may preserve them for same-origin).
|
|
172
|
+
// Always consume (clear) the cache regardless of outcome.
|
|
173
|
+
const cachedCtx = _cachedWorldContextId;
|
|
174
|
+
const cachedFrame = _cachedWorldFrameId;
|
|
175
|
+
_cachedWorldContextId = null;
|
|
176
|
+
_cachedWorldFrameId = null;
|
|
177
|
+
if (cachedCtx !== null && cachedFrame === frameId) {
|
|
178
|
+
try {
|
|
179
|
+
await sendCDP('Runtime.evaluate', {
|
|
180
|
+
expression: '1',
|
|
181
|
+
contextId: cachedCtx,
|
|
182
|
+
returnByValue: true,
|
|
183
|
+
});
|
|
184
|
+
// Context is still valid — reuse it.
|
|
185
|
+
return cachedCtx;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Context was destroyed (frame navigated), fall through to create.
|
|
189
|
+
}
|
|
190
|
+
}
|
|
134
191
|
try {
|
|
135
192
|
const result = await sendCDP('Page.createIsolatedWorld', {
|
|
136
193
|
frameId,
|
|
@@ -476,6 +533,13 @@ Cypress.Commands.add('disposeA11yOracle', () => {
|
|
|
476
533
|
// Engine was already disabled via orchestrator (same CDP session)
|
|
477
534
|
engine = null;
|
|
478
535
|
}
|
|
536
|
+
// Hand off the current isolated world to the cache so the next
|
|
537
|
+
// initA11yOracle() can reuse it instead of leaking a new one.
|
|
538
|
+
// CDP provides no API to destroy an isolated world; reuse is
|
|
539
|
+
// the only way to prevent accumulation. The cache is consumed
|
|
540
|
+
// (cleared) at the start of the next findAUTContextId() call.
|
|
541
|
+
_cachedWorldContextId = autContextId;
|
|
542
|
+
_cachedWorldFrameId = autFrameId;
|
|
479
543
|
autFrameId = null;
|
|
480
544
|
autContextId = null;
|
|
481
545
|
autIframeBounds = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a11y-oracle/cypress-plugin",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Cypress custom commands for accessibility speech assertions with iframe-aware CDP routing",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "a11y-oracle",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"cypress": ">=12.0.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@a11y-oracle/core-engine": "1.3.
|
|
49
|
-
"@a11y-oracle/keyboard-engine": "1.3.
|
|
50
|
-
"@a11y-oracle/audit-formatter": "1.3.
|
|
48
|
+
"@a11y-oracle/core-engine": "1.3.1",
|
|
49
|
+
"@a11y-oracle/keyboard-engine": "1.3.1",
|
|
50
|
+
"@a11y-oracle/audit-formatter": "1.3.1",
|
|
51
51
|
"tslib": "^2.3.0"
|
|
52
52
|
}
|
|
53
53
|
}
|