End-to-end tests verify that a real user workflow works across browser, API, database, and supporting services. They are slower than unit tests, so use them for the paths where integration risk is highest.
Prefer accessible selectors. They test the interface the user experiences and are less brittle than CSS class selectors.
Test Data
Seed known users and records before tests run. Clean up between tests or isolate each test with unique ids.
WARNING
E2E tests become flaky when they depend on shared mutable data, arbitrary sleeps, or third-party services without test doubles.
Further Learning
Search these terms to go deeper:
“Playwright end to end testing best practices” — reliable browser tests
“test data seeding strategy E2E” — predictable environments
“contract tests vs end to end tests” — choosing test levels
“CI flaky test debugging” — making release checks trustworthy
End-to-End Testing
End-to-end (E2E) tests click through your app just like a real user would — real browser, real API calls, real database. They’re slower than unit tests, so you save them for the most important user journeys: signup, checkout, the core thing your app does.
This test does everything a real person would: log in, create a task, see it appear. If any layer of your stack breaks this flow, the test catches it.
Find elements the way a person would
Use getByRole and getByLabel (finding things by their visible label/role) rather than fragile CSS classes. It survives design changes better, and it doubles as an accessibility check.
Give it predictable data
Seed known test users/records before the test runs, so the test doesn’t depend on whatever happens to be in the database at the time.
WARNING
E2E tests get flaky (randomly failing) when they depend on shared, changing data, or arbitrary “wait a bit” delays. Use predictable seeded data and wait for actual conditions (like “this text appears”), not fixed timeouts.
In one sentence
End-to-end tests script a real user journey through your actual app (browser + API + database) — reserve them for your most critical flows, use accessible selectors, and seed predictable test data to avoid flakiness.
Want to go deeper?
Switch to Expert mode above for test isolation strategies and running E2E tests reliably in CI.