ideas.
June 07, 2026 3 min read browser-extensiondev-toolsautomation

Browser-based interaction recorder for Playwright tests

A browser extension that records user clicks and form interactions, then exports them as ready-to-run Playwright test scripts — no manual test authoring needed.

The idea

Most developers avoid writing end-to-end tests because authoring them is tedious: open a spec file, write selectors, handle async waits, guess at the right assertions. This extension records what you do in the browser and converts it to a working Playwright .spec.ts file. Click record, do the thing, hit stop, download the test.

The recording captures clicks, form fills, navigation, and keypresses. It resolves selectors in priority order: data-testid, ARIA labels, visible text, then a stable CSS path as a last resort. The exported file uses await expect(page.locator(...)).toBeVisible() style assertions derived from what was on screen at the moment of interaction.

Why build this

Playwright ships its own codegen tool (playwright codegen <url>), but it requires a separate terminal session and a Node installation. QA contributors, designers, and non-engineering teammates working in a browser-first workflow can't or won't use a CLI. A browser extension brings the same capability without leaving the tab.

The gap exists because Chrome extension APIs give you DOM access and user event observation without needing a proxy or an instrumented browser binary. The timing is good: Playwright's test format has stabilized and is now the default E2E choice in most new TypeScript projects, so generated files are likely to just work.

Stack sketch

  • Manifest V3 Chrome extension (runs in Chrome, Edge, Arc)
  • Content script to intercept and record DOM events via addEventListener with capture: true
  • Background service worker to buffer events and manage recording state across navigations
  • Extension popup for record / stop / export controls, built with plain HTML + Alpine.js
  • TypeScript throughout; Vite with vite-plugin-web-extension for the build
  • Selector resolution logic ported from Playwright's own @playwright/test internals (MIT-licensed) into the content script
  • No backend, no account — export is a Blob download to disk

Scope for v1

  • Record clicks, input and change events, form submissions, and Enter/Tab keypresses
  • Detect data-testid, aria-label, placeholder, name, and visible button/link text as selector candidates; fall back to a minimal stable CSS path when nothing better exists
  • Export as a single .spec.ts file with test(), page.goto(), page.locator().click(), page.locator().fill(), and expect().toBeVisible() calls
  • One recording session at a time; no history or session replay UI
  • Works on HTTP and HTTPS pages
  • Deliberately out of v1: iframe recording, shadow DOM, drag-and-drop, Firefox port, Safari MV3 port

Where it could go

If v1 proves useful, the most valuable next step is smarter assertions: instead of only asserting that interacted elements are visible, watch for DOM changes after each action and generate toHaveText or toHaveCount assertions automatically. That moves the output from "a test that does not crash" to "a test that validates observable behavior."

A second expansion worth considering is a visual baseline mode: capture a screenshot after each navigation, store it alongside the .spec.ts, and inject expect(page).toMatchSnapshot() calls automatically. Paired with Playwright's own snapshot update tooling, a recorded session becomes a pixel-level regression guardrail in a single click.

Watch out for

Dynamic selectors — React keys, server-rendered class hashes, randomly generated IDs — are the primary failure mode. The extension should warn the user explicitly when it falls back to a CSS path selector, rather than silently generating a test that will break on the next deploy.