fix(browser): default non-finite dialog arm timeouts

This commit is contained in:
Peter Steinberger
2026-05-28 23:44:42 -04:00
parent e7fb8cabb6
commit 18ef59bb33
2 changed files with 29 additions and 1 deletions

View File

@@ -99,6 +99,28 @@ describe("observed browser dialogs", () => {
observed.cleanup();
});
it("uses the default arm-next-dialog timeout for non-finite timeoutMs", async () => {
vi.useFakeTimers();
vi.setSystemTime(0);
const { page, emit } = createPageHarness();
ensurePageState(page);
const dialog = createDialog({ type: "alert", message: "Still armed" });
const observed = createObservedDialogAbortSignalForPage({ page });
armObservedDialogResponseOnPage({ page, accept: false, timeoutMs: Number.NaN });
await vi.advanceTimersByTimeAsync(119_999);
emit("dialog", dialog);
await Promise.resolve();
expect(observed.signal.aborted).toBe(false);
expect(dialog.dismiss).toHaveBeenCalledOnce();
expect(getObservedBrowserStateForPage(page).dialogs.pending).toEqual([]);
expect(getObservedBrowserStateForPage(page).dialogs.recent).toMatchObject([
{ id: "d1", type: "alert", closedBy: "armed" },
]);
observed.cleanup();
});
it("aborts in-flight actions while keeping unarmed dialogs pending", async () => {
const { page, emit } = createPageHarness();
ensurePageState(page);

View File

@@ -1,5 +1,6 @@
import crypto from "node:crypto";
import path from "node:path";
import { parseFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import type {
Browser,
@@ -182,6 +183,11 @@ const connectingByCdpUrl = new Map<string, Promise<ConnectedBrowser>>();
const blockedTargetsByCdpUrl = new Set<string>();
const blockedPageRefsByCdpUrl = new Map<string, WeakSet<Page>>();
function resolveObservedDialogTimeoutMs(timeoutMs: number | undefined): number {
const parsed = parseFiniteNumber(timeoutMs);
return Math.max(1, Math.floor(parsed ?? OBSERVED_DIALOG_TIMEOUT_MS));
}
function normalizeCdpUrl(raw: string) {
return raw.replace(/\/$/, "");
}
@@ -784,7 +790,7 @@ export function armObservedDialogResponseOnPage(opts: {
}): void {
const state = ensurePageState(opts.page);
clearArmedDialogResponse(state);
const timeoutMs = Math.max(1, Math.floor(opts.timeoutMs ?? OBSERVED_DIALOG_TIMEOUT_MS));
const timeoutMs = resolveObservedDialogTimeoutMs(opts.timeoutMs);
const response: ArmedDialogResponse = {
accept: opts.accept,
expiresAt: Date.now() + timeoutMs,