@playwright/cli
Advanced tools
| # Inspecting Element Attributes | ||
| When the snapshot doesn't show an element's `id`, `class`, `data-*` attributes, or other DOM properties, use `eval` to inspect them. | ||
| ## Examples | ||
| ```bash | ||
| playwright-cli snapshot | ||
| # snapshot shows a button as e7 but doesn't reveal its id or data attributes | ||
| # get the element's id | ||
| playwright-cli eval "el => el.id" e7 | ||
| # get all CSS classes | ||
| playwright-cli eval "el => el.className" e7 | ||
| # get a specific attribute | ||
| playwright-cli eval "el => el.getAttribute('data-testid')" e7 | ||
| playwright-cli eval "el => el.getAttribute('aria-label')" e7 | ||
| # get a computed style property | ||
| playwright-cli eval "el => getComputedStyle(el).display" e7 | ||
| ``` |
| # Running Playwright Tests | ||
| To run Playwright tests, use the `npx playwright test` command, or a package manager script. To avoid opening the interactive html report, use `PLAYWRIGHT_HTML_OPEN=never` environment variable. | ||
| ```bash | ||
| # Run all tests | ||
| PLAYWRIGHT_HTML_OPEN=never npx playwright test | ||
| # Run all tests through a custom npm script | ||
| PLAYWRIGHT_HTML_OPEN=never npm run special-test-command | ||
| ``` | ||
| # Debugging Playwright Tests | ||
| To debug a failing Playwright test, run it with `--debug=cli` option. This command will pause the test at the start and print the debugging instructions. | ||
| **IMPORTANT**: run the command in the background and check the output until "Debugging Instructions" is printed. | ||
| Once instructions containing a session name are printed, use `playwright-cli` to attach the session and explore the page. | ||
| ```bash | ||
| # Run the test | ||
| PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli | ||
| # ... | ||
| # ... debugging instructions for "tw-abcdef" session ... | ||
| # ... | ||
| # Attach to the test | ||
| playwright-cli attach tw-abcdef | ||
| ``` | ||
| Keep the test running in the background while you explore and look for a fix. | ||
| The test is paused at the start, so you should step over or pause at a particular location | ||
| where the problem is most likely to be. | ||
| Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code. | ||
| This code appears in the output and can be copied directly into the test. Most of the time, a specific locator or an expectation should be updated, but it could also be a bug in the app. Use your judgement. | ||
| After fixing the test, stop the background test run. Rerun to check that test passes. |
| # Request Mocking | ||
| Intercept, mock, modify, and block network requests. | ||
| ## CLI Route Commands | ||
| ```bash | ||
| # Mock with custom status | ||
| playwright-cli route "**/*.jpg" --status=404 | ||
| # Mock with JSON body | ||
| playwright-cli route "**/api/users" --body='[{"id":1,"name":"Alice"}]' --content-type=application/json | ||
| # Mock with custom headers | ||
| playwright-cli route "**/api/data" --body='{"ok":true}' --header="X-Custom: value" | ||
| # Remove headers from requests | ||
| playwright-cli route "**/*" --remove-header=cookie,authorization | ||
| # List active routes | ||
| playwright-cli route-list | ||
| # Remove a route or all routes | ||
| playwright-cli unroute "**/*.jpg" | ||
| playwright-cli unroute | ||
| ``` | ||
| ## URL Patterns | ||
| ``` | ||
| **/api/users - Exact path match | ||
| **/api/*/details - Wildcard in path | ||
| **/*.{png,jpg,jpeg} - Match file extensions | ||
| **/search?q=* - Match query parameters | ||
| ``` | ||
| ## Advanced Mocking with run-code | ||
| For conditional responses, request body inspection, response modification, or delays: | ||
| ### Conditional Response Based on Request | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.route('**/api/login', route => { | ||
| const body = route.request().postDataJSON(); | ||
| if (body.username === 'admin') { | ||
| route.fulfill({ body: JSON.stringify({ token: 'mock-token' }) }); | ||
| } else { | ||
| route.fulfill({ status: 401, body: JSON.stringify({ error: 'Invalid' }) }); | ||
| } | ||
| }); | ||
| }" | ||
| ``` | ||
| ### Modify Real Response | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.route('**/api/user', async route => { | ||
| const response = await route.fetch(); | ||
| const json = await response.json(); | ||
| json.isPremium = true; | ||
| await route.fulfill({ response, json }); | ||
| }); | ||
| }" | ||
| ``` | ||
| ### Simulate Network Failures | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.route('**/api/offline', route => route.abort('internetdisconnected')); | ||
| }" | ||
| # Options: connectionrefused, timedout, connectionreset, internetdisconnected | ||
| ``` | ||
| ### Delayed Response | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.route('**/api/slow', async route => { | ||
| await new Promise(r => setTimeout(r, 3000)); | ||
| route.fulfill({ body: JSON.stringify({ data: 'loaded' }) }); | ||
| }); | ||
| }" | ||
| ``` |
| # Running Custom Playwright Code | ||
| Use `run-code` to execute arbitrary Playwright code for advanced scenarios not covered by CLI commands. | ||
| ## Syntax | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| // Your Playwright code here | ||
| // Access page.context() for browser context operations | ||
| }" | ||
| ``` | ||
| ## Geolocation | ||
| ```bash | ||
| # Grant geolocation permission and set location | ||
| playwright-cli run-code "async page => { | ||
| await page.context().grantPermissions(['geolocation']); | ||
| await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 }); | ||
| }" | ||
| # Set location to London | ||
| playwright-cli run-code "async page => { | ||
| await page.context().grantPermissions(['geolocation']); | ||
| await page.context().setGeolocation({ latitude: 51.5074, longitude: -0.1278 }); | ||
| }" | ||
| # Clear geolocation override | ||
| playwright-cli run-code "async page => { | ||
| await page.context().clearPermissions(); | ||
| }" | ||
| ``` | ||
| ## Permissions | ||
| ```bash | ||
| # Grant multiple permissions | ||
| playwright-cli run-code "async page => { | ||
| await page.context().grantPermissions([ | ||
| 'geolocation', | ||
| 'notifications', | ||
| 'camera', | ||
| 'microphone' | ||
| ]); | ||
| }" | ||
| # Grant permissions for specific origin | ||
| playwright-cli run-code "async page => { | ||
| await page.context().grantPermissions(['clipboard-read'], { | ||
| origin: 'https://example.com' | ||
| }); | ||
| }" | ||
| ``` | ||
| ## Media Emulation | ||
| ```bash | ||
| # Emulate dark color scheme | ||
| playwright-cli run-code "async page => { | ||
| await page.emulateMedia({ colorScheme: 'dark' }); | ||
| }" | ||
| # Emulate light color scheme | ||
| playwright-cli run-code "async page => { | ||
| await page.emulateMedia({ colorScheme: 'light' }); | ||
| }" | ||
| # Emulate reduced motion | ||
| playwright-cli run-code "async page => { | ||
| await page.emulateMedia({ reducedMotion: 'reduce' }); | ||
| }" | ||
| # Emulate print media | ||
| playwright-cli run-code "async page => { | ||
| await page.emulateMedia({ media: 'print' }); | ||
| }" | ||
| ``` | ||
| ## Wait Strategies | ||
| ```bash | ||
| # Wait for network idle | ||
| playwright-cli run-code "async page => { | ||
| await page.waitForLoadState('networkidle'); | ||
| }" | ||
| # Wait for specific element | ||
| playwright-cli run-code "async page => { | ||
| await page.locator('.loading').waitFor({ state: 'hidden' }); | ||
| }" | ||
| # Wait for function to return true | ||
| playwright-cli run-code "async page => { | ||
| await page.waitForFunction(() => window.appReady === true); | ||
| }" | ||
| # Wait with timeout | ||
| playwright-cli run-code "async page => { | ||
| await page.locator('.result').waitFor({ timeout: 10000 }); | ||
| }" | ||
| ``` | ||
| ## Frames and Iframes | ||
| ```bash | ||
| # Work with iframe | ||
| playwright-cli run-code "async page => { | ||
| const frame = page.locator('iframe#my-iframe').contentFrame(); | ||
| await frame.locator('button').click(); | ||
| }" | ||
| # Get all frames | ||
| playwright-cli run-code "async page => { | ||
| const frames = page.frames(); | ||
| return frames.map(f => f.url()); | ||
| }" | ||
| ``` | ||
| ## File Downloads | ||
| ```bash | ||
| # Handle file download | ||
| playwright-cli run-code "async page => { | ||
| const downloadPromise = page.waitForEvent('download'); | ||
| await page.getByRole('link', { name: 'Download' }).click(); | ||
| const download = await downloadPromise; | ||
| await download.saveAs('./downloaded-file.pdf'); | ||
| return download.suggestedFilename(); | ||
| }" | ||
| ``` | ||
| ## Clipboard | ||
| ```bash | ||
| # Read clipboard (requires permission) | ||
| playwright-cli run-code "async page => { | ||
| await page.context().grantPermissions(['clipboard-read']); | ||
| return await page.evaluate(() => navigator.clipboard.readText()); | ||
| }" | ||
| # Write to clipboard | ||
| playwright-cli run-code "async page => { | ||
| await page.evaluate(text => navigator.clipboard.writeText(text), 'Hello clipboard!'); | ||
| }" | ||
| ``` | ||
| ## Page Information | ||
| ```bash | ||
| # Get page title | ||
| playwright-cli run-code "async page => { | ||
| return await page.title(); | ||
| }" | ||
| # Get current URL | ||
| playwright-cli run-code "async page => { | ||
| return page.url(); | ||
| }" | ||
| # Get page content | ||
| playwright-cli run-code "async page => { | ||
| return await page.content(); | ||
| }" | ||
| # Get viewport size | ||
| playwright-cli run-code "async page => { | ||
| return page.viewportSize(); | ||
| }" | ||
| ``` | ||
| ## JavaScript Execution | ||
| ```bash | ||
| # Execute JavaScript and return result | ||
| playwright-cli run-code "async page => { | ||
| return await page.evaluate(() => { | ||
| return { | ||
| userAgent: navigator.userAgent, | ||
| language: navigator.language, | ||
| cookiesEnabled: navigator.cookieEnabled | ||
| }; | ||
| }); | ||
| }" | ||
| # Pass arguments to evaluate | ||
| playwright-cli run-code "async page => { | ||
| const multiplier = 5; | ||
| return await page.evaluate(m => document.querySelectorAll('li').length * m, multiplier); | ||
| }" | ||
| ``` | ||
| ## Error Handling | ||
| ```bash | ||
| # Try-catch in run-code | ||
| playwright-cli run-code "async page => { | ||
| try { | ||
| await page.getByRole('button', { name: 'Submit' }).click({ timeout: 1000 }); | ||
| return 'clicked'; | ||
| } catch (e) { | ||
| return 'element not found'; | ||
| } | ||
| }" | ||
| ``` | ||
| ## Complex Workflows | ||
| ```bash | ||
| # Login and save state | ||
| playwright-cli run-code "async page => { | ||
| await page.goto('https://example.com/login'); | ||
| await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com'); | ||
| await page.getByRole('textbox', { name: 'Password' }).fill('secret'); | ||
| await page.getByRole('button', { name: 'Sign in' }).click(); | ||
| await page.waitForURL('**/dashboard'); | ||
| await page.context().storageState({ path: 'auth.json' }); | ||
| return 'Login successful'; | ||
| }" | ||
| # Scrape data from multiple pages | ||
| playwright-cli run-code "async page => { | ||
| const results = []; | ||
| for (let i = 1; i <= 3; i++) { | ||
| await page.goto(\`https://example.com/page/\${i}\`); | ||
| const items = await page.locator('.item').allTextContents(); | ||
| results.push(...items); | ||
| } | ||
| return results; | ||
| }" | ||
| ``` |
| # Browser Session Management | ||
| Run multiple isolated browser sessions concurrently with state persistence. | ||
| ## Named Browser Sessions | ||
| Use `-s` flag to isolate browser contexts: | ||
| ```bash | ||
| # Browser 1: Authentication flow | ||
| playwright-cli -s=auth open https://app.example.com/login | ||
| # Browser 2: Public browsing (separate cookies, storage) | ||
| playwright-cli -s=public open https://example.com | ||
| # Commands are isolated by browser session | ||
| playwright-cli -s=auth fill e1 "user@example.com" | ||
| playwright-cli -s=public snapshot | ||
| ``` | ||
| ## Browser Session Isolation Properties | ||
| Each browser session has independent: | ||
| - Cookies | ||
| - LocalStorage / SessionStorage | ||
| - IndexedDB | ||
| - Cache | ||
| - Browsing history | ||
| - Open tabs | ||
| ## Browser Session Commands | ||
| ```bash | ||
| # List all browser sessions | ||
| playwright-cli list | ||
| # Stop a browser session (close the browser) | ||
| playwright-cli close # stop the default browser | ||
| playwright-cli -s=mysession close # stop a named browser | ||
| # Stop all browser sessions | ||
| playwright-cli close-all | ||
| # Forcefully kill all daemon processes (for stale/zombie processes) | ||
| playwright-cli kill-all | ||
| # Delete browser session user data (profile directory) | ||
| playwright-cli delete-data # delete default browser data | ||
| playwright-cli -s=mysession delete-data # delete named browser data | ||
| ``` | ||
| ## Environment Variable | ||
| Set a default browser session name via environment variable: | ||
| ```bash | ||
| export PLAYWRIGHT_CLI_SESSION="mysession" | ||
| playwright-cli open example.com # Uses "mysession" automatically | ||
| ``` | ||
| ## Common Patterns | ||
| ### Concurrent Scraping | ||
| ```bash | ||
| #!/bin/bash | ||
| # Scrape multiple sites concurrently | ||
| # Start all browsers | ||
| playwright-cli -s=site1 open https://site1.com & | ||
| playwright-cli -s=site2 open https://site2.com & | ||
| playwright-cli -s=site3 open https://site3.com & | ||
| wait | ||
| # Take snapshots from each | ||
| playwright-cli -s=site1 snapshot | ||
| playwright-cli -s=site2 snapshot | ||
| playwright-cli -s=site3 snapshot | ||
| # Cleanup | ||
| playwright-cli close-all | ||
| ``` | ||
| ### A/B Testing Sessions | ||
| ```bash | ||
| # Test different user experiences | ||
| playwright-cli -s=variant-a open "https://app.com?variant=a" | ||
| playwright-cli -s=variant-b open "https://app.com?variant=b" | ||
| # Compare | ||
| playwright-cli -s=variant-a screenshot | ||
| playwright-cli -s=variant-b screenshot | ||
| ``` | ||
| ### Persistent Profile | ||
| By default, browser profile is kept in memory only. Use `--persistent` flag on `open` to persist the browser profile to disk: | ||
| ```bash | ||
| # Use persistent profile (auto-generated location) | ||
| playwright-cli open https://example.com --persistent | ||
| # Use persistent profile with custom directory | ||
| playwright-cli open https://example.com --profile=/path/to/profile | ||
| ``` | ||
| ## Default Browser Session | ||
| When `-s` is omitted, commands use the default browser session: | ||
| ```bash | ||
| # These use the same default browser session | ||
| playwright-cli open https://example.com | ||
| playwright-cli snapshot | ||
| playwright-cli close # Stops default browser | ||
| ``` | ||
| ## Browser Session Configuration | ||
| Configure a browser session with specific settings when opening: | ||
| ```bash | ||
| # Open with config file | ||
| playwright-cli open https://example.com --config=.playwright/my-cli.json | ||
| # Open with specific browser | ||
| playwright-cli open https://example.com --browser=firefox | ||
| # Open in headed mode | ||
| playwright-cli open https://example.com --headed | ||
| # Open with persistent profile | ||
| playwright-cli open https://example.com --persistent | ||
| ``` | ||
| ## Best Practices | ||
| ### 1. Name Browser Sessions Semantically | ||
| ```bash | ||
| # GOOD: Clear purpose | ||
| playwright-cli -s=github-auth open https://github.com | ||
| playwright-cli -s=docs-scrape open https://docs.example.com | ||
| # AVOID: Generic names | ||
| playwright-cli -s=s1 open https://github.com | ||
| ``` | ||
| ### 2. Always Clean Up | ||
| ```bash | ||
| # Stop browsers when done | ||
| playwright-cli -s=auth close | ||
| playwright-cli -s=scrape close | ||
| # Or stop all at once | ||
| playwright-cli close-all | ||
| # If browsers become unresponsive or zombie processes remain | ||
| playwright-cli kill-all | ||
| ``` | ||
| ### 3. Delete Stale Browser Data | ||
| ```bash | ||
| # Remove old browser data to free disk space | ||
| playwright-cli -s=oldsession delete-data | ||
| ``` |
| # Storage Management | ||
| Manage cookies, localStorage, sessionStorage, and browser storage state. | ||
| ## Storage State | ||
| Save and restore complete browser state including cookies and storage. | ||
| ### Save Storage State | ||
| ```bash | ||
| # Save to auto-generated filename (storage-state-{timestamp}.json) | ||
| playwright-cli state-save | ||
| # Save to specific filename | ||
| playwright-cli state-save my-auth-state.json | ||
| ``` | ||
| ### Restore Storage State | ||
| ```bash | ||
| # Load storage state from file | ||
| playwright-cli state-load my-auth-state.json | ||
| # Reload page to apply cookies | ||
| playwright-cli open https://example.com | ||
| ``` | ||
| ### Storage State File Format | ||
| The saved file contains: | ||
| ```json | ||
| { | ||
| "cookies": [ | ||
| { | ||
| "name": "session_id", | ||
| "value": "abc123", | ||
| "domain": "example.com", | ||
| "path": "/", | ||
| "expires": 1735689600, | ||
| "httpOnly": true, | ||
| "secure": true, | ||
| "sameSite": "Lax" | ||
| } | ||
| ], | ||
| "origins": [ | ||
| { | ||
| "origin": "https://example.com", | ||
| "localStorage": [ | ||
| { "name": "theme", "value": "dark" }, | ||
| { "name": "user_id", "value": "12345" } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
| ## Cookies | ||
| ### List All Cookies | ||
| ```bash | ||
| playwright-cli cookie-list | ||
| ``` | ||
| ### Filter Cookies by Domain | ||
| ```bash | ||
| playwright-cli cookie-list --domain=example.com | ||
| ``` | ||
| ### Filter Cookies by Path | ||
| ```bash | ||
| playwright-cli cookie-list --path=/api | ||
| ``` | ||
| ### Get Specific Cookie | ||
| ```bash | ||
| playwright-cli cookie-get session_id | ||
| ``` | ||
| ### Set a Cookie | ||
| ```bash | ||
| # Basic cookie | ||
| playwright-cli cookie-set session abc123 | ||
| # Cookie with options | ||
| playwright-cli cookie-set session abc123 --domain=example.com --path=/ --httpOnly --secure --sameSite=Lax | ||
| # Cookie with expiration (Unix timestamp) | ||
| playwright-cli cookie-set remember_me token123 --expires=1735689600 | ||
| ``` | ||
| ### Delete a Cookie | ||
| ```bash | ||
| playwright-cli cookie-delete session_id | ||
| ``` | ||
| ### Clear All Cookies | ||
| ```bash | ||
| playwright-cli cookie-clear | ||
| ``` | ||
| ### Advanced: Multiple Cookies or Custom Options | ||
| For complex scenarios like adding multiple cookies at once, use `run-code`: | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.context().addCookies([ | ||
| { name: 'session_id', value: 'sess_abc123', domain: 'example.com', path: '/', httpOnly: true }, | ||
| { name: 'preferences', value: JSON.stringify({ theme: 'dark' }), domain: 'example.com', path: '/' } | ||
| ]); | ||
| }" | ||
| ``` | ||
| ## Local Storage | ||
| ### List All localStorage Items | ||
| ```bash | ||
| playwright-cli localstorage-list | ||
| ``` | ||
| ### Get Single Value | ||
| ```bash | ||
| playwright-cli localstorage-get token | ||
| ``` | ||
| ### Set Value | ||
| ```bash | ||
| playwright-cli localstorage-set theme dark | ||
| ``` | ||
| ### Set JSON Value | ||
| ```bash | ||
| playwright-cli localstorage-set user_settings '{"theme":"dark","language":"en"}' | ||
| ``` | ||
| ### Delete Single Item | ||
| ```bash | ||
| playwright-cli localstorage-delete token | ||
| ``` | ||
| ### Clear All localStorage | ||
| ```bash | ||
| playwright-cli localstorage-clear | ||
| ``` | ||
| ### Advanced: Multiple Operations | ||
| For complex scenarios like setting multiple values at once, use `run-code`: | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.evaluate(() => { | ||
| localStorage.setItem('token', 'jwt_abc123'); | ||
| localStorage.setItem('user_id', '12345'); | ||
| localStorage.setItem('expires_at', Date.now() + 3600000); | ||
| }); | ||
| }" | ||
| ``` | ||
| ## Session Storage | ||
| ### List All sessionStorage Items | ||
| ```bash | ||
| playwright-cli sessionstorage-list | ||
| ``` | ||
| ### Get Single Value | ||
| ```bash | ||
| playwright-cli sessionstorage-get form_data | ||
| ``` | ||
| ### Set Value | ||
| ```bash | ||
| playwright-cli sessionstorage-set step 3 | ||
| ``` | ||
| ### Delete Single Item | ||
| ```bash | ||
| playwright-cli sessionstorage-delete step | ||
| ``` | ||
| ### Clear sessionStorage | ||
| ```bash | ||
| playwright-cli sessionstorage-clear | ||
| ``` | ||
| ## IndexedDB | ||
| ### List Databases | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| return await page.evaluate(async () => { | ||
| const databases = await indexedDB.databases(); | ||
| return databases; | ||
| }); | ||
| }" | ||
| ``` | ||
| ### Delete Database | ||
| ```bash | ||
| playwright-cli run-code "async page => { | ||
| await page.evaluate(() => { | ||
| indexedDB.deleteDatabase('myDatabase'); | ||
| }); | ||
| }" | ||
| ``` | ||
| ## Common Patterns | ||
| ### Authentication State Reuse | ||
| ```bash | ||
| # Step 1: Login and save state | ||
| playwright-cli open https://app.example.com/login | ||
| playwright-cli snapshot | ||
| playwright-cli fill e1 "user@example.com" | ||
| playwright-cli fill e2 "password123" | ||
| playwright-cli click e3 | ||
| # Save the authenticated state | ||
| playwright-cli state-save auth.json | ||
| # Step 2: Later, restore state and skip login | ||
| playwright-cli state-load auth.json | ||
| playwright-cli open https://app.example.com/dashboard | ||
| # Already logged in! | ||
| ``` | ||
| ### Save and Restore Roundtrip | ||
| ```bash | ||
| # Set up authentication state | ||
| playwright-cli open https://example.com | ||
| playwright-cli eval "() => { document.cookie = 'session=abc123'; localStorage.setItem('user', 'john'); }" | ||
| # Save state to file | ||
| playwright-cli state-save my-session.json | ||
| # ... later, in a new session ... | ||
| # Restore state | ||
| playwright-cli state-load my-session.json | ||
| playwright-cli open https://example.com | ||
| # Cookies and localStorage are restored! | ||
| ``` | ||
| ## Security Notes | ||
| - Never commit storage state files containing auth tokens | ||
| - Add `*.auth-state.json` to `.gitignore` | ||
| - Delete state files after automation completes | ||
| - Use environment variables for sensitive data | ||
| - By default, sessions run in-memory mode which is safer for sensitive operations |
| # Test Generation | ||
| Generate Playwright test code automatically as you interact with the browser. | ||
| ## How It Works | ||
| Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code. | ||
| This code appears in the output and can be copied directly into your test files. | ||
| ## Example Workflow | ||
| ```bash | ||
| # Start a session | ||
| playwright-cli open https://example.com/login | ||
| # Take a snapshot to see elements | ||
| playwright-cli snapshot | ||
| # Output shows: e1 [textbox "Email"], e2 [textbox "Password"], e3 [button "Sign In"] | ||
| # Fill form fields - generates code automatically | ||
| playwright-cli fill e1 "user@example.com" | ||
| # Ran Playwright code: | ||
| # await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com'); | ||
| playwright-cli fill e2 "password123" | ||
| # Ran Playwright code: | ||
| # await page.getByRole('textbox', { name: 'Password' }).fill('password123'); | ||
| playwright-cli click e3 | ||
| # Ran Playwright code: | ||
| # await page.getByRole('button', { name: 'Sign In' }).click(); | ||
| ``` | ||
| ## Building a Test File | ||
| Collect the generated code into a Playwright test: | ||
| ```typescript | ||
| import { test, expect } from '@playwright/test'; | ||
| test('login flow', async ({ page }) => { | ||
| // Generated code from playwright-cli session: | ||
| await page.goto('https://example.com/login'); | ||
| await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com'); | ||
| await page.getByRole('textbox', { name: 'Password' }).fill('password123'); | ||
| await page.getByRole('button', { name: 'Sign In' }).click(); | ||
| // Add assertions | ||
| await expect(page).toHaveURL(/.*dashboard/); | ||
| }); | ||
| ``` | ||
| ## Best Practices | ||
| ### 1. Use Semantic Locators | ||
| The generated code uses role-based locators when possible, which are more resilient: | ||
| ```typescript | ||
| // Generated (good - semantic) | ||
| await page.getByRole('button', { name: 'Submit' }).click(); | ||
| // Avoid (fragile - CSS selectors) | ||
| await page.locator('#submit-btn').click(); | ||
| ``` | ||
| ### 2. Explore Before Recording | ||
| Take snapshots to understand the page structure before recording actions: | ||
| ```bash | ||
| playwright-cli open https://example.com | ||
| playwright-cli snapshot | ||
| # Review the element structure | ||
| playwright-cli click e5 | ||
| ``` | ||
| ### 3. Add Assertions Manually | ||
| Generated code captures actions but not assertions. Add expectations in your test: | ||
| ```typescript | ||
| // Generated action | ||
| await page.getByRole('button', { name: 'Submit' }).click(); | ||
| // Manual assertion | ||
| await expect(page.getByText('Success')).toBeVisible(); | ||
| ``` |
| # Tracing | ||
| Capture detailed execution traces for debugging and analysis. Traces include DOM snapshots, screenshots, network activity, and console logs. | ||
| ## Basic Usage | ||
| ```bash | ||
| # Start trace recording | ||
| playwright-cli tracing-start | ||
| # Perform actions | ||
| playwright-cli open https://example.com | ||
| playwright-cli click e1 | ||
| playwright-cli fill e2 "test" | ||
| # Stop trace recording | ||
| playwright-cli tracing-stop | ||
| ``` | ||
| ## Trace Output Files | ||
| When you start tracing, Playwright creates a `traces/` directory with several files: | ||
| ### `trace-{timestamp}.trace` | ||
| **Action log** - The main trace file containing: | ||
| - Every action performed (clicks, fills, navigations) | ||
| - DOM snapshots before and after each action | ||
| - Screenshots at each step | ||
| - Timing information | ||
| - Console messages | ||
| - Source locations | ||
| ### `trace-{timestamp}.network` | ||
| **Network log** - Complete network activity: | ||
| - All HTTP requests and responses | ||
| - Request headers and bodies | ||
| - Response headers and bodies | ||
| - Timing (DNS, connect, TLS, TTFB, download) | ||
| - Resource sizes | ||
| - Failed requests and errors | ||
| ### `resources/` | ||
| **Resources directory** - Cached resources: | ||
| - Images, fonts, stylesheets, scripts | ||
| - Response bodies for replay | ||
| - Assets needed to reconstruct page state | ||
| ## What Traces Capture | ||
| | Category | Details | | ||
| |----------|---------| | ||
| | **Actions** | Clicks, fills, hovers, keyboard input, navigations | | ||
| | **DOM** | Full DOM snapshot before/after each action | | ||
| | **Screenshots** | Visual state at each step | | ||
| | **Network** | All requests, responses, headers, bodies, timing | | ||
| | **Console** | All console.log, warn, error messages | | ||
| | **Timing** | Precise timing for each operation | | ||
| ## Use Cases | ||
| ### Debugging Failed Actions | ||
| ```bash | ||
| playwright-cli tracing-start | ||
| playwright-cli open https://app.example.com | ||
| # This click fails - why? | ||
| playwright-cli click e5 | ||
| playwright-cli tracing-stop | ||
| # Open trace to see DOM state when click was attempted | ||
| ``` | ||
| ### Analyzing Performance | ||
| ```bash | ||
| playwright-cli tracing-start | ||
| playwright-cli open https://slow-site.com | ||
| playwright-cli tracing-stop | ||
| # View network waterfall to identify slow resources | ||
| ``` | ||
| ### Capturing Evidence | ||
| ```bash | ||
| # Record a complete user flow for documentation | ||
| playwright-cli tracing-start | ||
| playwright-cli open https://app.example.com/checkout | ||
| playwright-cli fill e1 "4111111111111111" | ||
| playwright-cli fill e2 "12/25" | ||
| playwright-cli fill e3 "123" | ||
| playwright-cli click e4 | ||
| playwright-cli tracing-stop | ||
| # Trace shows exact sequence of events | ||
| ``` | ||
| ## Trace vs Video vs Screenshot | ||
| | Feature | Trace | Video | Screenshot | | ||
| |---------|-------|-------|------------| | ||
| | **Format** | .trace file | .webm video | .png/.jpeg image | | ||
| | **DOM inspection** | Yes | No | No | | ||
| | **Network details** | Yes | No | No | | ||
| | **Step-by-step replay** | Yes | Continuous | Single frame | | ||
| | **File size** | Medium | Large | Small | | ||
| | **Best for** | Debugging | Demos | Quick capture | | ||
| ## Best Practices | ||
| ### 1. Start Tracing Before the Problem | ||
| ```bash | ||
| # Trace the entire flow, not just the failing step | ||
| playwright-cli tracing-start | ||
| playwright-cli open https://example.com | ||
| # ... all steps leading to the issue ... | ||
| playwright-cli tracing-stop | ||
| ``` | ||
| ### 2. Clean Up Old Traces | ||
| Traces can consume significant disk space: | ||
| ```bash | ||
| # Remove traces older than 7 days | ||
| find .playwright-cli/traces -mtime +7 -delete | ||
| ``` | ||
| ## Limitations | ||
| - Traces add overhead to automation | ||
| - Large traces can consume significant disk space | ||
| - Some dynamic content may not replay perfectly |
| # Video Recording | ||
| Capture browser automation sessions as video for debugging, documentation, or verification. Produces WebM (VP8/VP9 codec). | ||
| ## Basic Recording | ||
| ```bash | ||
| # Open browser first | ||
| playwright-cli open | ||
| # Start recording | ||
| playwright-cli video-start demo.webm | ||
| # Add a chapter marker for section transitions | ||
| playwright-cli video-chapter "Getting Started" --description="Opening the homepage" --duration=2000 | ||
| # Navigate and perform actions | ||
| playwright-cli goto https://example.com | ||
| playwright-cli snapshot | ||
| playwright-cli click e1 | ||
| # Add another chapter | ||
| playwright-cli video-chapter "Filling Form" --description="Entering test data" --duration=2000 | ||
| playwright-cli fill e2 "test input" | ||
| # Stop and save | ||
| playwright-cli video-stop | ||
| ``` | ||
| ## Best Practices | ||
| ### 1. Use Descriptive Filenames | ||
| ```bash | ||
| # Include context in filename | ||
| playwright-cli video-start recordings/login-flow-2024-01-15.webm | ||
| playwright-cli video-start recordings/checkout-test-run-42.webm | ||
| ``` | ||
| ### 2. Record entire hero scripts. | ||
| When recording a video for the user or as a proof of work, it is best to create a code snippet and execute it with run-code. | ||
| It allows pulling appropriate pauses between the actions and annotating the video. There are new Playwright APIs for that. | ||
| 1) Perform scenario using CLI and take note of all locators and actions. You'll need those locators to request thier bounding boxes for highlight. | ||
| 2) Create a file with the intended script for video (below). Use pressSequentially w/ delay for nice typing, make reasonable pauses. | ||
| 3) Use playwright-cli run-code --file your-script.js | ||
| **Important**: Overlays are `pointer-events: none` — they do not interfere with page interactions. You can safely keep sticky overlays visible while clicking, filling, or performing any actions on the page. | ||
| ```js | ||
| async page => { | ||
| await page.screencast.start({ path: 'video.webm', size: { width: 1280, height: 800 } }); | ||
| await page.goto('https://demo.playwright.dev/todomvc'); | ||
| // Show a chapter card — blurs the page and shows a dialog. | ||
| // Blocks until duration expires, then auto-removes. | ||
| // Use this for simple use cases, but always feel free to hand-craft your own beautiful | ||
| // overlay via await page.screencast.showOverlay(). | ||
| await page.screencast.showChapter('Adding Todo Items', { | ||
| description: 'We will add several items to the todo list.', | ||
| duration: 2000, | ||
| }); | ||
| // Perform action | ||
| await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Walk the dog', { delay: 60 }); | ||
| await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter'); | ||
| await page.waitForTimeout(1000); | ||
| // Show next chapter | ||
| await page.screencast.showChapter('Verifying Results', { | ||
| description: 'Checking the item appeared in the list.', | ||
| duration: 2000, | ||
| }); | ||
| // Add a sticky annotation that stays while you perform actions. | ||
| // Overlays are pointer-events: none, so they won't block clicks. | ||
| const annotation = await page.screencast.showOverlay(` | ||
| <div style="position: absolute; top: 8px; right: 8px; | ||
| padding: 6px 12px; background: rgba(0,0,0,0.7); | ||
| border-radius: 8px; font-size: 13px; color: white;"> | ||
| ✓ Item added successfully | ||
| </div> | ||
| `); | ||
| // Perform more actions while the annotation is visible | ||
| await page.getByRole('textbox', { name: 'What needs to be done?' }).pressSequentially('Buy groceries', { delay: 60 }); | ||
| await page.getByRole('textbox', { name: 'What needs to be done?' }).press('Enter'); | ||
| await page.waitForTimeout(1500); | ||
| // Remove the annotation when done | ||
| await annotation.dispose(); | ||
| // You can also highlight relevant locators and provide contextual annotations. | ||
| const bounds = await page.getByText('Walk the dog').boundingBox(); | ||
| await page.screencast.showOverlay(` | ||
| <div style="position: absolute; | ||
| top: ${bounds.y}px; | ||
| left: ${bounds.x}px; | ||
| width: ${bounds.width}px; | ||
| height: ${bounds.height}px; | ||
| border: 1px solid red;"> | ||
| </div> | ||
| <div style="position: absolute; | ||
| top: ${bounds.y + bounds.height + 5}px; | ||
| left: ${bounds.x + bounds.width / 2}px; | ||
| transform: translateX(-50%); | ||
| padding: 6px; | ||
| background: #808080; | ||
| border-radius: 10px; | ||
| font-size: 14px; | ||
| color: white;">Check it out, it is right above this text | ||
| </div> | ||
| `, { duration: 2000 }); | ||
| await page.screencast.stop(); | ||
| } | ||
| ``` | ||
| Embrace creativity, overlays are powerful. | ||
| ### Overlay API Summary | ||
| | Method | Use Case | | ||
| |--------|----------| | ||
| | `page.screencast.showChapter(title, { description?, duration?, styleSheet? })` | Full-screen chapter card with blurred backdrop — ideal for section transitions | | ||
| | `page.screencast.showOverlay(html, { duration? })` | Custom HTML overlay — use for callouts, labels, highlights | | ||
| | `disposable.dispose()` | Remove a sticky overlay added without duration | | ||
| | `page.screencast.hideOverlays()` / `page.screencast.showOverlays()` | Temporarily hide/show all overlays | | ||
| ## Tracing vs Video | ||
| | Feature | Video | Tracing | | ||
| |---------|-------|---------| | ||
| | Output | WebM file | Trace file (viewable in Trace Viewer) | | ||
| | Shows | Visual recording | DOM snapshots, network, console, actions | | ||
| | Use case | Demos, documentation | Debugging, analysis | | ||
| | Size | Larger | Smaller | | ||
| ## Limitations | ||
| - Recording adds slight overhead to automation | ||
| - Large recordings can consume significant disk space |
| --- | ||
| name: playwright-cli | ||
| description: Automate browser interactions, test web pages and work with Playwright tests. | ||
| allowed-tools: Bash(playwright-cli:*) Bash(npx:*) Bash(npm:*) | ||
| --- | ||
| # Browser Automation with playwright-cli | ||
| ## Quick start | ||
| ```bash | ||
| # open new browser | ||
| playwright-cli open | ||
| # navigate to a page | ||
| playwright-cli goto https://playwright.dev | ||
| # interact with the page using refs from the snapshot | ||
| playwright-cli click e15 | ||
| playwright-cli type "page.click" | ||
| playwright-cli press Enter | ||
| # take a screenshot (rarely used, as snapshot is more common) | ||
| playwright-cli screenshot | ||
| # close the browser | ||
| playwright-cli close | ||
| ``` | ||
| ## Commands | ||
| ### Core | ||
| ```bash | ||
| playwright-cli open | ||
| # open and navigate right away | ||
| playwright-cli open https://example.com/ | ||
| playwright-cli goto https://playwright.dev | ||
| playwright-cli type "search query" | ||
| playwright-cli click e3 | ||
| playwright-cli dblclick e7 | ||
| # --submit presses Enter after filling the element | ||
| playwright-cli fill e5 "user@example.com" --submit | ||
| playwright-cli drag e2 e8 | ||
| playwright-cli hover e4 | ||
| playwright-cli select e9 "option-value" | ||
| playwright-cli upload ./document.pdf | ||
| playwright-cli check e12 | ||
| playwright-cli uncheck e12 | ||
| playwright-cli snapshot | ||
| playwright-cli eval "document.title" | ||
| playwright-cli eval "el => el.textContent" e5 | ||
| # get element id, class, or any attribute not visible in the snapshot | ||
| playwright-cli eval "el => el.id" e5 | ||
| playwright-cli eval "el => el.getAttribute('data-testid')" e5 | ||
| playwright-cli dialog-accept | ||
| playwright-cli dialog-accept "confirmation text" | ||
| playwright-cli dialog-dismiss | ||
| playwright-cli resize 1920 1080 | ||
| playwright-cli close | ||
| ``` | ||
| ### Navigation | ||
| ```bash | ||
| playwright-cli go-back | ||
| playwright-cli go-forward | ||
| playwright-cli reload | ||
| ``` | ||
| ### Keyboard | ||
| ```bash | ||
| playwright-cli press Enter | ||
| playwright-cli press ArrowDown | ||
| playwright-cli keydown Shift | ||
| playwright-cli keyup Shift | ||
| ``` | ||
| ### Mouse | ||
| ```bash | ||
| playwright-cli mousemove 150 300 | ||
| playwright-cli mousedown | ||
| playwright-cli mousedown right | ||
| playwright-cli mouseup | ||
| playwright-cli mouseup right | ||
| playwright-cli mousewheel 0 100 | ||
| ``` | ||
| ### Save as | ||
| ```bash | ||
| playwright-cli screenshot | ||
| playwright-cli screenshot e5 | ||
| playwright-cli screenshot --filename=page.png | ||
| playwright-cli pdf --filename=page.pdf | ||
| ``` | ||
| ### Tabs | ||
| ```bash | ||
| playwright-cli tab-list | ||
| playwright-cli tab-new | ||
| playwright-cli tab-new https://example.com/page | ||
| playwright-cli tab-close | ||
| playwright-cli tab-close 2 | ||
| playwright-cli tab-select 0 | ||
| ``` | ||
| ### Storage | ||
| ```bash | ||
| playwright-cli state-save | ||
| playwright-cli state-save auth.json | ||
| playwright-cli state-load auth.json | ||
| # Cookies | ||
| playwright-cli cookie-list | ||
| playwright-cli cookie-list --domain=example.com | ||
| playwright-cli cookie-get session_id | ||
| playwright-cli cookie-set session_id abc123 | ||
| playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure | ||
| playwright-cli cookie-delete session_id | ||
| playwright-cli cookie-clear | ||
| # LocalStorage | ||
| playwright-cli localstorage-list | ||
| playwright-cli localstorage-get theme | ||
| playwright-cli localstorage-set theme dark | ||
| playwright-cli localstorage-delete theme | ||
| playwright-cli localstorage-clear | ||
| # SessionStorage | ||
| playwright-cli sessionstorage-list | ||
| playwright-cli sessionstorage-get step | ||
| playwright-cli sessionstorage-set step 3 | ||
| playwright-cli sessionstorage-delete step | ||
| playwright-cli sessionstorage-clear | ||
| ``` | ||
| ### Network | ||
| ```bash | ||
| playwright-cli route "**/*.jpg" --status=404 | ||
| playwright-cli route "https://api.example.com/**" --body='{"mock": true}' | ||
| playwright-cli route-list | ||
| playwright-cli unroute "**/*.jpg" | ||
| playwright-cli unroute | ||
| ``` | ||
| ### DevTools | ||
| ```bash | ||
| playwright-cli console | ||
| playwright-cli console warning | ||
| playwright-cli network | ||
| playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])" | ||
| playwright-cli run-code --filename=script.js | ||
| playwright-cli tracing-start | ||
| playwright-cli tracing-stop | ||
| playwright-cli video-start video.webm | ||
| playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000 | ||
| playwright-cli video-stop | ||
| ``` | ||
| ## Open parameters | ||
| ```bash | ||
| # Use specific browser when creating session | ||
| playwright-cli open --browser=chrome | ||
| playwright-cli open --browser=firefox | ||
| playwright-cli open --browser=webkit | ||
| playwright-cli open --browser=msedge | ||
| # Connect to browser via extension | ||
| playwright-cli open --extension | ||
| # Use persistent profile (by default profile is in-memory) | ||
| playwright-cli open --persistent | ||
| # Use persistent profile with custom directory | ||
| playwright-cli open --profile=/path/to/profile | ||
| # Start with config file | ||
| playwright-cli open --config=my-config.json | ||
| # Close the browser | ||
| playwright-cli close | ||
| # Delete user data for the default session | ||
| playwright-cli delete-data | ||
| ``` | ||
| ## Snapshots | ||
| After each command, playwright-cli provides a snapshot of the current browser state. | ||
| ```bash | ||
| > playwright-cli goto https://example.com | ||
| ### Page | ||
| - Page URL: https://example.com/ | ||
| - Page Title: Example Domain | ||
| ### Snapshot | ||
| [Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml) | ||
| ``` | ||
| You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed. | ||
| ```bash | ||
| # default - save to a file with timestamp-based name | ||
| playwright-cli snapshot | ||
| # save to file, use when snapshot is a part of the workflow result | ||
| playwright-cli snapshot --filename=after-click.yaml | ||
| # snapshot an element instead of the whole page | ||
| playwright-cli snapshot "#main" | ||
| # limit snapshot depth for efficiency, take a partial snapshot afterwards | ||
| playwright-cli snapshot --depth=4 | ||
| playwright-cli snapshot e34 | ||
| ``` | ||
| ## Targeting elements | ||
| By default, use refs from the snapshot to interact with page elements. | ||
| ```bash | ||
| # get snapshot with refs | ||
| playwright-cli snapshot | ||
| # interact using a ref | ||
| playwright-cli click e15 | ||
| ``` | ||
| You can also use css selectors or Playwright locators. | ||
| ```bash | ||
| # css selector | ||
| playwright-cli click "#main > button.submit" | ||
| # role locator | ||
| playwright-cli click "getByRole('button', { name: 'Submit' })" | ||
| # test id | ||
| playwright-cli click "getByTestId('submit-button')" | ||
| ``` | ||
| ## Browser Sessions | ||
| ```bash | ||
| # create new browser session named "mysession" with persistent profile | ||
| playwright-cli -s=mysession open example.com --persistent | ||
| # same with manually specified profile directory (use when requested explicitly) | ||
| playwright-cli -s=mysession open example.com --profile=/path/to/profile | ||
| playwright-cli -s=mysession click e6 | ||
| playwright-cli -s=mysession close # stop a named browser | ||
| playwright-cli -s=mysession delete-data # delete user data for persistent session | ||
| playwright-cli list | ||
| # Close all browsers | ||
| playwright-cli close-all | ||
| # Forcefully kill all browser processes | ||
| playwright-cli kill-all | ||
| ``` | ||
| ## Installation | ||
| If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`: | ||
| ```bash | ||
| npx --no-install playwright-cli --version | ||
| ``` | ||
| When local version is available, use `npx playwright-cli` in all commands. Otherwise, install `playwright-cli` as a global command: | ||
| ```bash | ||
| npm install -g @playwright/cli@latest | ||
| ``` | ||
| ## Example: Form submission | ||
| ```bash | ||
| playwright-cli open https://example.com/form | ||
| playwright-cli snapshot | ||
| playwright-cli fill e1 "user@example.com" | ||
| playwright-cli fill e2 "password123" | ||
| playwright-cli click e3 | ||
| playwright-cli snapshot | ||
| playwright-cli close | ||
| ``` | ||
| ## Example: Multi-tab workflow | ||
| ```bash | ||
| playwright-cli open https://example.com | ||
| playwright-cli tab-new https://example.com/other | ||
| playwright-cli tab-list | ||
| playwright-cli tab-select 0 | ||
| playwright-cli snapshot | ||
| playwright-cli close | ||
| ``` | ||
| ## Example: Debugging with DevTools | ||
| ```bash | ||
| playwright-cli open https://example.com | ||
| playwright-cli click e4 | ||
| playwright-cli fill e7 "test" | ||
| playwright-cli console | ||
| playwright-cli network | ||
| playwright-cli close | ||
| ``` | ||
| ```bash | ||
| playwright-cli open https://example.com | ||
| playwright-cli tracing-start | ||
| playwright-cli click e4 | ||
| playwright-cli fill e7 "test" | ||
| playwright-cli tracing-stop | ||
| playwright-cli close | ||
| ``` | ||
| ## Specific tasks | ||
| * **Running and Debugging Playwright tests** [references/playwright-tests.md](references/playwright-tests.md) | ||
| * **Request mocking** [references/request-mocking.md](references/request-mocking.md) | ||
| * **Running Playwright code** [references/running-code.md](references/running-code.md) | ||
| * **Browser session management** [references/session-management.md](references/session-management.md) | ||
| * **Storage state (cookies, localStorage)** [references/storage-state.md](references/storage-state.md) | ||
| * **Test generation** [references/test-generation.md](references/test-generation.md) | ||
| * **Tracing** [references/tracing.md](references/tracing.md) | ||
| * **Video recording** [references/video-recording.md](references/video-recording.md) | ||
| * **Inspecting element attributes** [references/element-attributes.md](references/element-attributes.md) |
+3
-3
| { | ||
| "name": "@playwright/cli", | ||
| "version": "0.1.1", | ||
| "version": "0.1.2", | ||
| "description": "Playwright CLI", | ||
@@ -21,3 +21,3 @@ "repository": { | ||
| "devDependencies": { | ||
| "@playwright/test": "1.59.0-alpha-1771104257000", | ||
| "@playwright/test": "1.59.0-alpha-1774912654000", | ||
| "@types/node": "^25.2.1" | ||
@@ -27,3 +27,3 @@ }, | ||
| "minimist": "^1.2.5", | ||
| "playwright": "1.59.0-alpha-1771104257000" | ||
| "playwright": "1.59.0-alpha-1774912654000" | ||
| }, | ||
@@ -30,0 +30,0 @@ "bin": { |
@@ -18,2 +18,5 @@ #!/usr/bin/env node | ||
| require('playwright/lib/cli/client/program'); | ||
| const { program } = require('playwright-core/lib/tools/cli-client/program'); | ||
| const packageJson = require('./package.json'); | ||
| program({ embedderVersion: packageJson.version }); |
+64
-21
@@ -51,3 +51,3 @@ # playwright-cli | ||
| > Use playwright skills to test https://demo.playwright.dev/todomvc/. | ||
| Take screenshots for all successful and failing scenarios. | ||
| Take screenshots for all successful and failing scenarios. | ||
| ``` | ||
@@ -141,2 +141,3 @@ | ||
| playwright-cli fill <ref> <text> # fill text into editable element | ||
| playwright-cli fill <ref> <text> --submit # fill and press Enter | ||
| playwright-cli drag <startRef> <endRef> # perform drag and drop between two elements | ||
@@ -150,2 +151,4 @@ playwright-cli hover <ref> # hover over element on page | ||
| playwright-cli snapshot --filename=f # save snapshot to specific file | ||
| playwright-cli snapshot <ref> # snapshot a specific element | ||
| playwright-cli snapshot --depth=N # limit snapshot depth for efficiency | ||
| playwright-cli eval <func> [ref] # evaluate javascript expression on page or element | ||
@@ -242,6 +245,8 @@ playwright-cli dialog-accept [prompt] # accept a dialog | ||
| playwright-cli run-code <code> # run playwright code snippet | ||
| playwright-cli run-code --filename=f # run playwright code from a file | ||
| playwright-cli tracing-start # start trace recording | ||
| playwright-cli tracing-stop # stop trace recording | ||
| playwright-cli video-start # start video recording | ||
| playwright-cli video-stop [filename] # stop video recording | ||
| playwright-cli video-start [filename] # start video recording | ||
| playwright-cli video-chapter <title> # add a chapter marker to the video | ||
| playwright-cli video-stop # stop video recording | ||
| ``` | ||
@@ -274,6 +279,44 @@ | ||
| You can also take a snapshot on demand using `playwright-cli snapshot` command. | ||
| You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed. | ||
| If `--filename` is not provided, a new snapshot file is created with a timestamp. Default to automatic file naming, use `--filename=` when artifact is a part of the workflow result. | ||
| ```bash | ||
| # default - save to a file with timestamp-based name | ||
| playwright-cli snapshot | ||
| # save to file, use when snapshot is a part of the workflow result | ||
| playwright-cli snapshot --filename=after-click.yaml | ||
| # snapshot an element instead of the whole page | ||
| playwright-cli snapshot "#main" | ||
| # limit snapshot depth for efficiency, take a partial snapshot afterwards | ||
| playwright-cli snapshot --depth=4 | ||
| playwright-cli snapshot e34 | ||
| ``` | ||
| ### Targeting elements | ||
| By default, use refs from the snapshot to interact with page elements. | ||
| ```bash | ||
| # get snapshot with refs | ||
| playwright-cli snapshot | ||
| # interact using a ref | ||
| playwright-cli click e15 | ||
| ``` | ||
| You can also use css selectors or Playwright locators. | ||
| ```bash | ||
| # css selector | ||
| playwright-cli click "#main > button.submit" | ||
| # role locator | ||
| playwright-cli click "getByRole('button', { name: 'Submit' })" | ||
| # test id | ||
| playwright-cli click "getByTestId('submit-button')" | ||
| ``` | ||
| ### Sessions | ||
@@ -292,9 +335,14 @@ | ||
| In some cases you might want to install playwright-cli locally. If running the globally available `playwright-cli` binary fails, use `npx playwright-cli` to run the commands. For example: | ||
| If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`: | ||
| ```bash | ||
| npx playwright-cli open https://example.com | ||
| npx playwright-cli click e1 | ||
| npx --no-install playwright-cli --version | ||
| ``` | ||
| When local version is available, use `npx playwright-cli` in all commands. Otherwise, install `playwright-cli` as a global command: | ||
| ```bash | ||
| npm install -g @playwright/cli@latest | ||
| ``` | ||
| ## Configuration file | ||
@@ -308,3 +356,3 @@ | ||
| Playwright CLI will load config from `playwright-cli.json` by default so that you did not need to specify it every time. | ||
| Playwright CLI will load config from `.playwright/cli.config.json` by default so that you did not need to specify it every time. | ||
@@ -465,4 +513,4 @@ <details> | ||
| | `PLAYWRIGHT_MCP_CDP_ENDPOINT` CDP endpoint to connect to. | | ||
| | `PLAYWRIGHT_MCP_CDP_HEADER` CDP headers to send with the connect request, multiple can be specified. | | ||
| | `PLAYWRIGHT_MCP_CODEGEN` specify the language to use for code generation, possible values: "typescript", "none". Default is "typescript". | | ||
| | `PLAYWRIGHT_MCP_CDP_HEADERS` CDP headers to send with the connect request, multiple can be specified. | | ||
| | `PLAYWRIGHT_MCP_CDP_TIMEOUT` timeout for the CDP connection. | | ||
| | `PLAYWRIGHT_MCP_CONFIG` path to the configuration file. | | ||
@@ -474,4 +522,3 @@ | `PLAYWRIGHT_MCP_CONSOLE_LEVEL` level of console messages to return: "error", "warning", "info", "debug". Each level includes the messages of more severe levels. | | ||
| | `PLAYWRIGHT_MCP_GRANT_PERMISSIONS` List of permissions to grant to the browser context, for example "geolocation", "clipboard-read", "clipboard-write". | | ||
| | `PLAYWRIGHT_MCP_HEADLESS` run browser in headless mode, headed by default | | ||
| | `PLAYWRIGHT_MCP_HOST` host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces. | | ||
| | `PLAYWRIGHT_MCP_HEADLESS` whether to run browser in headless mode, headless by default. | | ||
| | `PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS` ignore https errors | | ||
@@ -481,15 +528,9 @@ | `PLAYWRIGHT_MCP_INIT_PAGE` path to TypeScript file to evaluate on Playwright page object | | ||
| | `PLAYWRIGHT_MCP_ISOLATED` keep the browser profile in memory, do not save it to disk. | | ||
| | `PLAYWRIGHT_MCP_IMAGE_RESPONSES` whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow". | | ||
| | `PLAYWRIGHT_MCP_NO_SANDBOX` disable the sandbox for all process types that are normally sandboxed. | | ||
| | `PLAYWRIGHT_MCP_SANDBOX` whether to enable the browser sandbox. | | ||
| | `PLAYWRIGHT_MCP_OUTPUT_DIR` path to the directory for output files. | | ||
| | `PLAYWRIGHT_MCP_OUTPUT_MODE` whether to save snapshots, console messages, network logs to a file or to the standard output. Can be "file" or "stdout". Default is "stdout". | | ||
| | `PLAYWRIGHT_MCP_PORT` port to listen on for SSE transport. | | ||
| | `PLAYWRIGHT_MCP_PROXY_BYPASS` comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com" | | ||
| | `PLAYWRIGHT_MCP_PROXY_SERVER` specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080" | | ||
| | `PLAYWRIGHT_MCP_SAVE_SESSION` Whether to save the Playwright MCP session into the output directory. | | ||
| | `PLAYWRIGHT_MCP_SAVE_TRACE` Whether to save the Playwright Trace of the session into the output directory. | | ||
| | `PLAYWRIGHT_MCP_SAVE_VIDEO` Whether to save the video of the session into the output directory. For example "--save-video=800x600" | | ||
| | `PLAYWRIGHT_MCP_SECRETS` path to a file containing secrets in the dotenv format | | ||
| | `PLAYWRIGHT_MCP_SHARED_BROWSER_CONTEXT` reuse the same browser context between all connected HTTP clients. | | ||
| | `PLAYWRIGHT_MCP_SNAPSHOT_MODE` when taking snapshots for responses, specifies the mode to use. Can be "incremental", "full", or "none". Default is incremental. | | ||
| | `PLAYWRIGHT_MCP_SECRETS_FILE` path to a file containing secrets in the dotenv format | | ||
| | `PLAYWRIGHT_MCP_STORAGE_STATE` path to the storage state file for isolated sessions. | | ||
@@ -508,2 +549,3 @@ | `PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE` specify the attribute to use for test ids, defaults to "data-testid" | | ||
| * **Running and Debugging Playwright tests** — run, debug and manage Playwright test suites | ||
| * **Request mocking** — intercept and mock network requests | ||
@@ -516,1 +558,2 @@ * **Running Playwright code** — execute arbitrary Playwright scripts | ||
| * **Video recording** — capture browser session videos | ||
| * **Inspecting element attributes** — get element id, class, or any attribute not visible in the snapshot |
73326
117.06%14
250%19
11.76%548
8.51%+ Added
+ Added
- Removed
- Removed