aboutsummaryrefslogtreecommitdiff
path: root/src/domains/click.ts
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-28 00:17:13 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commitbfba73fa2f1373abd8a5a704c9c833d6fce1b44f (patch)
treee684310863ef6d9aaa9a6bd3d4d3100d75ee9069 /src/domains/click.ts
parent5cfa7ccc8f4082db111bc0186c5fa3d44b767ad3 (diff)
refactor(domains): share target resolution and CDP error mapping
The ref-vs-x/y branch turned out to exist in one tool, not four; it is now one helper with tests covering the half-specified-coordinate and stale-ref cases. cdpCall folds the repeated cdp_error mapping at 24 active-session call sites; target-scoped callOnTarget/callBrowser sites are left alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'src/domains/click.ts')
-rw-r--r--src/domains/click.ts39
1 files changed, 13 insertions, 26 deletions
diff --git a/src/domains/click.ts b/src/domains/click.ts
index 81bd7ca..0215d9a 100644
--- a/src/domains/click.ts
+++ b/src/domains/click.ts
@@ -2,10 +2,12 @@ import { Type } from "typebox";
import { Text } from "@mariozechner/pi-tui";
import type { BrowserClient } from "../client";
import { Coords, MouseButton } from "../schemas/common";
-import { type Result, err, ok } from "../util/result";
+import { type Result, ok } from "../util/result";
import { defineBrowserTool, type ToolErr } from "../util/tool";
+import { cdpCall } from "./cdp-call";
import { captureWithCrosshair } from "./screenshot";
-import { interactiveDiff, resolveRefToBox } from "./ref-resolve";
+import { interactiveDiff } from "./ref-resolve";
+import { resolveTarget } from "./target";
const ClickArgs = Type.Object({
ref: Type.Optional(
@@ -37,18 +39,16 @@ const dispatchClick = async (
// Move the pointer to the target first. Some focus/hover handlers (and React
// synthetic events) only fire when a mousemove precedes the press, so without
// it a click can land without focusing the element.
- const moved = await client.session().call("Input.dispatchMouseEvent", {
- type: "mouseMoved", x, y,
- });
- if (!moved.success) return err({ kind: "cdp_error", message: moved.error.message });
- const pressed = await client.session().call("Input.dispatchMouseEvent", {
+ const moved = await cdpCall(client, "Input.dispatchMouseEvent", { type: "mouseMoved", x, y });
+ if (!moved.success) return moved;
+ const pressed = await cdpCall(client, "Input.dispatchMouseEvent", {
type: "mousePressed", x, y, button, clickCount: count,
});
- if (!pressed.success) return err({ kind: "cdp_error", message: pressed.error.message });
- const released = await client.session().call("Input.dispatchMouseEvent", {
+ if (!pressed.success) return pressed;
+ const released = await cdpCall(client, "Input.dispatchMouseEvent", {
type: "mouseReleased", x, y, button, clickCount: count,
});
- if (!released.success) return err({ kind: "cdp_error", message: released.error.message });
+ if (!released.success) return released;
return ok(undefined);
};
@@ -73,26 +73,13 @@ export const clickTool = defineBrowserTool({
const button = args.button ?? "left";
const count = args.count ?? 1;
- // Resolve the click point: ref re-resolves to the element's CURRENT box
- // (so re-renders don't matter); otherwise use the literal x/y.
- let x: number;
- let y: number;
- if (args.ref !== undefined) {
- const box = await resolveRefToBox(client, args.ref);
- if (!box.success) return box;
- x = box.data.cx;
- y = box.data.cy;
- } else if (args.x !== undefined && args.y !== undefined) {
- x = args.x;
- y = args.y;
- } else {
- return err({ kind: "invalid_state", message: "Provide either `ref` or both `x` and `y`." });
- }
+ const resolved = await resolveTarget(client, args);
+ if (!resolved.success) return resolved;
+ const { x, y, label: target } = resolved.data;
const clicked = await dispatchClick(client, x, y, button, count);
if (!clicked.success) return clicked;
- const target = args.ref !== undefined ? `[${args.ref}] (${x}, ${y})` : `(${x}, ${y})`;
const diff = await interactiveDiff(client);
if (process.env["BH_DEBUG_CLICKS"]) {
const debug = await captureWithCrosshair(client, { x, y });