Open-source AI coworkers that each get a computer of their own: a browser, files and tools, with every action decided before it happens and recorded after. Bring any AG-UI agent.
Playwright test scaffold for Claude Code, Cursor, and Copilot
Agentic Playwright is a cloneable Playwright + TypeScript scaffold for test automation. It bundles page objects, fixtures, API testing, data factories, CI, and agent rules so your coding assistant follows the same testing patterns from the first prompt.
Builders who want their coding agent to start from a Playwright testing scaffold instead of a blank repo.
You can start a new test suite with the project structure, rules, and examples already in place.
What it does
Playwright test scaffold
Creates a ready-to-fill Playwright + TypeScript project with example specs, page objects, fixtures, and config.
Agent rule trees
Includes separate rule sets for Claude Code, Cursor, and GitHub Copilot in `.claude/`, `.cursor/`, and `.github/instructions/`.
Constitution enforcement hook
Uses `.claude/scripts/enforce_constitution.py` as a pre-write hook to block forbidden test patterns before they land.
Confidence-gated workflow
Routes non-trivial agent work through the `ai-native-workflow` skill with required confidence, rationale, and unknowns.
API testing support
Adds an `apiRequest` fixture, Zod schema validation, and helper fixtures for setup and teardown.
Setup scripts and containers
Provides `npm create`, `bash scripts/setup.sh`, and a Dev Container path for getting started.
How to get it
- 1The fastest path — scaffold a fresh project with everything wired, straight into the…
npm create agentic-playwright . -- --demo
- 2Why the .? It scaffolds into the current directory and names the project after the…
npm create agentic-playwright my-tests -- --demo # same, but in ./my-tests npm create agentic-playwright . # interactive — 4 questions npm create agentic-playwright . -- --bare # your own app URLs
- 3Clone the repository
git clone <your-repository-url> # replace with your fork/clone URL cd playwright-scaffold
- 4This renders a rich status bar at the bottom of the Claude Code terminal
✦ main ● | 📁 project | 🤖 Sonnet 4.6 | ⏳ 12m05s | 💰 $1.42 | + 85 | — 12 | [████████░░░░] 42.5% (85,012/200k)
- 5Clone the repository
git clone <your-repository-url> # replace with your fork/clone URL cd playwright-scaffold
- 6Run the setup script
bash scripts/setup.sh
README
Agentic Playwright
Stop teaching your AI how to write tests. Hand it the rulebook.
Production-grade Playwright + TypeScript Scaffold for Agentic Testing.
A complete, running test framework — page objects, API contracts, data factories, CI —
plus the AI rules your assistant picks up automatically, from the very first prompt.
See it
From the (empty) directory your project should live in — the . means "scaffold right
here, and name the project after this folder" (a fresh git clone of an empty repo
works too). Prefer a new subfolder? Pass a name instead of .:
npm create agentic-playwright . -- --demo
Zero questions. Scaffolds the framework, installs dependencies and a browser, and ends by running the smoke test against a live demo application — you see green before writing a line. Under 5 minutes on normal broadband.
Full System Explained Live
Debbie O'Brien and Ivan Davidov will walk through the architecture at C3, "Orchestrating Agentic Test Automation with Playwright". October 21st, online, organized by Packt
Without the rulebook vs with it
The same prompt — "write a test for the product search" — to the same AI assistant:
// ❌ Unsupervised: XPath, hard waits, `any`, magic timeouts, no structure
test('search', async ({ page }) => {
await page.goto('https://practicesoftwaretesting.com');
await page.locator('//input[@id="search-query"]').fill('pliers');
await page.locator('//button[@type="submit"]').click();
await page.waitForTimeout(5000);
const cards: any = await page.$$('.card');
expect(cards.length > 0).toBe(true);
});
// ✅ With Agentic Playwright: fixtures, steps, web-first assertions
import { expect, test } from '../../../fixtures/pom/test-options';
test(
'should show only matching products when searching',
{ tag: '@regression' },
async ({ homePage }) => {
await test.step('GIVEN the user is on the home page', async () => {
await homePage.open();
});
await test.step('WHEN the user searches for "pliers"', async () => {
await homePage.searchFor('pliers');
});
await test.step('THEN every result matches the search term', async () => {
await expect(homePage.searchCaption).toContainText('pliers');
await expect(homePage.productNames.first()).toContainText('Pliers');
});
}
);
Dependency-injected page objects, Given/When/Then steps, web-first assertions, no hard
waits, no any, one tag per test — enforced by a Constitution and 17 skills the
assistant loads automatically, with a write-time hook that blocks the forbidden
patterns outright.
Not affiliated with Microsoft. Playwright is an open-source project by Microsoft; this scaffold builds on it.
This is a scaffold, not a finished framework. The example files (
AppPage,login.spec.ts,NavigationComponent, etc.) demonstrate the patterns and conventions you should follow. Replace them with your real application's pages, tests, and data as you build out your test suite.
Table of Contents
- Features
- Prerequisites
- Quick Start: npm create
- Quick Start: Dev Container
- Quick Start: Local Setup Script
- Manual Installation
- Getting Started: Adapting the Scaffold
- Project Structure
- Configuration
- Environment Variables
- Running Tests
- Tag Reference
- Writing Tests
- Page Object Model
- API Testing
- Data Strategy
- Authentication Setup
- Code Quality
- Coding Standards
- Core Principles (The Constitution)
- AI-Assisted Development Workflow
- AI Rules Architecture
- Architecture Overview
- Troubleshooting
- Agentic Playwright Pro
- License
Features
- TypeScript -- Full type safety with strict mode enabled
- Page Object Model -- Maintainable and scalable test architecture
- Fixture-based Architecture -- Reusable test components with dependency injection
- API Testing -- Built-in
apiRequestfixture with Zod schema validation and helper fixtures for setup/teardown - Multi-browser Support -- Chrome, Firefox, and WebKit configurations
- Environment Management -- Flexible
.envconfiguration with multi-environment support - Authentication Handling -- Pre-configured storage state for authenticated tests
- Code Quality -- ESLint + Prettier + Husky pre-commit hooks
- Parallel Execution -- Fast test runs with configurable workers
- Comprehensive Reporting -- HTML reports with traces, screenshots, and videos
- AI-Assisted Development -- Modular orchestrator rules for Claude Code, Cursor, and GitHub Copilot with glob-scoped auto-loading. Each tool's rule tree (
.claude/,.cursor/,.github/instructions/) is self-contained and stands alone. - Confidence-Gated Workflow -- The
ai-native-workflowskill is the sole entry-point router for non-trivial work. Every plan must includeConfidence: <1-10>,Rationale, andUnknowns; below confidence 5 the agent is required to stop and ask the user for the missing primary input rather than emit a plan built on guesses. - Constitution Enforcement Hook --
.claude/scripts/enforce_constitution.pyis wired as a Claude CodePreToolUsehook in.claude/settings.json. It blocks anyWrite/Edit/MultiEditthat would introduce a mechanically-detectable WON'T violation (waitForTimeout,z.objectin schemas, XPath,@playwright/testimports in specs,.jsonstatic data, the@functionaltag, tags ontest.describe()) before the file is ever written -- a hard backstop beneath the prompt-level rules. - Version Single-Source -- the root
VERSIONfile is the one source of truth for the product version.npm run version:stampwrites it intopackage.json;npm run check:versionassertsVERSION==package.json== the latestCHANGELOG.mdheading and fails on drift. Gated in.husky/pre-commit(when a version surface is staged) and in CI (skill-lint.yml). - Pre-Commit Drift Lints --
npm run check:skills-driftkeeps Constitution rules anchored in their owning skill's Critical block;npm run check:skills-referenceswalks all three rule trees (.claude/skills/,.cursor/skills/,.github/instructions/,.github/skills/) and catches broken pointers, orphan references, and broken section anchors between eachSKILL.mdand itsreferences/siblings. Both fire from.husky/pre-commitwhenever any of those trees has files staged. - Upstream Skill Sync --
skills-lock.jsonrecords the SHA-256 of the locally vendored copies ofskill-creator(fromanthropics/skills) andplaywright-cli(from@playwright/cli).npm run skills:verifyre-hashes the local files and exits non-zero on drift;npm run skills:reinstallfetches upstream, overwrites.claude/skills/<name>/SKILL.mdand.cursor/skills/<name>/SKILL.md, and refreshes the lock;npm run skills:updatere-locks after intentional local edits. - Playwright CLI Exploration --
playwright-cliis the default browser exploration path for UI discovery, tracing, storage inspection, and flow capture - Out-of-the-Box Anthropic Skills --
playwright-cliandskill-creatorare reinstalled fresh from the upstream Anthropic packages and tracked viaskills-lock.jsonfor reproducible installs - AI Task Workflows Playbook --
AI-WORKFLOWS.mdmaps the exact step sequence for every common flow (API suite for a controller, functional tests from a ticket, E2E suite, debugging, refactors, and more) to its owning skill and phase, with an anti-drift guardrails table -- so AI-assisted execution stays consistent across sessions
Prerequisites
- Node.js v22.x or later
- npm v10.x or later
Quick Start: npm create
The fastest path — scaffold a fresh project with everything wired, straight into the directory you are standing in:
npm create agentic-playwright . -- --demo
Why the .? It scaffolds into the current directory and names the project
after the folder — the natural fit when you have already created (or cloned) an empty
repo for your tests. The directory must be empty apart from repo bookkeeping like
.git; if a git repo already exists there, the initializer detects it and skips
git init. Prefer a new subfolder instead? Pass a name:
npm create agentic-playwright my-tests -- --demo # same, but in ./my-tests
npm create agentic-playwright . # interactive — 4 questions
npm create agentic-playwright . -- --bare # your own app URLs
Useful flags: --no-claude / --no-cursor / --no-copilot (prune AI rule trees you
don't use), --yes, --skip-install, --skip-browsers, --skip-git, --skip-smoke.
Quick Start: Dev Container
The fastest way to get a fully working environment. Requires Docker Desktop and a Dev Containers extension for your editor:
- Cursor: Install the Dev Containers extension by Dev Containers.
- VS Code: Install the Dev Containers extension by Microsoft.
Important: Make sure Docker Desktop is up and running before proceeding with the steps below. The Dev Container will fail to build if Docker is not started.
-
Clone the repository:
git clone <your-repository-url> # replace with your fork/clone URL cd playwright-scaffold -
Open in Cursor/VS Code and accept the prompt to "Reopen in Container" (or run
Dev Containers: Reopen in Containerfrom the Command Palette). -
Done. The Docker image ships with pre-warmed npm and
playwright-clibrowser caches, sopostCreateCommandcompletes in seconds even on first start. The container provides Node.js, npm dependencies (on a fast named volume), Playwright test browsers, Python 3, Claude Code CLI, andplaywright/playwright-clilinked into~/.local/bin. Editenv/.env.devwith your app configuration and runnpm test.
Version alignment: The Playwright Docker image tag in
.devcontainer/Dockerfilemust match the@playwright/testversion inpackage.json. When upgrading Playwright, update both.
Claude Code Custom Status Line
The scaffold includes a custom Claude Code status line that displays git branch, PR status, model, duration, cost, lines changed, and context window usage directly in the terminal.
To enable it, add the following to your .claude/settings.local.json (create the file if it doesn't exist):
{
"statusLine": {
"type": "command",
"command": "python3 .claude/scripts/status_line.py"
}
}
This renders a rich status bar at the bottom of the Claude Code terminal:
✦ main ● | 📁 project | 🤖 Sonnet 4.6 | ⏳ 12m05s | 💰 $1.42 | + 85 | — 12 | [████████░░░░] 42.5% (85,012/200k)
The status line script lives at .claude/scripts/status_line.py and uses a Gruvbox Dark color palette. It shows:
| Segment | Description |
|---|---|
| Git branch | Current branch with dirty indicator (●) |
| PR status | Review state emoji with clickable PR link (requires gh CLI) |
| Directory | Current workspace folder |
| Model | Active Claude model |
| Duration | Session duration |
| Cost | Cumulative API cost |
| Lines changed | Lines added/removed in the session |
| Context bar | Visual context window usage scaled to the autocompact threshold |
Note: Cost, lines changed, and context bar segments appear dynamically as you interact with Claude Code. A fresh session will only show git, directory, model, and duration.
Quick Start: Local Setup Script
For terminal-based workflows or if you prefer not to use Docker. Works on macOS and Linux (Windows users: use WSL2).
-
Clone the repository:
git clone <your-repository-url> # replace with your fork/clone URL cd playwright-scaffold -
Run the setup script:
bash scripts/setup.shThis automatically installs Node.js v22 (via nvm if needed), npm dependencies, Playwright browsers with system deps, Python 3.11+, links
playwrightandplaywright-cliinto~/.local/bin, and installs a dedicatedplaywright-cliChromium cache. If you already have Node.js v22+ installed, you can also runnpm run setup— it is equivalent. -
Ensure
~/.local/binis on your PATH (if your shell does not already include it):export PATH="$HOME/.local/bin:$PATH"This is where the scaffold links
playwrightandplaywright-cli. Add this line to your~/.zshrcor~/.bashrcto make it permanent. -
Edit
env/.env.devwith your app configuration and runnpm test.
Manual Installation
If you prefer to install dependencies manually. Steps 1-3 and 5-6 are identical on all platforms; step 4 differs.
-
Clone the repository:
git clone <your-repository-url> # replace with your fork/clone URL cd playwright-scaffold -
Install npm dependencies:
npm install -
Install Playwright test browsers:
npx playwright install --with-deps -
Link CLI commands and install
playwright-clibrowsers:macOS / Linux:
bash scripts/link-cli.sh "$(pwd -P)" npm run playwright-cli:install-browsersThen ensure
~/.local/binis on your PATH (add to~/.zshrcor~/.bashrcto make permanent):export PATH="$HOME/.local/bin:$PATH"Windows (PowerShell):
npm run playwright-cli:install-browsers -
Set up environment variables:
macOS / Linux:
cp env/.env.example env/.env.devWindows (PowerShell):
Copy-Item env\.env.example env\.env.devEdit
env/.env.devwith your application's configuration. -
Run tests:
npm test
Verify Your Installation
After any setup method, confirm all tools are available:
macOS / Linux:
playwright --version
playwright-cli --version
Windows (PowerShell):
npx playwright --version
playwright-cli --version
Expected output (exact versions vary with your installed packages):
playwright --version → Version 1.60.0
playwright-cli --version → 0.1.13
Getting Started: Adapting the Scaffold
This scaffold ships with example files that demonstrate every pattern. Here's how to replace them with your real application code, step by step.
Step 1: Configure Your Environment
Edit env/.env.dev with your application's actual URLs and credentials:
APP_URL=https://your-real-app.com
API_URL=https://your-real-api.com
APP_EMAIL=your-test-user@example.com
APP_PASSWORD=your-test-password
Step 2: Update Enums
Open enums/app/app.ts and replace the placeholder values with your app's actual messages, API endpoints, and storage state paths:
export enum Messages {
LOGIN_SUCCESS = 'Your actual success message',
LOGIN_ERROR = 'Your actual error message',
// Add more messages as needed
}
export enum ApiEndpoints {
LOGIN = '/your/actual/login/endpoint',
// Add more endpoints as needed
}
Step 3: Create Your First Page Object
Replace pages/app/app.page.ts with a page object for your application's actual login page (or whichever page you're testing first). Use the existing file as a template:
- Update the locators to match your app's actual elements
- Update the action methods to match your app's actual behavior
- Keep the same patterns: getter locators, JSDoc comments,
Promise<void>return types
Tip: If using Cursor with AI, ask it to "navigate to [your-url] and create a page object" -- the AI rules will guide it to use
playwright-cliby default to explore the page and generate accurate locators.
Step 4: Update Authentication Setup
Edit helpers/app/createStorageState.ts to match your app's actual login flow. The two functions to update:
createAppStorageState()-- Browser-based login for storage statesetUserAccessToken()-- API-based login for access tokens
Step 5: Write Your First Real Test
Replace the example tests in tests/app/functional/ with tests for your application. Follow the pattern in the example files:
import { expect, test } from '../../../fixtures/pom/test-options';
test.describe('Your Feature', () => {
test(
'should do something specific',
{ tag: '@smoke' },
async ({ appPage }) => {
await test.step('GIVEN precondition', async () => {
/* ... */
});
await test.step('WHEN action is taken', async () => {
/* ... */
});
await test.step('THEN expected result', async () => {
/* ... */
});
}
);
});
Step 6: Run and Verify
npm test
What to Keep vs. What to Replace
| Keep As-Is | Replace With Your App |
|---|---|
fixtures/pom/test-options.ts | pages/app/*.page.ts (your page objects) |
fixtures/pom/page-object-fixture.ts (extend it) | tests/app/**/*.spec.ts (your tests) |
fixtures/api/plain-function.ts | enums/app/app.ts (your messages/endpoints) |
fixtures/api/api-types.ts | test-data/static/app/*.ts (your test data) |
fixtures/helper/helper-fixture.ts (extend it) | test-data/factories/app/*.factory.ts (your factories) |
config/, helpers/util/ | helpers/app/createStorageState.ts (your auth flow) |
.claude/skills/, .cursor/skills/, .github/instructions/ (AI skills) | fixtures/api/schemas/app/ (your API schemas) |
playwright.config.ts (mostly) | pages/components/ (your UI components) |
Project Structure
root/
├── .devcontainer/ # Dev Container configuration (Docker-based setup)
│ ├── Dockerfile # Playwright + Python + pre-warmed npm/CLI caches + Claude Code
│ ├── devcontainer.json # VS Code/Cursor container settings
│ └── post-create.sh # Auto-setup script (npm ci, CLI links, env file, etc.)
│
├── .playwright/
│ └── cli.config.json # playwright-cli browser defaults (Chromium channel)
│
├── scripts/
│ ├── check-rules-drift.sh # Constitution rules <-> skill Critical-block anchors
│ ├── check-skill-references-drift.sh # SKILL.md <-> references/ pointers, orphans, anchors
│ ├── check-skill-crossrefs.sh # Skills Index sync, frontmatter, cross-skill refs
│ ├── check-version-drift.sh # VERSION <-> package.json <-> CHANGELOG consistency
│ ├── stamp-version.sh # Stamp VERSION into package.json (single-source)
│ ├── install-playwright-cli-browsers.sh
│ ├── link-cli.sh # Links playwright/playwright-cli into ~/.local/bin
│ ├── playwright-cli.sh # Wrapper that isolates PLAYWRIGHT_BROWSERS_PATH for @playwright/cli
│ └── setup.sh # Local development setup (non-Docker alternative)
│
├── VERSION # Single source of truth for the product version
├── CHANGELOG.md # Release history (newest first)
├── CLAUDE.md # AI orchestrator for Claude Code (always loaded)
├── AI-WORKFLOWS.md # Step-by-step task workflow playbook (anti-drift reference)
├── .claude/ # Claude Code configuration and AI skills
│ ├── settings.json # Shared settings (Constitution enforcement PreToolUse hook)
│ ├── settings.local.json # Local settings (status line, permissions)
│ ├── scripts/
│ │ ├── enforce_constitution.py # PreToolUse hook: blocks mechanical WON'T violations
│ │ └── status_line.py # Custom status line renderer (Gruvbox Dark theme)
│ └── skills/ # Detailed AI skills (tool-agnostic)
│ ├── api-testing/ # apiRequest fixture, schema validation, helpers
│ ├── common-tasks/ # Prompt templates, anti-patterns, verification checklist
│ ├── config/ # Configuration patterns, environment variables
│ ├── data-strategy/ # Factories (Faker + Zod) vs static TS data (`.ts` `as const`, three-tier rule)
│ ├── enums/ # Enum conventions, naming, organization
│ ├── fixtures/ # DI pattern, fixture creation, merging
│ ├── helpers/ # Helper function conventions, auth helpers
│ ├── page-objects/ # POM pattern, getter locators, components
│ ├── playwright-cli/ # Default browser exploration workflow for UI discovery
│ ├── pr-revi
Files in the repo
- .claude
- .cursor
- .devcontainer
- .github
- .husky
- .playwright
- .vscode
- assets
- config
- enums
- env
- fixtures
- helpers
- packages
- pages
- scripts
- test-data
- tests
- .dockerignore
- .gitattributes
- .gitignore
- .nvmrc
- .prettierignore
- .prettierrc
- AI-WORKFLOWS.md
- CHANGELOG.md
- CLAUDE.md
- CODE_OF_CONDUCT.md
- CONTRIBUTING.md
- eslint.config.mts
- LICENSE
- NOTICE.md
- package-lock.json
- package.json
- playwright.config.ts
- README.md
- SECURITY.md
- skills-lock.json
- tsconfig.json
- VERSION
Discussion (0)
Ask about usage, or say what you built with itSign in to join the discussion.
No comments yet. Be the first to say what this is good for.
More templates
Turn Claude Code into a full game dev studio — 49 AI agents, 72 workflow skills, and a complete coordination system mirroring real studio hierarchy.
A self-organizing Obsidian vault that gives AI coding agents persistent memory. Claude Code, Codex CLI, Gemini CLI.
Omnia Vault - the all-in-one project brain: an Obsidian LLM wiki, Graphify code graphs, a living plan that triages new videos against itself, and a Claude Code ⇄ Codex relay. Everything your project knows, in one clonable vault.

🎬 Tạo video "so sánh kiến thức" ngắn tự động — HyperFrames + AI voice, 1 template nhiều chủ đề.
Robinhood Agentic Trading agent — a fully automated AI trading bot placing real orders through Robinhood's Agentic Trading MCP, under mechanical, auditable risk rules the model cannot override. Able to run unattended on Claude Pro, no metered API spend. Not financial advice.