mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(browser): refresh target after guarded existing-session actions (#104094)
* fix(browser): refresh target after guarded existing-session actions * test(browser): isolate guarded target cases * test(browser): mock safe replacement URL resolution * fix(browser): refresh target after guarded evaluate * style(browser): format guarded action matrix --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
co-authored by
Peter Steinberger
parent
6852016b51
commit
c059d7d062
+26
@@ -43,6 +43,14 @@ vi.mock("../navigation-guard.js", () => navigationGuardMocks);
|
||||
vi.mock("./agent.shared.js", () => createExistingSessionAgentSharedModule());
|
||||
|
||||
const DEFAULT_SSRF_POLICY = { allowPrivateNetwork: false } as const;
|
||||
const GUARDED_TARGET_REFRESH_ACTIONS = [
|
||||
{ kind: "hover", ref: "btn-1" },
|
||||
{ kind: "scrollIntoView", ref: "btn-1" },
|
||||
{ kind: "drag", startRef: "item-1", endRef: "slot-1" },
|
||||
{ kind: "select", ref: "menu-1", values: ["alpha"] },
|
||||
{ kind: "fill", fields: [{ ref: "input-1", value: "Ada" }] },
|
||||
{ kind: "evaluate", fn: "() => document.title" },
|
||||
] as const;
|
||||
|
||||
const { registerBrowserAgentActRoutes } = await import("./agent.act.js");
|
||||
const routeState = existingSessionRouteState;
|
||||
@@ -150,6 +158,24 @@ describe("existing-session interaction navigation guard", () => {
|
||||
expectNavigationProbeUrls(Array.from({ length: 8 }, () => "https://example.com"));
|
||||
});
|
||||
|
||||
it.each(GUARDED_TARGET_REFRESH_ACTIONS)(
|
||||
"resolves current target after guarded $kind interaction",
|
||||
async (body) => {
|
||||
routeState.profileCtx.listTabs
|
||||
.mockResolvedValueOnce([routeState.tab])
|
||||
.mockResolvedValue([{ targetId: "new-target", url: routeState.tab.url }]);
|
||||
|
||||
const response = await runAction(body);
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body).toMatchObject({
|
||||
ok: true,
|
||||
targetId: "new-target",
|
||||
url: routeState.tab.url,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("threads one request budget through coordinate actions and navigation probes", async () => {
|
||||
const handler = getActPostHandler();
|
||||
const response = createBrowserRouteResponse();
|
||||
|
||||
@@ -542,7 +542,7 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
guard: existingSessionNavigationGuard,
|
||||
});
|
||||
return await jsonOk();
|
||||
return await jsonOk(undefined, { resolveCurrentTarget: true });
|
||||
case "scrollIntoView":
|
||||
await runExistingSessionActionWithNavigationGuard({
|
||||
execute: () =>
|
||||
@@ -553,7 +553,7 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
guard: existingSessionNavigationGuard,
|
||||
});
|
||||
return await jsonOk();
|
||||
return await jsonOk(undefined, { resolveCurrentTarget: true });
|
||||
case "drag":
|
||||
await runExistingSessionActionWithNavigationGuard({
|
||||
execute: () =>
|
||||
@@ -564,7 +564,7 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
guard: existingSessionNavigationGuard,
|
||||
});
|
||||
return await jsonOk();
|
||||
return await jsonOk(undefined, { resolveCurrentTarget: true });
|
||||
case "select":
|
||||
await runExistingSessionActionWithNavigationGuard({
|
||||
execute: () =>
|
||||
@@ -575,7 +575,7 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
guard: existingSessionNavigationGuard,
|
||||
});
|
||||
return await jsonOk();
|
||||
return await jsonOk(undefined, { resolveCurrentTarget: true });
|
||||
case "fill":
|
||||
await runExistingSessionActionWithNavigationGuard({
|
||||
execute: () =>
|
||||
@@ -588,7 +588,7 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
guard: existingSessionNavigationGuard,
|
||||
});
|
||||
return await jsonOk();
|
||||
return await jsonOk(undefined, { resolveCurrentTarget: true });
|
||||
case "resize":
|
||||
await resizeChromeMcpPage({
|
||||
...existingSessionTarget,
|
||||
@@ -621,7 +621,7 @@ export function registerBrowserAgentActRoutes(
|
||||
}),
|
||||
guard: existingSessionNavigationGuard,
|
||||
});
|
||||
return await jsonOk({ result });
|
||||
return await jsonOk({ result }, { resolveCurrentTarget: true });
|
||||
}
|
||||
case "close":
|
||||
await profileCtx.closeTab(tab.targetId, {
|
||||
|
||||
@@ -54,6 +54,16 @@ export function createExistingSessionAgentSharedModule() {
|
||||
throw new Error("Playwright should not be used for existing-session tests");
|
||||
}),
|
||||
resolveProfileContext: vi.fn(() => existingSessionRouteState.profileCtx),
|
||||
resolveSafeRouteTabUrl: vi.fn(
|
||||
async (params: {
|
||||
profileCtx: typeof existingSessionRouteState.profileCtx;
|
||||
targetId: string;
|
||||
fallbackUrl?: string;
|
||||
}) => {
|
||||
const tabs = await params.profileCtx.listTabs();
|
||||
return tabs.find((tab) => tab.targetId === params.targetId)?.url ?? params.fallbackUrl;
|
||||
},
|
||||
),
|
||||
resolveTargetIdFromBody: vi.fn((body: Record<string, unknown>) =>
|
||||
typeof body.targetId === "string" ? body.targetId : undefined,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user