# Skill: Write E2E tests in Playwright that check real user scenarios > Lets an AI coding agent produce reliable end-to-end tests that walk the site like a real visitor -- using data-testid anchors, event-based waits, and screenshot-on-failure -- applies whenever a user needs a robot safety net before or after deploying changes. Source: sodigi·learn -- vibecoding/testiruem-kak-polzovatel · https://sodigi.io/learn/vibecoding/testiruem-kak-polzovatel ## When to use - User asks to add tests, set up a safety net, or "make sure nothing breaks." - Before deploying a significant change to a site (new feature, design update, animation). - Protecting critical flows: checkout, sign-up, login, wallet connection, any money-related path. - After fixing a bug, to prevent regression. ## Core rules - Tests describe **user scenarios**, not code internals: "user arrives, searches, sees results" -- not "variable count equals 5." - Always hook onto `data-testid` attributes, never onto text labels, CSS classes, or colors. Design changes must not break tests. - Never use fixed-time pauses (`waitForTimeout`, `sleep 5000`). Always wait for a specific event: element visible, network idle, data loaded. Fixed pauses are the direct cause of flaky tests. - On failure, always capture a screenshot and video trace so the failure is immediately visible without guessing. - Do not run payment or financial tests against the live/production environment. Always guard these with an environment check. - Add `data-testid` to every element the test needs to touch. Do not assume it already exists. - Prioritize critical paths: payment/checkout > auth > core user action > static pages. - Set up auto-run in CI/CD so tests execute before every deploy, not just on demand. ## Procedure 1. List the most critical user scenarios (e.g., homepage loads, checkout flow, search, login). 2. For each scenario, add `data-testid` to every button, input, and result block the test will touch. 3. Write each test as a human-readable story: goto, fill, click, expect-visible. 4. Replace any `waitForTimeout` calls with `waitForSelector`, `waitForLoadState`, or `waitForResponse`. 5. Configure Playwright to save screenshot + video on every test failure. 6. For payment/sensitive tests, add an environment guard: skip the test if running on production. 7. Provide a single command to run all tests (e.g., `npx playwright test`). 8. Optionally wire the command into a pre-deploy CI step so the suite runs automatically before every publish. ## Ready-to-use prompt ``` Write E2E tests in Playwright for my site. Cover these real user scenarios: 1. Homepage loads and the main heading is visible. 2. Full checkout flow: select a product, click Buy, fill in the form, see the confirmation. 3. Site search: type a keyword, verify results appeared. Rules for every test: - Hook onto data-testid, not text or CSS classes. Add data-testid where it is missing. - No fixed time pauses. Wait for specific events: element visible, data loaded. - On failure: save a screenshot and a video trace. - For any test touching payments, add a guard that skips it on production. - After writing the tests, give me one command to run them all. ``` ## Pitfalls - Not writing tests at all and relying on manual checking -- a single code change can silently break something unrelated. - Hooking tests onto text labels or CSS classes -- any copy edit or redesign breaks all tests immediately. - Using `wait 5 seconds` pauses -- creates flaky tests that randomly pass and fail on the same code, destroying trust in the suite. - Testing only the new feature, not the pre-existing behavior -- the main value of tests is catching what the new change quietly broke. - Ignoring a failing test by disabling it -- a red test is a signal, not a nuisance; fix the code, not the test. - Running money-path tests against a live production environment with real accounts and real money.