Skip to content

Commit 04ba7cc

Browse files
Guard waitForSettledDOM frame-manager option setup
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent dfd2d2d commit 04ba7cc

3 files changed

Lines changed: 67 additions & 2 deletions

File tree

‎currentState.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ HyperAgent exposes a TypeScript SDK for browser automation with three primary pa
121121
- Added per-invocation frame-filter overrides on `page.ai`, `page.perform`, and replay params so workflows can opt in/out of ad/tracking iframe filtering without constructing a new agent.
122122
- Synced frame-filter policy into a11y DOM capture setup (`getA11yDOM`/`captureDOMState`) so first-attempt frame discovery uses the active task/action override instead of stale manager state.
123123
- Hardened per-call frame-filter option reads against trap-prone parameter objects in `executeTask`, `executeTaskAsync`, and `executeSingleAction` (falls back to agent default instead of throwing).
124+
- Hardened `waitForSettledDOM` frame-manager option setup so debug/filter configuration setter failures are isolated to sanitized warnings instead of aborting settle behavior.
124125
- Expanded top-level package exports for key workflow/config types at `@hyperbrowser/agent`.
125126
- Removed stale script entry (`build-dom-tree-script`) and improved README usage docs.
126127
- Added canonical single-action debug writer helper (`writePerformDebug`) while preserving deprecated alias compatibility.

‎src/utils/waitForSettledDOM.test.ts‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,54 @@ describe("waitForSettledDOM diagnostics", () => {
249249
expect(setFrameFilteringEnabled).toHaveBeenCalledWith(false);
250250
});
251251

252+
it("continues when frame-filter configuration throws", async () => {
253+
const warnSpy = jest.spyOn(console, "warn").mockImplementation(() => {});
254+
const { session } = createSessionWithEvents();
255+
const cdpClient: CDPClient = {
256+
rootSession: session,
257+
createSession: async () => session,
258+
acquireSession: async () => session,
259+
dispose: async () => undefined,
260+
};
261+
getCDPClient.mockResolvedValue(cdpClient);
262+
getOrCreateFrameContextManager.mockReturnValue({
263+
setDebug: jest.fn(),
264+
setFrameFilteringEnabled: jest.fn(() => {
265+
throw new Error(`filter\u0000\n${"x".repeat(2_000)}`);
266+
}),
267+
});
268+
getDebugOptions.mockReturnValue({
269+
enabled: false,
270+
traceWait: false,
271+
});
272+
273+
const page = {
274+
context: () => ({}),
275+
} as never;
276+
277+
try {
278+
const waitPromise = waitForSettledDOM(page, 600, {
279+
filterAdTrackingFrames: false,
280+
});
281+
await Promise.resolve();
282+
await Promise.resolve();
283+
await jest.advanceTimersByTimeAsync(700);
284+
const stats = await waitPromise;
285+
286+
expect(stats.resolvedByTimeout).toBe(false);
287+
const warning = String(
288+
warnSpy.mock.calls.find((call) =>
289+
String(call[0] ?? "").includes("configure frame filtering")
290+
)?.[0] ?? ""
291+
);
292+
expect(warning).toContain("[truncated");
293+
expect(warning).not.toContain("\u0000");
294+
expect(warning).not.toContain("\n");
295+
} finally {
296+
warnSpy.mockRestore();
297+
}
298+
});
299+
252300
it("falls back to timeout when network listener registration fails", async () => {
253301
const warnSpy = jest.spyOn(console, "warn").mockImplementation(() => {});
254302
const { session } = createSessionWithEvents({

‎src/utils/waitForSettledDOM.ts‎

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,28 @@ export async function waitForSettledDOM(
172172

173173
const cdpClient = await getCDPClient(page);
174174
const manager = getOrCreateFrameContextManager(cdpClient);
175-
manager.setDebug(traceWait);
175+
try {
176+
manager.setDebug(traceWait);
177+
} catch (error) {
178+
console.warn(
179+
`[waitForSettledDOM] Failed to configure frame manager debug flag: ${formatWaitDiagnostic(
180+
error
181+
)}`
182+
);
183+
}
176184
if (
177185
typeof manager.setFrameFilteringEnabled === "function" &&
178186
typeof options.filterAdTrackingFrames === "boolean"
179187
) {
180-
manager.setFrameFilteringEnabled(options.filterAdTrackingFrames);
188+
try {
189+
manager.setFrameFilteringEnabled(options.filterAdTrackingFrames);
190+
} catch (error) {
191+
console.warn(
192+
`[waitForSettledDOM] Failed to configure frame filtering: ${formatWaitDiagnostic(
193+
error
194+
)}`
195+
);
196+
}
181197
}
182198

183199
const lifecycleSession = await cdpClient.acquireSession("lifecycle");

0 commit comments

Comments
 (0)