Most browser form fillers were built when the web was mostly static HTML with a sprinkle of jQuery. Set element.value, click submit, done. That model is broken for React, Vue, and Angular — frameworks where the visible value and the internal state are two different things, and only one of them gets sent when the form submits.
If your QA team uses a form filler that does not understand controlled inputs, you are not testing your forms. You are testing whether the DOM looks the way you expect, while the framework state silently disagrees.
Why React, Vue, and Angular need different treatment
In a vanilla HTML form, setting input.value = "..." is enough. The form submits whatever is in the DOM.
In a controlled component (React, Vue with v-model, Angular reactive forms), the form does not submit what is in the DOM. It submits what is in the framework's state. And the framework only updates its state when it receives the right event.
Here is what each framework actually needs:
React
React tracks input values in component state via onChange. But React does not listen to the native change event — it listens to its synthetic event system, which intercepts input events and dedupes them.
To autofill a React input correctly, you need to:
- Use the native
HTMLInputElementvalue setter (not justelement.value =) - Dispatch a real
Event('input', { bubbles: true }) - Let React's synthetic event handler pick it up
If you skip step 1 and just write element.value = "foo", React's onChange will not fire on the next render, because React compares the previous value to the new one at the prototype level. This is the single most common reason "my form filler works on every site except this React app".
Vue
Vue's v-model is essentially a wrapper around input events on text inputs and change events on checkboxes/selects. A form filler that fires both will work in almost every Vue 2 and Vue 3 app — but a filler that only sets value and skips events will silently fail every controlled input.
Vue 3 with Composition API and ref() bindings is even stricter: the ref only updates when the bound event fires. No event, no state update, no submit value.
Angular
Angular has two form systems and they behave differently:
- Template-driven forms (
ngModel) listen toinputevents on text fields. A form filler that firesinputwill work. - Reactive forms (
FormControl) are driven by Angular's own change-detection cycle. They listen toinputfor text fields andchangefor selects. They also rerun validators on every event, which is where validation bugs surface.
In both cases, Angular's Validators.required will not clear until the right event fires and Angular's change detection runs. A form filler that bypasses events skips both.
What this looks like when it goes wrong
The symptoms are the same across frameworks:
- the field is visibly filled
- the validation error is still showing
- the submit button is still disabled
- the form state object is empty
- submitting the form (if you can) sends an empty payload
- nobody can reproduce the bug because everyone fills the form by typing
This is why "the form filler works on most sites but not ours" is such a common complaint from teams running React, Vue, or Angular apps. The form filler is doing exactly what it was designed to do — and that design predates controlled components.
What to look for in a framework-aware form filler
Before adopting a form filler for a React, Vue, or Angular codebase, verify all of the following on a test form:
- After autofill, the framework devtools (React DevTools, Vue DevTools, Angular DevTools) show the updated state — not just the updated DOM.
- Required-field validation messages clear without any manual click or tab.
- The submit button enables based on internal validity, not visual state.
- Dependent fields update (country → state → city, plan → seat count).
- Material UI / Ant Design / Vuetify / Angular Material floating labels reset correctly.
- Multi-step forms preserve state across navigation.
- The final submit payload contains every field that was autofilled.
If any of these fail, the form filler is not framework-aware. It is just a value = shim that happens to work on simple forms.
How MockFill handles framework forms
MockFill was built specifically for the controlled-input world:
- it uses the native value setter so React's
onChangefires correctly - it dispatches both
inputandchangeevents withbubbles: true - it triggers
blurto clear focus-bound validation - it works equally well on React, Vue 2, Vue 3, Angular template-driven forms, Angular reactive forms, Svelte, Solid, and vanilla HTML
- it does not require any per-framework configuration
In practice, that means a QA tester can fill a React onboarding flow, a Vue checkout, and an Angular admin form with the same one-click workflow, and the framework state will match the visible UI in all three.
Quick verification you can run today
If you want to know whether your current form filler is framework-aware, run this test in your own app:
- Open a form built with React, Vue, or Angular.
- Open your framework's devtools and watch the form's state.
- Trigger your form filler.
- Check whether the state updated, not just the DOM.
- Try to submit the form without clicking or tabbing first.
If the state did not update or the submit failed, your form filler is not safe for QA work on that codebase.
Install MockFill from the Chrome Web Store
If you are running QA on a React, Vue, or Angular app and your current tool is silently breaking on controlled inputs:
- Install MockFill on Chrome
- Test it on your most complex form and watch the framework devtools to confirm the state updates correctly.

