DEV Community

Ishimirwe Denyse
Ishimirwe Denyse

Posted on

I built a Chrome extension that tests web forms with AI

Dev log #1

Hi, I'm Denyse. I'm a software engineer, and for the past two months I've been building a tool I'm genuinely excited about.

It's a Chrome extension that takes a requirements document, uses AI to generate test cases, and then drives a real web form the same way a human QA tester would filling fields, clicking dropdowns, reading validation messages, and producing a pass/fail report.

I'm calling it QA Helper, and I'm going to start writing about it every week. Some weeks will be deep technical posts. Some will be short "here's what I shipped" updates. This is the first one, and the most important one, because it's the one where I actually start.

Up front: the tool is early. It currently works on simple, one-section forms. I'm in the middle of expanding it to handle multi-section forms with all the complexity that brings. The interesting part of this post isn't a finished product it's the engineering problem I had to solve to even get to "working on simple forms," because Angular makes it harder than you'd expect.

Let's go.


The problem: QA testing forms by hand, one keystroke at a time

The QA team I work with tests forms manually. Every required field, every format validation, every conditional dropdown, clicked through by hand. For a long form with many fields, this is hours of work. And every time a developer changes something, the whole cycle starts over.

This isn't a problem unique to any one team. Anywhere you have complex web forms (government services, banking, insurance), you have QA people doing this. It's necessary work. It's also exactly the kind of work software should help with.

So I set out to build something that could starting small and growing the scope as I go.

What QA Helper does today

In plain English:

  1. You upload a requirements document (an SRD, Software Requirements Document) for a form.
  2. The tool reads it with AI and generates a list of test cases: Required Field, Format Validation, Conditional Field, Successful Submit, Label Check.
  3. You open the form in Chrome and click Run Test in the extension.
  4. The extension drives the form, filling fields, clicking dropdowns, capturing screenshots when something fails.
  5. You get a pass/fail report and an Excel export.

Today this works on one-section forms. The field types currently handled:

  • Text inputs — working
  • Native HTML dropdowns — working
  • ng-select dropdowns (Angular's component-based dropdowns) — working
  • Cascading location dropdowns (District → Sector → Cell) — working
  • Radio buttons — partial
  • Date pickers — partial

Multi-section forms are what I'm coding right now. That's the next big unlock.

The stack

Nothing fancy, on purpose:

  • Chrome extension: vanilla JavaScript, content script + popup
  • Backend: Node.js
  • Dashboard: React, hosted on Render
  • AI for test generation: currently Groq + OpenAI, soon moving to Gemini
  • Output: pass/fail report in the dashboard, screenshots on failure, Excel export

The architecture is intentionally boring. The interesting part isn't the stack. It's what happens when the extension tries to fill a form.

The hard part: making Angular believe the form was filled

Here's the thing nobody warned me about when I started.

The forms I'm testing are built with Angular. And in Angular, you cannot just set input.value = "something" and expect the form to notice. Angular's reactive forms have their own internal model of what's in each field, and that model only updates when the right DOM events fire, specifically the events that Angular's DefaultValueAccessor is listening for: input, change, blur.

If you just set the value, the field looks filled in the browser. The pixels are there. But Angular doesn't know. So when the tool clicks Continue, Angular's validator says "this field is empty" and the form refuses to submit.

This took me longer to figure out than I want to admit.

The fix, and the core of how QA Helper actually works, is what I'd call DOM manipulation with framework-aware event dispatch. Instead of just setting values, the tool simulates the actions of a real user, in the order a real user would do them, with the events Angular cares about firing at the right moments.

Three examples of how this plays out:

Text inputs: simulated typing, one character at a time

For a regular text input, the tool doesn't just slam a value in. It:

  1. Focuses the input
  2. Clicks it
  3. Clears it, then appends the value one character at a time, dispatching an input event after each character
  4. Finally dispatches input + change, then blur

It's literally pretending to be a person typing. Slower than it needs to be? Maybe. But it works, and it works reliably, which is more valuable than fast.

ng-select dropdowns: open the panel, find the option, click it

This is the part I'm most proud of figuring out.

Angular's ng-select component doesn't have a settable value. There is no <select> with <option value="..."> you can assign to. The "value" lives inside Angular's component state, and the only way to update it from outside is to drive the component the way a user would.

So for ng-select, the tool:

  1. Clicks the dropdown container to open the option panel
  2. Polls the DOM for the rendered .ng-option elements (they don't exist until the panel opens)
  3. Dispatches mouseenter + click on the option I want

That's it. The component does the rest of the work itself, because as far as it knows, a human just picked an option.

Native <select>, radios, dates

For plain HTML elements, life is easier. Native <select>: set .value, dispatch input and change, done. Radios: call .click() on the element, fire events. Date pickers (including a custom date widget on the platform I'm testing against): same idea, though there are edge cases I'm still working through.

The principle stays the same throughout: set things up the way the DOM expects, then fire the events the framework is listening for.

What still doesn't work (the honest part)

I want to be upfront: this tool is early. A few specific things I'm working on right now.

1. Not all test cases get generated. The AI step that reads the SRD and produces test cases is decent, but not consistent. Sometimes it misses a validation rule that's clearly in the document. Sometimes it generates a test for a field that doesn't exist on the form (often because the SRD and the form have drifted out of sync, useful information in its own right, but still a noisy result). I'm spending real time on prompt engineering and structured output to tighten this up.

2. Multi-section forms. Today the tool works on one-section forms. The QA team I work with tests forms that have many sections, so this is the most important next thing for me to build. I'm in the middle of it.

3. Some field types are still partial. Radio buttons and date pickers work most of the time but not always — they have weird edge cases I'm still untangling. API-backed search-as-you-type dropdowns (where options only appear after you type) aren't supported yet. File uploads, multi-step modal pickers, and signature pads also aren't supported.

I'd rather say this clearly than oversell. The tool already does real engineering work for the cases it handles. The rest is what next month is for.

What's next

  • Multi-section forms — actively coding this now
  • Migrating from Groq + OpenAI to Gemini for test case generation. I want to compare output quality and cost, and Gemini's structured output handling looks promising
  • Performance work — I've been making things faster but I want to actually measure it properly instead of guessing
  • Getting it in front of the QA team for real feedback as soon as it can handle their forms

Why I'm writing this

A few reasons.

One, I've been heads-down for two months and I've learned a lot of small, specific things that are easy to forget. Writing them down makes them stick.

Two, the next time I get stuck on Angular form internals, I want past-me to have left a note for present-me.

Three, I want to keep myself honest about progress. It's much harder to coast for a week when you've committed publicly to writing about it.

If you're working on something similar (Chrome extensions, browser automation, AI-assisted testing, anything where you're trying to make a framework do something it wasn't designed for), I'd love to hear how you're handling it. Drop a comment or reach out.

See you next week.

Denyse


Find me on GitHub and LinkedIn.

Top comments (0)