DEV Community

Srikanth Srinivas
Srikanth Srinivas

Posted on

Playwright Studio from AIQEAcademy

Playwright Studio is a Chrome DevTools extension that lets you record interactions, add assertions, save tests with version history, and run them headlessly — all from inside DevTools. No terminal. No setup. No copy-pasting from codegen.


The Problem With Existing Tools

playwright codegen is excellent for a quick start. But it has real limitations in daily use:

  • It opens a separate browser window — breaking your authenticated session
  • Generated code needs manual cleanup before it's mergeable
  • There's no way to add assertions interactively
  • Nothing is saved — it's a one-shot dump to stdout

For teams doing continuous authoring — adding coverage as features ship — you need something embedded in your workflow. That's what Playwright Studio is.


What It Does

The extension lives in your Chrome DevTools panel. Here's the core loop:

1. Record

Click Record and interact with the page normally. The extension captures:

  • page.goto() calls from navigation
  • page.click() with Playwright-native locators (preferring getByRole, getByLabel, getByText over brittle CSS selectors)
  • page.fill() for inputs
  • page.selectOption() for dropdowns
  • page.check() / page.uncheck() for checkboxes

Every captured action generates idiomatic Playwright code in real time — you see it build line by line in the panel.

// Example of what gets generated:
import { test, expect } from '@playwright/test';

test('User login flow', async ({ page }) => {
  await page.goto('https://myapp.com/login');
  await page.getByLabel('Email').fill('user@example.com');
  await page.getByLabel('Password').fill('••••••••');
  await page.getByRole('button', { name: 'Sign in' }).click();
  await expect(page).toHaveURL('/dashboard');
  await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
});
Enter fullscreen mode Exit fullscreen mode

2. Assert

Right-click any element while recording and add assertions:

Assertion Generated Code
Visible await expect(locator).toBeVisible()
Has text await expect(locator).toHaveText('...')
URL matches await expect(page).toHaveURL('...')
ARIA role await expect(locator).toHaveRole('button')
Count await expect(locator).toHaveCount(3)

No manual expect() wiring. You pick the element, pick the assertion type, and it slots into the generated test at the right position.

3. Save

Tests are saved inside the extension with:

  • Name and tags for organization
  • Version history — every edit creates a new version, old ones are preserved
  • Selector tracking — the extension records which locators were used so you can spot fragility early
  • Metadata — source, timestamp, test status

4. Run

Hit Run and the test executes headlessly inside Chrome using the Playwright runner bundled with the extension. Results come back as a step-by-step pass/fail report — no terminal needed.

5. Export

One click exports a clean .spec.ts file. Drop it into your existing Playwright project. It works.


Architecture

The extension is built on Chrome's Manifest V3 with three layers:

┌──────────────────────────────────────────────┐
│  DevTools Panel (React)                       │
│  Recording UI · Test editor · Result viewer   │
└────────────────────┬─────────────────────────┘
                     │ chrome.runtime.sendMessage
┌────────────────────▼─────────────────────────┐
│  Background Service Worker                    │
│  State management · Test storage · Runner     │
└────────────────────┬─────────────────────────┘
                     │ chrome.scripting.executeScript
┌────────────────────▼─────────────────────────┐
│  Content Script                               │
│  DOM event capture · Selector generation      │
└──────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Selector Strategy

The hardest part of any recorder is generating selectors that don't break the moment someone renames a CSS class. Playwright Studio uses a priority-ordered strategy:

  1. getByRole() — if the element has a semantic ARIA role and accessible name
  2. getByLabel() — for form inputs bound to a <label>
  3. getByText() — for elements with stable visible text
  4. getByTestId() — if data-testid is present
  5. locator('css=...') — last resort, flagged as potentially fragile

Each selector is stored alongside fallbacks, laying the groundwork for self-healing in a future release.

Test Runner

Running tests from inside the extension uses a sandboxed execution context. The generated Playwright script is evaluated with:

  • Action replay against the live page
  • Step-level timing capture
  • Console log collection
  • Screenshot on failure

What's Coming Next

Playwright Studio v1 covers the core authoring loop. The roadmap includes:

  • Cloud sync — push tests from the extension to a cloud backend, run them remotely with full parallel execution across Chromium/Firefox/WebKit
  • AI assertion generation — right-click an element and Claude suggests the most meaningful assertion based on context
  • Self-healing selectors — when a selector breaks, the extension proposes a fix based on the updated DOM
  • Visual regression — capture baseline screenshots and diff them on every run
  • MCP integration — expose tests to AI agents (Claude, Cursor, VS Code Copilot) via the Model Context Protocol

Try It

https://chromewebstore.google.com/detail/playwright-studio-by-aiqe/eodfkbagoeghobkkfpcfpacnnpgidhhd?authuser=0&hl=en

If you're building test automation tooling, working on Chrome extensions, or just have opinions about Playwright selector strategies — I'd love to hear from you.


Top comments (0)