All topics
Testingadvanced

End-to-End Testing with Playwright/Cypress

Automated browser tests that simulate real user interactions through an actual, full application stack, providing the highest-confidence but slowest and most expensive layer of the testing pyramid.

End-to-end (E2E) testing simulates real user interactions — clicking buttons, filling out forms, navigating between pages — against a genuinely real, fully running instance of an application, typically driving an actual browser through tools like Playwright or Cypress, verifying that an entire user flow works correctly from the UI all the way through to the real backend and database, with nothing mocked or stubbed out anywhere in the chain. It sits at the top of the testing pyramid, offering the highest possible confidence that the system genuinely works as a real user would experience it, at the cost of being the slowest, most resource-intensive, and often most brittle layer to maintain.

End-to-end testing is like a full dress rehearsal of an entire theatrical production with the real cast, real costumes, real lighting, and a real live audience seated in the actual theater, versus a unit test which is more like one actor privately rehearsing a single line in front of a mirror — the dress rehearsal catches problems (a costume malfunction, a lighting cue firing at the wrong real moment) that rehearsing individual lines alone could never reveal, but you obviously can't afford to run a full dress rehearsal for every single line in the entire show.

Key Concepts

1
Modern E2E tools like Playwright and Cypress work by actually driving a real browser instance (not a simulated or headless approximation of one, though headless mode is commonly used in CI for speed) programmatically: navigating to URLs, finding elements via selectors, simulating real clicks/typing/scrolling, and asserting on the actual rendered page state, network requests made, or even visual appearance via screenshot comparison. Because they drive a genuinely real browser against a genuinely real (if test-specific) running application and backend, these tests catch an entire category of bugs that no combination of unit or integration tests ever could — CSS layout issues, real browser-specific quirks, actual network timing and race conditions, and genuine cross-system integration failures spanning frontend, backend, and database together.
2
The real cost is test flakiness and speed: E2E tests are notoriously more prone to intermittent, non-deterministic failures than unit tests, often due to timing issues (an element not yet rendered or an animation still in progress when the test tries to interact with it) rather than genuine application bugs — modern tools mitigate this significantly with built-in automatic waiting/retrying for elements to become actionable, rather than requiring hand-rolled arbitrary sleep/wait calls, but flakiness is never fully eliminated. E2E suites are also meaningfully slower to run than unit tests (each test genuinely boots and drives a real application, rather than executing pure in-memory logic), which is exactly why the testing pyramid recommends keeping the E2E layer intentionally small and focused on a handful of the most critical, highest-value user flows (login, checkout, core primary features) rather than attempting exhaustive E2E coverage of every possible edge case, which unit and integration tests are far better suited (faster, more precise, less flaky) to cover instead.
sleepwait
3
A practical, well-balanced test suite typically reserves E2E tests specifically for verifying that the most business-critical flows genuinely work end-to-end at all, while relying on the faster, cheaper, more numerous unit and integration test layers to actually exhaustively cover edge cases, error handling, and detailed business logic correctness — using each layer for what it's genuinely best suited to catch, rather than either extreme.