LearnCen Docs
Guides 5 min read v4

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

  1. 🎭 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 your specs/ folder.
  2. 🎭 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.ts files inside your tests/ folder with fully implemented assertions and reliable DOM locators.
  3. 🎭 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.ts files 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:

  1. 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."
  2. 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 test and 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").