e2e-testing
End-to-end testing patterns with Playwright for full-stack Python/React applications. Use when writing E2E tests for complete user workflows (login, CRUD, navigation), critical path regression tests, or cross-browser validation. Covers test structure, page object model, selector strategy (data-testi
By hieutrtr · 1,643 installs
npx skills add hieutrtr/ai1-skills --skill e2e-testing
Source repository · Upstream listing
E2E Testing
When to Use
Activate this skill when:
Writing E2E tests for complete user workflows (login, CRUD operations, multi page flows)
Creating critical path regression tests that validate the full stack
Testing cross browser compatibility (Chromium, Firefox, WebKit)
Validating authentication flows end to end
Testing file upload/download workflows
Writing smoke tests for deployment verification
Do NOT use this skill for:
React component unit tests (use react testing patterns )
Python backend unit/integration tests (use pytest patterns )
TDD workflow enforcement (use tdd workflow )
API contract testing without a browser (use pytest patterns with httpx)
Instructions
Test Structure
Naming conventions:
Test files: <feature .spec.ts
Page objects: <page name .page.ts
Fixtures: <concern .fixture.ts
Test names: human readable sentences describing the user action and expected outcome
Page Object Model
Every page gets a page object class that encapsulates selectors and actions. Tests never interact with selectors directly.
Base page object:
Concrete page object:
Rules for page objects:
One page object per page or major UI section
Locators are public readonly properties
Actions are async methods
Page objects never contain assertions tests assert
Page objects handle waits internally after actions
Selector Strategy
Priority order (highest to lowest):
Priority Selector Example When to Use
1 data testid getByTestId("submit btn") Interactive elements, dynamic content
2 Role getByRole("button", { name: /save/i }) Buttons, links, headings, inputs
3 Label getByLabel("Email") Form inputs with labels
4 Placeholder getByPlaceholder("Search...") Search inputs
5 Text getByText("Welcome back") Static text content
NEVER use:
CSS selectors ( .class name , id ) brittle, break on styling changes
XPath ( //div[@class="foo"] ) unreadable, extremely brittle
DOM structure selectors ( div span:nth child(2) ) break on layout changes
Adding data testid attributes:
Wait Strategies
NEVER use hardcoded waits:
Use explicit wait conditions:
Auto waiting: Playwright auto waits for elements to be actionable before clicking, filling, etc. Explicit waits are needed only for assertions or complex state transitions.
Auth State Reuse
Avoid logging in before every test. Save auth state and reuse it.
Setup auth state once:
Reuse in tests:
Test Data Management
Principles:
Tests create their own data (never depend on pre existing data)
Tests clean up after themselves (or use API to reset)
Use API calls for setup, not UI interactions (faster, more reliable)
API helpers for test data:
Usage in tests:
Debugging Flaky Tests
1. Use trace viewer for failures:
View trace: npx playwright show trace trace.zip
2. Run in headed mode for debugging:
3. Common causes of flaky tests:
Cause Fix
Hardcoded waits Use explicit wait conditions
Shared test data Each test creates its own data
Animation interference Set animations: "disabled" in config
Race conditions Wait for API responses before assertions
Viewport dependent behavior Set explicit viewport in config
Session leaks between tests Use storageState correctly, clear cookies
4. Retry strategy:
CI Configuration
Use scripts/run e2e with report.sh to run Playwright with HTML report output locally.
Examples
See references/page object template.ts for annotated page object class.
See references/e2e test template.ts for annotated E2E test.
See references/playwright config example.ts for production Playwright config.