QA Interview Hub · Knowledge base · Quizzes
Cypress
Cypress vs Playwright
comparison and migration
What are the key differences between Cypress and Playwright?
| Cypress | Playwright |
| Where the test lives | Inside the browser | Outside, through the browser protocol |
| Asynchrony | A command queue, no await | Promises, async/await |
| Waiting | Retry of queries and should, 4 s | Auto-waiting of actions, expect 5 s |
| Isolation | State cleared in one browser | A new BrowserContext per test |
| Tabs and domains | One tab, cy.origin | Any number |
| Parallelism | Between machines, Cloud or a plugin | Workers built in, sharding |
| Browsers | Chromium, Firefox, WebKit experimental | Chromium, Firefox, WebKit |
| Network | cy.intercept through a proxy | page.route through the protocol |
| Debugging | Time travel in the Test Runner | Trace Viewer, UI mode |
| Languages | JavaScript, TypeScript | JS/TS, Python, Java, .NET |
In an interview: The fundamental difference: Cypress runs inside the browser, and Playwright drives it from outside. Everything else follows from that. Cypress has a command queue instead of async/await, one tab, parallelism only across machines and network interception through a proxy. Playwright has ordinary promises, multiple tabs and domains, isolated contexts, built-in workers and supports several languages. On the other hand, Cypress has very convenient debugging with time travel.
When would you choose Cypress over Playwright?
Cypress is appropriate when the application is single-page, with one domain and one tab, and the tests are written mostly by front-end developers for whom time travel and component testing in the same tool matter.
The deciding factor is more often the existing stack: if the project already has a large suite on Cypress and people who know it, there is no point rewriting. For a new project without such a legacy, today the default is usually Playwright.
In an interview: I would choose Cypress if the application is single-page, on one domain, and the tests are written together with front-end developers who find time travel and component tests convenient. Even more important is what already exists on the project: if there is a large Cypress suite and the team knows it, it isn't worth rewriting. And for a new project from scratch I would take Playwright.
How would you migrate a project from Cypress to Playwright?
- Don't rewrite everything at once. New tests are written in Playwright, the old ones run in parallel in CI and are moved gradually, starting with the most critical and most flaky.
- Migrate the architecture, not the syntax. A Page Object carries over almost directly, but the methods become
async. Custom commands turn into fixtures or helpers. cy.session is replaced by storageState with a setup project.
- Network:
cy.intercept with an alias becomes page.route or page.waitForResponse.
- Risks: two stacks in CI for a while, training the team, implicit dependencies between Cypress tests that become visible in a parallel run.
- Success criterion: less flakiness, a faster run thanks to workers, coverage didn't drop.
// Cypress
cy.intercept('GET', '/api/stats').as('stats');
cy.get('[data-cy=period]').select('30d');
cy.wait('@stats');
cy.get('[data-cy=chart]').should('be.visible');
// Playwright
const stats = page.waitForResponse('**/api/stats');
await page.getByTestId('period').selectOption('30d');
await stats;
await expect(page.getByTestId('chart')).toBeVisible();
In an interview: I wouldn't rewrite everything at once. New tests are written in Playwright, the old ones live alongside in CI and are moved gradually, starting with the critical and most unstable ones. I migrate the architecture, not the lines: Page Objects almost directly, but with async, custom commands become fixtures, cy.session becomes storageState, an intercept with an alias becomes waitForResponse. The main risks are two stacks at once and hidden dependencies between tests that surface in a parallel run. I measure success by stability, run speed and the fact that coverage didn't drop.