fix(domains): stop fill_form misreporting select-by-label, let it fail
Three review fixes on the restored fill_form:
- FILL_FN matches a <select> option by value, label or text but returns
el.value, so filling by visible label ("Canada" -> value "ca") tripped
the read-back mismatch check and reported a correctly-set field as
"Filled 0/1 fields; issues: ref e4 (value mismatch)". The mismatch test
now also accepts res.text, which FILL_FN sets only for selects, so
mismatch detection is preserved for every other field kind.
- fill_form always returned ok(), so total failure surfaced as a
successful result reading "Filled 0/4 fields". It now returns
invalid_state when okCount is 0, carrying the per-field issue list as
the error message. Partial success stays ok().
- Removed the two comment blocks this task had added to
test/manual/forms-test.ts.
Neither behaviour fix has automated coverage; the manual suite that would
exercise them still needs a live Chrome and was not run.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
amankumarsingh77 amankumarsingh7702@gmail.com
Tue, 28 Jul 2026 00:40:22 +0530
2 files changed,
5 insertions(+),
10 deletions(-)
M
src/domains/form-batch.ts
→
src/domains/form-batch.ts
@@ -1,5 +1,5 @@
import { Type } from "typebox"; -import { type Result, ok } from "../util/result"; +import { type Result, err, ok } from "../util/result"; import { defineBrowserTool, type ToolErr, type ToolOk } from "../util/tool"; import { detailsOf, resolveAndCall } from "./form";@@ -99,7 +99,7 @@ }
const res = r.data; const wanted = typeof f.value === "boolean" ? undefined : String(f.value); const got = res.value !== undefined ? String(res.value) : undefined; - const mismatch = wanted !== undefined && got !== undefined && got !== wanted; + const mismatch = wanted !== undefined && got !== undefined && got !== wanted && res.text !== wanted; const fieldOk = res.ok === true && !mismatch; if (fieldOk) okCount++; else issues.push(`ref ${f.ref} (${res.ok === false ? (res.reason ?? "failed") : "value mismatch"})`);@@ -108,6 +108,9 @@ }
const text = `Filled ${okCount}/${args.fields.length} fields` + (issues.length > 0 ? `; issues: ${issues.join(", ")}` : ""); + if (okCount === 0) { + return err({ kind: "invalid_state", message: text, details: { results } }); + } return ok({ text, details: { results } }); }, });
M
test/manual/forms-test.ts
→
test/manual/forms-test.ts
@@ -15,12 +15,6 @@ import { createBrowserClient } from "../../src/client";
import { fillTool, selectOptionTool, setCheckedTool } from "../../src/domains/form"; import { fillFormTool } from "../../src/domains/form-batch"; -// NOTE: we intentionally do NOT import snapshotTool here — it pulls in pi-tui / -// pi-coding-agent value imports that don't resolve under bare tsx. Instead we -// publish an 'eN' ref map onto the session from Accessibility.getFullAXTree, -// which is what browser_snapshot does when it prints [eN]. The snapshot's own -// ref rendering is covered by `npm run typecheck` + the real-page smoke test. - let passed = 0; let failed = 0; const check = (cond: boolean, label: string): void => {@@ -60,8 +54,6 @@ window.__model = function () { return model; };
</script> </body></html>`; -// Publish an 'eN' ref map onto the session for the given accessible names and -// return name → ref, mirroring what browser_snapshot does. const publishRefs = async (client: any, names: ReadonlyArray<string>): Promise<Record<string, string | undefined>> => { const ax = await client.session().call("Accessibility.getFullAXTree", {}); if (!ax.success) return {};