Skip to content

Commit 9934029

Browse files
Guard cache-hydration debug setter in a11y provider
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 3454cdb commit 9934029

3 files changed

Lines changed: 79 additions & 1 deletion

File tree

currentState.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ HyperAgent exposes a TypeScript SDK for browser automation with three primary pa
201201
- `collectExecutionContexts()` now also guards trap-prone `session.send` reads for `Runtime.enable`, preventing getter traps from aborting the context collection path.
202202
- Hardened frame-sync debug handling in a11y context provider:
203203
- `syncFrameContextManager()` now guards trap-prone frame-manager `setDebug` calls, preserving sync flow with sanitized debug warnings.
204+
- Hardened cache-hydration debug handling in a11y context provider:
205+
- `hydrateFrameContextFromSnapshot()` now guards trap-prone frame-manager `setDebug` calls so cache hydration continues instead of aborting early.
204206
- Refreshed remaining staged-flow wording in the CDP deep dive around OOPIF discovery to describe current execution-context sync progression without stale "Need Phase 4" phrasing.
205207
- Hardened CDP command dispatch in Playwright session adapter:
206208
- `PlaywrightSessionAdapter.send()` now guards trap-prone `session.send` method reads and wraps sync send failures with sanitized/diagnostic context.

src/context-providers/a11y-dom/index.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Page } from "playwright-core";
22
import { getA11yDOM } from "@/context-providers/a11y-dom";
3+
import { domSnapshotCache } from "@/context-providers/a11y-dom/dom-cache";
34

45
const getCDPClientMock = jest.fn();
56
const getOrCreateFrameContextManagerMock = jest.fn();
@@ -472,4 +473,69 @@ describe("getA11yDOM error formatting", () => {
472473
errorSpy.mockRestore();
473474
}
474475
});
476+
477+
it("continues cache hydration when frame-manager debug setter traps", async () => {
478+
const page = {
479+
url: jest.fn(() => "https://example.com"),
480+
} as unknown as Page;
481+
const cachedState = {
482+
domState: "cached dom",
483+
elements: new Map(),
484+
xpathMap: {},
485+
backendNodeMap: {},
486+
frameMap: new Map([
487+
[
488+
1,
489+
{
490+
frameIndex: 1,
491+
siblingPosition: 0,
492+
frameId: "frame-1",
493+
xpath: "//iframe[1]",
494+
parentFrameIndex: 0,
495+
},
496+
],
497+
]),
498+
} as unknown as Parameters<typeof domSnapshotCache.set>[1];
499+
domSnapshotCache.set(page, cachedState);
500+
501+
const rootSession = {
502+
id: "session-1",
503+
send: jest.fn().mockResolvedValue({
504+
frameTree: {
505+
frame: {
506+
id: "root-frame",
507+
parentId: undefined,
508+
loaderId: "loader-1",
509+
name: "root",
510+
url: "https://example.com",
511+
},
512+
},
513+
}),
514+
};
515+
const ensureInitialized = jest.fn().mockResolvedValue(undefined);
516+
getCDPClientMock.mockResolvedValue({
517+
rootSession,
518+
});
519+
getOrCreateFrameContextManagerMock.mockReturnValue({
520+
setDebug: jest.fn(() => {
521+
throw new Error("cache-hydration debug trap");
522+
}),
523+
ensureInitialized,
524+
upsertFrame: jest.fn(),
525+
assignFrameIndex: jest.fn(),
526+
setFrameSession: jest.fn(),
527+
getFrameByBackendNodeId: jest.fn(),
528+
getFrameSession: jest.fn(),
529+
});
530+
531+
try {
532+
const result = await getA11yDOM(page, false, false, undefined, {
533+
useCache: true,
534+
});
535+
expect(result.domState).toBe("cached dom");
536+
expect(ensureInitialized).toHaveBeenCalled();
537+
} finally {
538+
domSnapshotCache.invalidate(page);
539+
}
540+
});
475541
});

src/context-providers/a11y-dom/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,17 @@ async function hydrateFrameContextFromSnapshot(
495495
try {
496496
const cdpClient = await getCDPClient(page);
497497
const manager = getOrCreateFrameContextManager(cdpClient);
498-
manager.setDebug(debug);
498+
try {
499+
manager.setDebug(debug);
500+
} catch (error) {
501+
if (debug) {
502+
console.warn(
503+
`[FrameContext] Failed to configure cache-hydration debug mode: ${formatA11yDiagnostic(
504+
error
505+
)}`
506+
);
507+
}
508+
}
499509
await manager.ensureInitialized().catch(() => {});
500510
await syncFrameContextManager({
501511
manager,

0 commit comments

Comments
 (0)