fix(browser): default non-finite snapshot timeouts

This commit is contained in:
Peter Steinberger
2026-05-28 23:48:25 -04:00
parent 27b15a19e8
commit b2bdad5bee
2 changed files with 39 additions and 2 deletions

View File

@@ -131,6 +131,37 @@ describe("pw-tools-core aria snapshot storage", () => {
expect(ariaSnapshotMock).toHaveBeenCalledWith({ mode: "ai", timeout: 8888 });
});
it("uses the default snapshot timeout for non-finite role-aria timeouts", async () => {
const ariaSnapshotMock = vi.fn().mockResolvedValue("");
const page = { ariaSnapshot: ariaSnapshotMock };
getPageForTargetId.mockResolvedValue(page);
const mod = await import("./pw-tools-core.snapshot.js");
await mod.snapshotRoleViaPlaywright({
cdpUrl: "http://127.0.0.1:9222",
targetId: "tab-1",
refsMode: "aria",
timeoutMs: Number.NaN,
});
expect(ariaSnapshotMock).toHaveBeenCalledWith({ mode: "ai", timeout: 5000 });
});
it("uses the default snapshot timeout for non-finite ai snapshot timeouts", async () => {
const ariaSnapshotMock = vi.fn().mockResolvedValue("");
const page = { ariaSnapshot: ariaSnapshotMock };
getPageForTargetId.mockResolvedValue(page);
const mod = await import("./pw-tools-core.snapshot.js");
await mod.snapshotAiViaPlaywright({
cdpUrl: "http://127.0.0.1:9222",
targetId: "tab-1",
timeoutMs: Number.NaN,
});
expect(ariaSnapshotMock).toHaveBeenCalledWith({ mode: "ai", timeout: 5000 });
});
it("stores role fallback metadata when backend markers are unavailable", async () => {
const page = { id: "page-1" };
const mod = await import("./pw-tools-core.snapshot.js");

View File

@@ -1,3 +1,4 @@
import { parseFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
@@ -34,6 +35,11 @@ type SnapshotUrlEntry = {
url: string;
};
function resolveSnapshotTimeoutMs(timeoutMs: number | undefined): number {
const parsed = parseFiniteNumber(timeoutMs);
return Math.max(500, Math.min(60_000, Math.floor(parsed ?? 5_000)));
}
async function collectSnapshotUrls(page: Page): Promise<SnapshotUrlEntry[]> {
const urls = await page
.evaluate(() => {
@@ -227,7 +233,7 @@ export async function snapshotAiViaPlaywright(opts: {
let snapshot = await page.ariaSnapshot({
mode: "ai",
timeout: Math.max(500, Math.min(60_000, Math.floor(opts.timeoutMs ?? 5000))),
timeout: resolveSnapshotTimeoutMs(opts.timeoutMs),
});
if (opts.urls) {
snapshot = appendSnapshotUrls(snapshot, await collectSnapshotUrls(page));
@@ -284,7 +290,7 @@ export async function snapshotRoleViaPlaywright(opts: {
});
}
const ariaSnapshotTimeout = Math.max(500, Math.min(60_000, Math.floor(opts.timeoutMs ?? 5000)));
const ariaSnapshotTimeout = resolveSnapshotTimeoutMs(opts.timeoutMs);
if (opts.refsMode === "aria") {
if (normalizeOptionalString(opts.selector) || normalizeOptionalString(opts.frameSelector)) {