--- id: Mindrally/skills/playwright version: "6a0c7bef" license: Apache-2.0 install: manual updated: 2026-06-09 --- # playwright — This skill equips you with Playwright testing expertise drawn from proven coding standards. Discover patterns and best practices for building reliable browser automation tests across modern web applications, leveraging insights from expert developers who've refined these techniques in production environments. Publisher: Mindrally · Stars: 202 · Updated: 2026-06-09 Install (manual): `git clone https://github.com/Mindrally/skills` ## SKILL.md # Playwright Testing Best Practices You are a Senior QA Automation Engineer expert in TypeScript, JavaScript, and Playwright end-to-end testing. ## Test Design Principles ### Test Structure - Create descriptive test names that clearly explain expected behavior - Use Playwright fixtures (`test`, `page`, `expect`) for test isolation - Implement `test.beforeEach` and `test.afterEach` for clean state management - Keep tests DRY by extracting reusable logic into helper functions ```typescript import { test, expect } from '@playwright/test'; test.describe('User Authentication', () => { test.beforeEach(async ({ page }) => { await page.goto('/login'); }); test('should login successfully with valid credentials', async ({ page }) => { await page.getByLabel('Email').fill('user@example.com'); await page.getByLabel('Password').fill('password123'); await page.getByRole('button', { name: 'Sign In' }).click(); await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible(); }); }); ``` ## Locator Strategy ### Recommended Locators - `page.getByRole()` - Best for accessibility and user perspective - `page.getByLabel()` - For form inputs with labels - `page.getByText()` - For elements with visible text - `page.getByTestId()` - When `data-testid` attributes exist - `page.getByPlaceholder()` - For inputs with placeholder text ```typescript // Recommended await page.getByRole('button', { name: 'Submit' }).click(); await page.getByLabel('Email address').fill('test@example.com'); // Avoid await page.locator('.btn-primary').click(); ``` ## Assertions and Waits ### Web-First Assertions Prefer web-first assertions that automatically wait and retry: - `toBeVisible()` - Element is visible - `toHaveText()` - Element has specific text - `toHaveValue()` - Input has specific value - `toHaveURL()` - Page URL assertion ```typescript // Recommended - web-first assertions await expect(page.getByRole('alert')).toBeVisible(); await expect(page).toHaveURL('/dashboard'); // Avoid - hardcoded timeouts await page.waitForTimeout(5000); // Never do this ``` ### Waiting Best Practices - Avoid hardcoded timeouts - Use `page.waitForLoadState()` for navigation - Use `page.waitForResponse()` for API calls ## Configuration ```typescript import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests', fullyParallel: true, retries: process.env.CI ? 2 : 0, use: { baseURL: 'http://localhost:3000', trace: 'on-first-retry', screenshot: 'only-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'mobile', use: { ...devices['iPhone 13'] } }, ], }); ``` ## Best Practices - Focus on critical user paths reflecting real behavior - Keep tests independent and deterministic - Add JSDoc comments for helper functions - Implement proper error handling and logging [View on SkillFed](https://skillfed.io/Mindrally/skills/playwright) · [View on GitHub](https://github.com/Mindrally/skills)