Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Automate browser interactions for web testing, form filling, screenshots, and data extraction using the playwright-cli tool.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/test-generation.md
1# Test Generation23Generate Playwright test code automatically as you interact with the browser.45## How It Works67Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code.8This code appears in the output and can be copied directly into your test files.910## Example Workflow1112```bash13# Start a session14playwright-cli open https://example.com/login1516# Take a snapshot to see elements17playwright-cli snapshot18# Output shows: e1 [textbox "Email"], e2 [textbox "Password"], e3 [button "Sign In"]1920# Fill form fields - generates code automatically21playwright-cli fill e1 "[email protected]"22# Ran Playwright code:23# await page.getByRole('textbox', { name: 'Email' }).fill('[email protected]');2425playwright-cli fill e2 "password123"26# Ran Playwright code:27# await page.getByRole('textbox', { name: 'Password' }).fill('password123');2829playwright-cli click e330# Ran Playwright code:31# await page.getByRole('button', { name: 'Sign In' }).click();32```3334## Building a Test File3536Collect the generated code into a Playwright test:3738```typescript39import { test, expect } from '@playwright/test';4041test('login flow', async ({ page }) => {42// Generated code from playwright-cli session:43await page.goto('https://example.com/login');44await page.getByRole('textbox', { name: 'Email' }).fill('[email protected]');45await page.getByRole('textbox', { name: 'Password' }).fill('password123');46await page.getByRole('button', { name: 'Sign In' }).click();4748// Add assertions49await expect(page).toHaveURL(/.*dashboard/);50});51```5253## Best Practices5455### 1. Use Semantic Locators5657The generated code uses role-based locators when possible, which are more resilient:5859```typescript60// Generated (good - semantic)61await page.getByRole('button', { name: 'Submit' }).click();6263// Avoid (fragile - CSS selectors)64await page.locator('#submit-btn').click();65```6667### 2. Explore Before Recording6869Take snapshots to understand the page structure before recording actions:7071```bash72playwright-cli open https://example.com73playwright-cli snapshot74# Review the element structure75playwright-cli click e576```7778### 3. Add Assertions Manually7980Generated code captures actions but not assertions. Add expectations in your test using one of the recommended matchers:8182- `toBeVisible()` — element is rendered and visible83- `toHaveText(text)` — element text content matches84- `toHaveValue(value) / toBeEmpty()` — input/select value matches85- `toBeChecked() / toBeUnchecked()` — checkbox state matches86- `toMatchAriaSnapshot(snapshot)` — page (or locator) matches a partial accessibility snapshot8788Use `playwright-cli generate-locator <target>` to produce the locator expression for the assertion, and the snapshot/eval commands to capture the expected value.8990When asserting text content, make sure that generated locator does not contain text from the element itself. `getByTestId()` or `getByLabel()` usually work well with asserting text. When locator is text-based, prefer `toBeVisible()` instead.9192Snapshot to be matched does not have to contain all the information - only capture what's necessary for the assertion. You can use regular expressions for unstable values.9394```bash95# Get a stable locator for an element ref to use in the assertion96playwright-cli --raw generate-locator e597# getByRole('button', { name: 'Submit' })9899# Capture expected text content for toHaveText100playwright-cli --raw eval "el => el.textContent" e5101102# Capture expected input value for toHaveValue/toBeEmpty103playwright-cli --raw eval "el => el.value" e5104105# Capture expected aria snapshot for toMatchAriaSnapshot/toBeChecked106# (whole page, or use a ref to scope to a region)107playwright-cli --raw snapshot108playwright-cli --raw snapshot e5109```110111```typescript112// Generated action113await page.getByRole('button', { name: 'Submit' }).click();114115// Manual assertions using the outputs above:116await expect(page.getByRole('alert', { name: 'Success' })).toBeVisible();117await expect(page.getByTestId('main-header')).toHaveText('Welcome, user');118await expect(page.getByRole('textbox', { name: 'Email' })).toHaveValue('[email protected]');119await expect(page.getByRole('checkbox', { name: 'Enable notifications' })).toBeChecked();120121// toMatchAriaSnapshot on the whole page, finds a matching region122await expect(page).toMatchAriaSnapshot(`123- heading "Welcome, user"124- link /\\d+ new messages?/125- button "Sign out"126`);127128// toMatchAriaSnapshot scoped to a region129await expect(page.getByRole('navigation')).toMatchAriaSnapshot(`130- link "Home"131- link /\\d+ new messages?/132- link "Profile"133`);134```135