Playwright Browser Automation — JS Form Fill Pattern
Overview
Pattern for automating complex web forms via Playwright MCP using
browser_evaluate with raw DOM JavaScript. Bypasses input masks, session-sensitive forms, and flaky UI interactions that break with standard Playwright .fill() and .click().Problem
Playwright's standard UI interaction tools (
browser_type, browser_click, browser_select_option) fail on:- Input masks — SSN fields (
___-__-____), phone, date fields that fight with.fill() - Session-sensitive forms — multi-page wizards (JSF, ASP.NET) that lose state between interactions
- Submit button targeting —
.click()hitting wrong elements when multiple buttons share text - Radio buttons with JS listeners — state changes that don't fire with Playwright's synthetic events
Solution: 3-Step JS Pattern
Step 1: Inspect — map all form fields
Step 2: Fill — set all values with proper event dispatch
Step 3: Submit — click by ID
Key Details
- Event dispatch is critical — React, JSF, and Angular forms listen for
input,change, andblurevents. Setting.valuealone doesn't register. focus()before setting value — helps input mask fields initialize properly- For radios: set
.checked = true, then dispatchchangeand call.click() - Inspect first, fill second, submit third — never combine steps; IDs may change between pages
- Return values for verification — every fill function returns true/false so you confirm all fields were set
When to Use
- Government forms (VitalChek, DMV, business registration)
- Any JSF/server-rendered form with input masks
- Multi-page wizards that lose state with slow UI interactions
- Forms where
browser_type/browser_clickfail more than once
When NOT to Use
- Simple forms with no input masks — standard Playwright tools work fine
- Forms behind iframes from different origins (Stripe Elements) — can't access cross-origin DOMs
Origin
Discovered 2026-03-30 while automating PA VitalChek birth certificate order for Marcus Draney's DoorDash onboarding. Standard Playwright interactions failed 3 times on the SSN masked input and multi-page JSF form. One
browser_evaluate call filled all fields and submitted successfully.