GC-301f · Module 3

Form Automation & Testing

3 min read

Form automation tools let Gemini CLI fill and submit web forms — registration flows, search forms, data entry interfaces, checkout processes. Each form field maps to a tool parameter: text inputs, selects, checkboxes, radio buttons, file uploads. The tool fills fields in sequence using page.fill() for text inputs, page.selectOption() for dropdowns, and page.setChecked() for checkboxes. After filling, the tool clicks the submit button and waits for the response — either a success page, a validation error, or a redirect.

End-to-end testing through Gemini CLI flips the traditional testing model. Instead of writing brittle selectors and hardcoded assertions, you describe the test scenario to Gemini and let it drive the browser. "Log in as test user, create a new project, verify it appears in the project list, delete it, confirm deletion." Gemini handles element discovery, waits for dynamic content, and adapts when the UI changes. The test is resilient because the AI interprets the page like a user would — by reading labels and understanding layout, not by memorizing CSS selectors.

async function fillForm(
  fields: Record<string, string>,
  submitSelector = 'button[type="submit"]'
) {
  for (const [selector, value] of Object.entries(fields)) {
    const el = await page.waitForSelector(selector, { timeout: 5000 });
    const tag = await el?.evaluate((e) => e.tagName.toLowerCase());

    if (tag === "select") {
      await page.selectOption(selector, value);
    } else if (tag === "input") {
      const type = await el?.getAttribute("type");
      if (type === "checkbox") {
        await page.setChecked(selector, value === "true");
      } else {
        await page.fill(selector, value);
      }
    } else {
      await page.fill(selector, value);
    }
  }

  await page.click(submitSelector);
  await page.waitForLoadState("networkidle");

  // Check for validation errors
  const errors = await page.$eval(".error, .validation-error", (els) =>
    els.map((e) => e.textContent?.trim()).filter(Boolean)
  );

  return errors.length
    ? { success: false, errors }
    : { success: true, url: page.url(), title: await page.title() };
}

Visual regression testing captures screenshots at key points in a workflow and compares them against baselines. The tool takes a screenshot after each significant action — page load, form submission, modal open — and either saves it as a new baseline or compares it against an existing one using pixel-diff libraries like pixelmatch. Return the diff percentage and a highlighted diff image. Gemini can then decide whether the visual change is expected (a feature update) or unexpected (a regression). Threshold matters: a 0.1% diff is usually anti-aliasing noise. A 5% diff is a layout shift worth investigating.