aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-27 23:37:04 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commitd54d8e9e2dfbd31358b1f48e17338d74f5d270c0 (patch)
tree485ea036c06666744e4a260bd54aa179c3831d37
parent9f2f75dd9281153888776e5d39d4926655c15f2a (diff)
fix(domains): restore fail-closed focus check in browser_type
Adopting isFocusProbe inverted the safety default: the guard was ANDed into the condition gating the check, so a probe result the guard rejected skipped the check and fell through to Input.insertText — text typed into nothing, silently, which is the exact failure the block exists to prevent. The guard now feeds a value that defaults to { ok: false }, so a rejected shape produces the error instead of bypassing it. The other four guard adoptions (isFillResult, isFocusResult, isSelectResult, isPageResult) were already fail-closed: each feeds a value whose rejection lands on a pre-existing error branch. Also assert x/y in the box centre test — the fields snapshot's off-viewport filter reads — and wrap the zero-size message to the surrounding width. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-rw-r--r--src/domains/box.ts5
-rw-r--r--src/domains/keyboard.ts8
-rw-r--r--test/domains/box-test.ts2
3 files changed, 8 insertions, 7 deletions
diff --git a/src/domains/box.ts b/src/domains/box.ts
index 7b12e82..e013f70 100644
--- a/src/domains/box.ts
+++ b/src/domains/box.ts
@@ -41,7 +41,10 @@ export const boxOf = async (
return err({ kind: "invalid_state", message: "DOM.getBoxModel returned an incomplete content quad" });
}
if (model.width <= 0 || model.height <= 0) {
- return err({ kind: "invalid_state", message: "element has a zero-size box and cannot be clicked" });
+ return err({
+ kind: "invalid_state",
+ message: "element has a zero-size box and cannot be clicked",
+ });
}
return ok(centreOf(model));
};
diff --git a/src/domains/keyboard.ts b/src/domains/keyboard.ts
index 21681c5..6722ffb 100644
--- a/src/domains/keyboard.ts
+++ b/src/domains/keyboard.ts
@@ -27,10 +27,6 @@ export const typeTool = defineBrowserTool({
],
parameters: TypeArgs,
async handler(args, { client }): Promise<Result<ToolOk, ToolErr>> {
- // Guard against silent text loss: Input.insertText succeeds regardless of
- // whether an editable element is focused, so without this check typed text
- // can vanish into the void with no error. Fail loudly with an actionable
- // message instead. IIFE starts with "(" so evaluateJs returns it directly.
const focused = await client.evaluateJs(safeJs`
(() => {
const el = document.activeElement;
@@ -39,8 +35,8 @@ export const typeTool = defineBrowserTool({
return { ok, tag: el ? el.tagName : null };
})()
`);
- if (focused.success && isFocusProbe(focused.data)) {
- const f = focused.data;
+ if (focused.success) {
+ const f: FocusProbe = isFocusProbe(focused.data) ? focused.data : { ok: false, tag: null };
if (!f.ok) {
return err({
kind: "invalid_state",
diff --git a/test/domains/box-test.ts b/test/domains/box-test.ts
index cb930a0..248ae38 100644
--- a/test/domains/box-test.ts
+++ b/test/domains/box-test.ts
@@ -5,6 +5,8 @@ import { centreOf } from "../../src/domains/box";
describe("box centre", () => {
test("computes the centre from a content quad", () => {
const b = centreOf({ content: [10, 20, 110, 20, 110, 70, 10, 70], width: 100, height: 50 });
+ assert.equal(b.x, 10);
+ assert.equal(b.y, 20);
assert.equal(b.cx, 60);
assert.equal(b.cy, 45);
assert.equal(b.width, 100);