Playwright Fundamentals
Welcome to the comprehensive Playwright crash course! This guide covers everything from basic E2E testing to advanced element interactions, configuration, and executing Playwright's native AI agents.
1. What is Playwright?
Playwright is an open-source automation library built by Microsoft. It allows you to write code that controls web browsers (Chromium, Firefox, and WebKit) to simulate user interactions and test your web applications. It features auto-waiting, cross-browser support, and excellent debugging tools.
2. Installation and Setup
To add Playwright to a project, run the following command in your terminal:
npm init playwright@latest
3. Anatomy of a Playwright Test
Playwright tests use test to define a test case and expect to make assertions.
import { test, expect } from '@playwright/test';
test('basic navigation and title check', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});
4. Locators: Finding Elements
Locators are how you tell Playwright which element to interact with. Playwright recommends using user-facing locators.
test('using locators', async ({ page }) => {
await page.goto('https://example.com/login');
// getByRole (Recommended)
await page.getByRole('button', { name: 'Submit' }).click();
// getByPlaceholder
await page.getByPlaceholder('Enter your email').fill('user@test.com');
});
5. Advanced Interactions: Tables, Uploads, and Drag & Drop
Web pages often have complex elements. Here is how to handle them.
Identifying Elements in Tables
When dealing with tables, you often need to find a specific row based on text, and then click a button inside that specific row.
test('interacting with data tables', async ({ page }) => {
await page.goto('https://example.com/users');
// Find the row that contains the text "John Doe"
const row = page.getByRole('row', { name: 'John Doe' });
// Within that specific row, find and click the "Edit" button
await row.getByRole('button', { name: 'Edit' }).click();
});
File Uploads and Drag & Drop
test('advanced mouse and file interactions', async ({ page }) => {
await page.goto('https://example.com/tools');
// File Upload
await page.getByLabel('Upload resume').setInputFiles('path/to/resume.pdf');
// Drag and Drop
await page.locator('#draggable-item').dragTo(page.locator('#drop-zone'));
});
6. Working with Multiple Tabs and Iframes
Handling New Tabs (Pages)
To handle a new tab, you need to wait for the browser context to emit a new page event at the exact same time you trigger the click.
test('handling new browser tabs', async ({ context, page }) => {
await page.goto('https://example.com');
const [newPage] = await Promise.all([
context.waitForEvent('page'),
page.getByRole('link', { name: 'Open in new tab' }).click()
]);
await newPage.waitForLoadState();
await expect(newPage).toHaveTitle('New Tab Title');
});
Interacting with Iframes
Playwright cannot directly select elements inside an iframe. You must use a frameLocator first.
test('handling iframes', async ({ page }) => {
await page.goto('https://example.com/checkout');
const paymentFrame = page.frameLocator('#stripe-payment-frame');
await paymentFrame.getByPlaceholder('Card Number').fill('4242 4242 4242');
});
7. Configuration: playwright.config.ts
This is the control center for your test suite.
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
retries: 1,
workers: 4,
use: {
baseURL: 'https://staging.example.com',
trace: 'on-first-retry',
video: 'retain-on-failure',
headless: true,
},
});
8. The Playwright Test Runner (CLI)
The CLI offers powerful ways to execute your suite.
- Run a specific test file:
npx playwright test example.spec.ts - Run tests in headed mode:
npx playwright test --headed - Run tests with UI Mode (Recommended for debugging):
npx playwright test --ui - View the HTML test report:
npx playwright show-report
9. Playwright Native AI Agents
Playwright recently introduced native Playwright Test Agents that bring autonomous AI capabilities directly into the testing lifecycle using the Model Context Protocol (MCP).
The Three Agents in the Agentic Loop
-
🎭 Planner Agent (Test Planning)
- Goal: Understands what you want to test, explores the application dynamically, and translates your intent into a concrete test plan.
- Output: Generates a highly structured, human-readable Markdown (
.md) test plan saved directly in yourspecs/folder.
-
🎭 Generator Agent (Test Scripting)
- Goal: Converts the human-readable Markdown test plan created by the Planner into executable Playwright code.
- Output: Generates ready-to-run
.spec.tsfiles inside yourtests/folder with fully implemented assertions and reliable DOM locators.
-
🎭 Healer Agent (Self-Healing Maintenance)
- Goal: Operates during test execution to dynamically fix broken tests caused by UI changes (e.g., renamed buttons, new DOM structures).
- Output: Automatically updates selectors in your
.spec.tsfiles and re-runs the test to verify the fix.
How to Execute AI Agents on Playwright
Option 1: Executing via IDE Copilot (Interactive Mode) If you are using an AI coding assistant (like GitHub Copilot) with MCP support:
- Open your AI chat and call
@playwright-test-planner.- Prompt: "Generate a comprehensive test plan for the guest checkout flow. Starting URL is
http://localhost:3000/cart."
- Prompt: "Generate a comprehensive test plan for the guest checkout flow. Starting URL is
- Once the
specs/file is created, call@playwright-test-generator.- Prompt: "Generate Playwright tests for the scenarios outlined in the new spec file."
Option 2: Executing via CLI (Automated Loop) You can instruct terminal-aware AI agents (like Claude Code) to handle the lifecycle:
- Prompt: "Run the Playwright Planner on the local staging environment to map out the checkout flow. Save the plan, use the Generator to write the tests. Finally, run
npx playwright testand act as the Healer to fix any broken tests."
Best Practices for the Planner Agent
When executing the Planner, bounding its scope is critical. Provide a strict "charter" in your prompt:
- Target: Specific URL or feature area.
- Starting State: Logged in vs. Guest.
- In Scope: What paths it is allowed to explore.
- Out of Scope: Destructive actions to avoid (e.g., "Do NOT delete any accounts").