U

Ultimate Playwright Browser Automation Studio

Professional-grade skill designed for automated browser testing for web applications. Built for Claude Code with best practices and real-world patterns.

SkillCommunitytestingv1.0.0MIT
0 views0 copies

Playwright Browser Automation Studio

A comprehensive browser automation skill for building end-to-end test suites, web scraping pipelines, and automated browser workflows using Playwright's full feature set including codegen, trace viewer, and multi-browser testing.

When to Use

Choose Playwright Browser Automation Studio when:

  • Building comprehensive end-to-end test suites with visual debugging and trace recording
  • Creating complex browser automation workflows with multi-tab and multi-context support
  • Setting up cross-browser testing infrastructure for CI/CD pipelines
  • Building production web scraping systems with anti-detection and session management

Consider alternatives when:

  • Unit testing React components — use Testing Library
  • Simple HTTP API testing — use Supertest or REST clients
  • Mobile-specific testing — use Appium or XCUITest

Quick Start

# Initialize Playwright project with codegen npm init playwright@latest npx playwright codegen https://example.com # Record interactions npx playwright test --ui # Visual test runner
import { test, expect, type Page, type BrowserContext } from '@playwright/test'; // Custom fixture for authenticated testing const authenticatedTest = test.extend<{ authedPage: Page }>({ authedPage: async ({ browser }, use) => { const context = await browser.newContext({ storageState: 'auth-state.json' }); const page = await context.newPage(); await use(page); await context.close(); } }); authenticatedTest('manage user dashboard', async ({ authedPage }) => { await authedPage.goto('/dashboard'); await expect(authedPage.getByRole('heading', { name: 'Dashboard' })).toBeVisible(); // Test data table interaction const table = authedPage.getByRole('table'); await expect(table.getByRole('row')).toHaveCount(11); // Header + 10 rows // Sort by name await table.getByRole('columnheader', { name: 'Name' }).click(); const firstCell = table.getByRole('row').nth(1).getByRole('cell').first(); await expect(firstCell).toHaveText(/^A/); // Starts with A after sort // Filter await authedPage.getByPlaceholder('Search...').fill('admin'); await expect(table.getByRole('row')).toHaveCount(2); // Header + 1 match }); // Visual regression test test('homepage visual regression', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('networkidle'); await expect(page).toHaveScreenshot('homepage.png', { maxDiffPixelRatio: 0.01, fullPage: true }); }); // API mocking for deterministic tests test('handles API errors gracefully', async ({ page }) => { await page.route('**/api/data', route => route.fulfill({ status: 500, body: 'Internal Server Error' }) ); await page.goto('/data-view'); await expect(page.getByText('Something went wrong')).toBeVisible(); await expect(page.getByRole('button', { name: 'Retry' })).toBeVisible(); });

Core Concepts

Playwright Features Matrix

FeatureDescriptionUse Case
CodegenRecord and generate test codeQuick test creation
Trace ViewerVisual debugging with timelineCI failure debugging
UI ModeInteractive test runnerLocal development
Visual ComparisonsScreenshot diff testingVisual regression
Network InterceptionMock/modify API responsesDeterministic tests
Multi-browserChromium, Firefox, WebKitCross-browser testing
Auth StateSave/load authenticationSkip login in tests
FixturesCustom test setup/teardownShared configuration

Advanced Patterns

// Global setup for authentication import { chromium, type FullConfig } from '@playwright/test'; async function globalSetup(config: FullConfig) { const browser = await chromium.launch(); const page = await browser.newPage(); await page.goto('http://localhost:3000/login'); await page.getByLabel('Email').fill('[email protected]'); await page.getByLabel('Password').fill('admin123'); await page.getByRole('button', { name: 'Sign in' }).click(); await page.waitForURL('/dashboard'); await page.context().storageState({ path: 'auth-state.json' }); await browser.close(); } export default globalSetup; // Parallel test execution with worker isolation test.describe.parallel('independent tests', () => { test('test 1', async ({ page }) => { /* ... */ }); test('test 2', async ({ page }) => { /* ... */ }); test('test 3', async ({ page }) => { /* ... */ }); });

Configuration

OptionDescriptionDefault
baseURLBase URL for all navigations"http://localhost:3000"
projectsBrowser configurations to test[{ name: 'chromium' }]
workersParallel test workers50% of CPUs
retriesTest retry count0 (2 on CI)
timeoutTest timeout (ms)30000
use.traceTrace recording mode"on-first-retry"
use.screenshotScreenshot on failure"only-on-failure"
globalSetupGlobal setup script pathnull

Best Practices

  1. Use role-based locators (getByRole, getByLabel, getByPlaceholder) instead of CSS selectors or test IDs — role-based selectors test accessibility simultaneously and are more resilient to implementation changes
  2. Record traces on first retry to get detailed debugging information for flaky tests without the overhead of recording every test run — traces include screenshots, network logs, and console output at every step
  3. Use the global setup to authenticate once and share the storage state across all tests, eliminating redundant login flows and making the test suite 10-50x faster
  4. Mock external APIs with page.route() to make tests deterministic — real API calls make tests slow, flaky, and dependent on external service availability
  5. Run visual regression tests in Docker containers to ensure consistent rendering across local machines and CI, avoiding false positives from font rendering differences between operating systems

Common Issues

Flaky tests passing/failing intermittently: Most flakiness comes from timing issues where the test interacts with elements before they are ready. Use Playwright's built-in auto-waiting, avoid page.waitForTimeout(), and prefer expect(locator).toBeVisible() assertions that auto-retry until the condition is met or the timeout expires.

Visual regression tests failing across environments: Different operating systems render fonts and anti-aliasing differently. Run screenshot comparisons in Docker with a fixed browser version and OS, or use maxDiffPixelRatio to allow minor rendering differences while still catching meaningful visual changes.

Authentication state not persisting: The storage state file may be generated during global setup but not found during test execution if the path is relative to a different directory. Use absolute paths or configure the storageState path relative to playwright.config.ts location, and verify the file exists before tests run.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates