Browser Form Filling
SkillWeb & browsingUse when filling a multi-field form in the embedded browser. Fill text fields atomically with browser_fill_form, never press Enter per field, submit once, and verify from returned readbacks and DOM.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Browser Form Filling skill
What this skill tells your AI
The instructions your AI receives, as published by 7757/fan-browser-agent in skills/browser/browser-form-filling/SKILL.md and read by ahel’s review.
Overview
Filling a form reliably is mostly about sequencing and verification, not about any single clever action. browser_fill_form resolves all text fields from one snapshot, focuses and clears each target, verifies local readback, and returns one final DOM. The mistakes that waste turns are: separate focus/type/observe calls per field, pressing Enter after every field, and submitting before async validation finished.
Treat a form as one transaction: observe once, pass all text fields to browser_fill_form, handle special controls, then submit exactly once and confirm the result.
When to Use
- Filling login, signup, checkout, search, contact, or any multi-input form.
- Re-entering a field whose value did not persist (React/Vue controlled inputs).
- Don't use for: dropdown selection (use
browser-dropdown-selection), file inputs (usebrowser-file-upload).
Core Recipe
- Observe once.
browser_observeto get the indices of every input/textarea you need. - Fill all text fields once. Call
browser_fill_form(fields=[...]). The runtime resolves every index from one snapshot, fills and verifies each field locally, then returns one final observation.- Do not pass Enter and do not call
browser_send_keys("Enter")between fields.
- Do not pass Enter and do not call
- Handle special controls with their own tools:
browser_select/ open-and-click for dropdowns,browser_uploadfor file inputs,browser_clickfor checkboxes and radios. - Read the transaction result. Check
status,completedCount, and each field'sreadback. Only inspect a field separately when the transaction reports a mismatch or the control has custom behavior. - Submit once on the next model turn.
browser_fill_formreturns the final DOM snapshot; choose the submit control from that refreshed snapshot and click it once. Only usebrowser_send_keys("Enter")when a single text field is explicitly designed for Enter submission. - Confirm from the click result. The submit action returns a fresh DOM. Look there for a success state, redirect, or inline validation errors. Use
browser_settlefollowed bybrowser_observeonly when the result is genuinely delayed.
Framework-Bound Inputs (React / Vue / Angular)
Controlled inputs re-render from state. A naive value assignment can be discarded on the next render, leaving the field visually empty or reverted. browser_type defaults to human typing mode, which dispatches real key events and fires the input/change handlers frameworks listen for — this is the correct default for controlled inputs.
If a value does not persist:
- Re-run
browser_fill_formfor only the failed field withtyping_mode="human"explicitly. - If the field is an autocomplete/combobox, keep
autocomplete_wait=true(default) so the suggestion list settles; raiseautocomplete_wait_msif it's slow. - Only use
typing_mode="direct"for special browser controls (e.g. date/color pickers) that reject synthetic keystrokes — it assigns the value directly and may skip some handlers. - After typing into a field that triggers async state, give it a beat:
browser_settle(waits for DOM readiness + network idle) before reading the value back.
Verifying a Value Landed
Use the fields[].readback returned by browser_fill_form first. That check happens inside the same runtime transaction and costs no additional model tool call.
For a custom control or a reported mismatch, inspect the value explicitly:
browser_element(index=N, operation="attribute", name="value")
or read it live:
browser_element(index=N, operation="evaluate", expression="() => this.value")
If the returned value is empty or wrong, re-type that one field. Retry at most 2-3 times; if it still won't stick, the field may be disabled, masked, or gated by an earlier required field — re-observe and check.
Submit Once, Then Confirm
- Click the actual submit control once. Do not double-click or re-submit "to be safe" — that can create duplicate records.
- Read the fresh DOM returned by the submit action. If the backend response is still pending, call
browser_settleand thenbrowser_observeonce. Look for a success message, URL change, or validation errors. - If validation errors appear, fix only the flagged fields and submit again. Don't refill the whole form.
Common Pitfalls
-
Pressing Enter after each field. Submits the form early or triggers per-field validation that blocks the rest. Type all fields first; submit once at the end.
-
Ignoring transaction readback. Controlled inputs can revert. Check
browser_fill_formfield results; usebrowser_elementonly for a mismatch or custom control. -
Re-observing and reusing old indices. If the page re-rendered (validation appeared, a section expanded), indices may have shifted. Use indices only from the latest observation.
-
Submitting before async work finishes. Autocomplete, availability checks, and debounced validation need a moment.
browser_settlebefore submit when the form does background work. -
Manually clicking/focusing before every
browser_type. Unnecessary —browser_typefocuses for you. Extra clicks can close popovers or open the wrong control. -
Leaving
clearunset when appending.browser_typeclears by default. To append to existing content, passclear=false. -
Double-submitting. Re-clicking submit after a slow response can create duplicates. Wait and confirm instead.
Verification Checklist
- Observed once and captured all field indices up front
- Filled all text fields in one
browser_fill_formcall with no per-field Enter - Dropdowns/uploads/checkboxes handled with their proper tools
- Checked
browser_fill_formstatus and field readbacks (inspected only mismatches separately) -
browser_settleafter fields that trigger async validation - Submitted exactly once and used its returned DOM to confirm success or read validation errors
Signals
- GitHub stars
- 38
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
browser-form-filling- Source
- github.com/7757/fan-browser-agent