Cypress was the first tool to make UI testing feel modern. Great DX, time-travel debugging, automatic waiting. So why did Playwright come along? Because Cypress has architectural limitations that cannot be fixed without rewriting it.
| Feature | Playwright | Cypress |
|---|---|---|
| Runs Where | Outside the browser (Node.js process) | Inside the browser (same JavaScript context) |
| Multi-tab | Full support | Not supported (architectural limitation) |
| Cross-origin | Full support | Limited. cy.origin() is a workaround |
| Browser Support | Chromium, Firefox, WebKit | Chrome, Edge, Firefox (no Safari/WebKit) |
| Language | TS, JS, Python, Java, C# | JavaScript/TypeScript only |
| iFrames | frameLocator() -- clean | Experimental, limited support |
| Network Mocking | page.route() -- full control | cy.intercept() -- similar but in-browser |
| Component Testing | Experimental | Built-in (mature) |
| Test Isolation | Browser context per test (fast) | Page reload per test (slower) |
| Pricing | 100% free, no paid tier | Free runner, paid Dashboard for CI features |
Cypress runs inside the browser. That is why it cannot do multi-tab testing -- it literally cannot see other tabs. This is an architectural decision, not a bug. It will not be "fixed" in a future version.
Q: A team is currently using Cypress. Should they migrate to Playwright?
A: It depends. If their tests work fine and they do not need multi-tab, cross-origin, or Safari testing, migration has a cost with limited benefit. If they are hitting Cypress limitations (cannot test OAuth flows across domains, cannot test multi-tab workflows, need Safari coverage), then Playwright solves real problems. Migration is not free -- locators, assertions, and test structure all change. I would recommend a pilot: write new tests in Playwright, keep existing Cypress tests running, and migrate gradually.
Key Point: Playwright and Cypress both auto-wait. The difference is architecture: Playwright runs outside the browser, giving it superpowers Cypress cannot match.