@tank/playwright-mastery
1.0.0Description
End-to-end testing mastery with Playwright Test. Covers locators, auto-waiting assertions, Page Object Model with fixtures, test configuration, authentication state reuse, network mocking, visual regression, API testing, CI/CD integration, debugging with Trace Viewer, and accessibility testing.
Triggered by
playwrighte2e testplaywright fixtureplaywright page objectplaywright CIplaywright visual testing
Download
Verified
tank install @tank/playwright-masteryPlaywright Mastery
Core Philosophy
- User-facing locators first — Locate elements as users and assistive technology perceive them. Prefer getByRole, getByLabel, getByText over CSS selectors or XPath. Resilient locators survive refactors.
- Auto-waiting eliminates flakiness — Every Playwright action waits for actionability (visible, enabled, stable) before executing. Never add manual sleep() calls. Trust the built-in retry mechanism.
- Test isolation is non-negotiable — Each test gets a fresh BrowserContext. Tests must not share state, leak cookies, or depend on execution order. Fixtures enforce this automatically.
- Fixtures over hooks — Replace beforeEach/afterEach with custom fixtures. Fixtures are composable, reusable across files, on-demand, and encapsulate setup + teardown together.
- Assert, never check — Use web-first assertions (expect(locator).toBeVisible()) that auto-retry until timeout. Never use if/else with isVisible() for assertions — that creates race conditions.
Quick-Start: Common Problems
"Tests are flaky and timing out"
- Replace manual waitForTimeout() calls with proper assertions or locator auto-waiting
- Use web-first assertions:
await expect(locator).toBeVisible()— retries automatically - Check if locators are too broad (matching multiple elements triggers strict mode)
- Inspect failures with Trace Viewer: set
trace: 'on-first-retry'in config -> Seereferences/locators-selectors.mdandreferences/ci-cd-integration.md
"How do I structure tests with Page Object Model?"
- Create page classes with Locator fields in the constructor
- Wrap them in custom fixtures via
test.extend<{ myPage: MyPage }>() - Request the fixture by name in test functions — setup/teardown is automatic
- Compose multiple page objects into a single test via multiple fixture parameters
-> See
references/fixtures-page-objects.md
"Tests need authentication but login is slow"
- Create a globalSetup script that logs in and saves
storageStateto a JSON file - Configure the project to reuse that storage state for all tests
- For multi-role tests, create separate storage state files per role
-> See
references/authentication-state.md
"I need to mock API responses"
- Use
page.route('**/api/**', route => route.fulfill({ json: data }))for inline mocks - Record HAR files with
page.routeFromHAR()for complex API surfaces - Combine UI tests with real API calls using the
requestfixture -> Seereferences/network-api-testing.md
"CI is slow and screenshots differ across environments"
- Shard tests with
--shard=1/4for parallel CI jobs - Use the official Docker image
mcr.microsoft.com/playwrightfor consistent visual baselines - Upload traces and reports as CI artifacts for debugging
-> See
references/ci-cd-integration.md
Decision Trees
Locator Selection
| Element Type | Recommended Locator |
|---|---|
| Button, link, checkbox | getByRole('button', { name: '...' }) |
| Form input with label | getByLabel('Email') |
| Non-interactive text | getByText('Welcome') |
| Image | getByAltText('Logo') |
| No accessible name available | getByTestId('submit-btn') |
| Complex dynamic element | locator('css=...').filter({ hasText: '...' }) |
Test Organization
| Signal | Approach |
|---|---|
| Shared setup across files | Custom fixture in shared test file |
| Tests need different browsers | Projects in playwright.config.ts |
| Tests need auth state | storageState via globalSetup or setup project |
| Tests must run sequentially | test.describe.serial() |
| Slow test suite in CI | Shard across multiple CI jobs |
Assertion Type
| Need | Assertion |
|---|---|
| Element visible/hidden | expect(locator).toBeVisible() / .toBeHidden() |
| Text content | expect(locator).toHaveText('...') / .toContainText() |
| URL after navigation | expect(page).toHaveURL(/dashboard/) |
| Input value | expect(locator).toHaveValue('...') |
| Element count | expect(locator).toHaveCount(3) |
| Visual appearance | expect(page).toHaveScreenshot() |
| Non-retrying check | expect(await locator.textContent()).toBe('...') |
Reference Index
| File | Contents |
|---|---|
references/locators-selectors.md | Locator hierarchy, getByRole/getByText/getByTestId, filtering, chaining, Shadow DOM, strictness, auto-waiting |
references/assertions-waiting.md | Web-first assertions, expect() API, soft assertions, polling, custom matchers, timeout configuration, actionability |
references/fixtures-page-objects.md | Custom fixtures, test.extend(), worker-scoped fixtures, Page Object Model, fixture composition, automatic fixtures |
references/test-configuration.md | playwright.config.ts, projects, parallelism, retries, reporters, webServer, timeouts, expect options |
references/authentication-state.md | storageState, globalSetup login, setup projects, multi-role auth, session reuse, per-test auth override |
references/network-api-testing.md | page.route(), route.fulfill/continue/abort, HAR recording, API testing with request fixture, response validation |
references/ci-cd-integration.md | GitHub Actions, Docker images, sharding, artifacts, visual regression in CI, Trace Viewer, codegen, accessibility testing |