Cypress to Playwright migration: A step-by-step guide

Step by step guide to migrate Cypress tests to Playwright, compare architectures, map commands, reduce flakiness, debug faster with traces, and CI speed.

User

TestDino

Dec 18, 2025

Cypress to Playwright migration: A step-by-step guide

I like how every migration tells a story: a story of evolution, where teams move from comfort to capability. Cypress brought front-end testing within reach, but Playwright revolutionized it with performance, scalability, and cross-browser liberty.

Whether you're pursuing fast CI runs, reduced flakiness, or a better understanding of failures, this step-by-step guide is here to help you transform your test suite into a contemporary, robust automation framework.

I am fond of watching how quickly the test automation world develops. Each year brings new frameworks, improved browser coverage, and more advanced debugging tools. Yet, one question keeps coming up among QA teams: “Should we migrate from Cypress to Playwright?”

If you’ve ever wondered that, this guide is for you. Let’s walk through the Cypress to Playwright migration journey from understanding their architectures to mapping commands, handling waits, and improving reporting with TestDino.

Overview

Cypress Architecture:

Cypress is known for its simplicity and developer-friendly syntax. It runs directly inside the browser, which makes debugging easy but also limits flexibility.

  • Single-browser tab execution is great for speed, but it restricts multi-tab tests.
  • Network layer control: intercepts requests inside the browser.
  • Tight coupling with Chrome-based browsers.

This architecture makes Cypress excellent for small to medium-sized front-end tests but less ideal for cross-browser or large-scale automation setups.

Playwright Architecture

Playwright, on the other hand, uses a browser driver model similar to Selenium but with modern APIs and auto-waiting mechanisms. It’s designed for multi-browser, multi-context testing at scale.

  • Supports Chromium, WebKit, and Firefox
  • Cross-language support: JavaScript, TypeScript, Python, C#, and Java
  • Parallel execution: Runs multiple tests across browsers
  • Powerful debugging tools: Trace viewer and network monitoring

Why teams are moving to Playwright

I like watching how teams evolve their testing strategies. Most begin with Cypress due to its ease of use and rapid setup, but as projects expand, they hit the limitations of scalability and compatibility.

That is where Playwright testing comes into its own, allowing teams to overcome those boundaries and evolve frontend automation.

Signs You Should Move from Cypress to Playwright

  • Need for cross-browser or cross-device testing: Playwright supports Chromium, Firefox, and WebKit, enabling true cross-browser testing.
  • Struggling with parallel execution: Large test suites run faster in Playwright thanks to built-in parallelism.
  • Desire for headless and faster CI/CD runs: Playwright optimizes test execution in pipelines.
  • Requirement for advanced network mocking and debugging tools: Auto-waits, request interception, and trace viewer simplify debugging.
  • Scaling automation across microservices: Playwright’s multi-context architecture handles complex workflows efficiently.

If you notice one or more of these signs, it may be time to consider a Cypress to Playwright migration for a more robust and scalable automation framework.

Key differences: Cypress vs Playwright

Feature Cypress Playwright
Browser Support
  • Only Chromium
  • Partial Firefox support
  • Chromium, WebKit, Firefox
Parallel Execution
  • Limited
  • Slower in CI/CD
  • Native parallelism
  • Fast CI/CD execution
Test Isolation
  • Single tab
  • Shared state may cause flakiness
  • Independent browser contexts
  • Better isolation
Network Stubbing/Mocking
  • Basic support
  • Advanced, flexible request interception
  • Custom response mocking
Language Support
  • JavaScript only
  • JavaScript, TypeScript, Python, C#, Java
Debugging
  • Built-in GUI
  • Interactive debugging
  • CLI + Trace Viewer
  • Step-through debugging
  • Inspect requests/responses
Flakiness Handling
  • Manual waits required
  • Auto-wait built-in
  • Configurable retries
CI/CD Integration
  • Works but requires setup
  • Native support
  • Optimized for pipelines
Cross-Device Testing
  • Limited device emulation
  • Real devices
  • Mobile browser emulation (iOS/Android)
Screenshots/Video
  • Automatic for failed tests
  • Screenshots, video
  • Detailed execution traces
Test Reporting
  • Basic reporting
  • Plugins needed for advanced reports
  • Built-in detailed reporting
  • Customizable
Community & Ecosystem
  • Large and mature
  • Many plugins
  • Growing ecosystem
  • First-class Playwright tools
Performance
  • Slower with parallel tests
  • Fast optimized for multiple browser contexts
API Testing
  • Limited via workarounds
  • Native API testing alongside UI tests
Auto-Wait for Elements
  • Manual waits needed
  • Auto-waits for ready elements
Flaky Test Prevention
  • Manual intervention required
  • Built-in isolation
  • Retries and auto-wait reduce flakiness
Learning Curve
  • Beginner-friendly
  • Simpler API
  • Slightly steeper
  • More flexible and powerful

This comparison clearly shows why the Cypress to Playwright migration has become a trend among modern QA teams.

Is Playwright the right choice for your testing needs?

Playwright is an excellent choice if you need to future-proof your test stack and automate at ease across browsers, devices, and teams. Built with the latest engineering challenges in mind, it provides speed, reliability, and flexibility, all of which are critical to large-scale QA operations.

It's especially good when you need:

  • End-to-end coverage on Chrome, Safari, and Firefox, Playwright's native multi-browser support offers equal validation in top browsers with the fewest environment-specific failures, thus providing a seamless user experience.
  • Quick headless test execution for CI/CD Playwright is optimized for automation pipelines and runs tests headlessly with low overhead, providing quicker feedback loops and deeper integration with DevOps pipelines.
  • Deep debugging for flaky tests: Trace viewer, network logs, and video capture features make root cause analysis a breeze. You can visually replay test steps and identify problems that otherwise pass undetected.

Step-by-step guide to Cypress to Playwright migration

1. Set up Playwright

Install Playwright in your project directory using the recommended initializer:

bash
npm init playwright@latest

Or manually:

bash
npm install -D @playwright/test npx playwright install

Then, add a test script to your package.json for easy execution:

package.json
"scripts": { "test:e2e": "npx playwright test" }

This sets up Playwright testing alongside your existing Cypress tests, preparing your project for a smooth Cypress to Playwright migration.

2. Create a basic Playwright test

Inline code example:

playwright.config.ts
// Playwright basic navigation test import { test, expect } from '@playwright/test'; test('navigate to example.com', async ({ page }) => { // Go to the page await page.goto('https://example.com'); // Verify the title contains "Example" await expect(page).toHaveTitle(/Example/); });

This mirrors Cypress’ it() syntax but with async/await handling for stability and modern automation practices.

3. Map Cypress commands to Playwright

Cypress Command Playwright Equivalent Explanation
cy.visit(url) await page.goto(url) Opens a page and waits until it fully loads.
cy.get(selector) page.locator(selector) Finds elements dynamically and handles DOM changes.
cy.click() await locator.click() Waits for elements to be visible before clicking.
cy.type('text') await locator.fill('text') Quickly fills input fields without typing delays.
cy.contains('text') page.getByText('text') Locates elements using visible text.
cy.wait(time) await page.waitForTimeout(time) Adds short waits when debugging or syncing steps.
cy.intercept('GET', '/api') await page.route('**/api/**', route => route.continue()) Intercepts or mocks network requests.
cy.screenshot('name') await page.screenshot({ path: 'name.png' }) Captures screenshots for test reports.
cy.viewport(width, height) await page.setViewportSize({ width, height }) Simulates different screen sizes.
cy.title() await page.title() Gets the page title for quick validation.

4. Handle waits and timing

Playwright has auto-waiting built in, which reduces flakiness:

ts
await page.locator('button#submit').click(); // waits automatically

For explicit waits:

ts
await page.waitForSelector('#status', { state: 'visible' });

5. Explore advanced use cases

Network interception:

ts
await page.route('**/api/*', route => route.abort());

Screenshot testing:

ts
await page.screenshot({ path: 'test-result.png' });

Multiple browser contexts:

ts
const context = await browser.newContext(); const page = await context.newPage();

This allows parallelism, multi-context testing, and robust Playwright testing strategies that Cypress alone cannot fully support.

6. Run and debug Playwright tests

Run tests in debug mode:

bash
npx playwright test --debug

Use the Trace Viewer for step-by-step replay:

bash
npx playwright show-trace trace.zip

This level of debugging and traceability makes Playwright testing more reliable than Cypress for larger, multi-browser test suites.

Migrating a Cypress test to Playwright

When moving from Cypress to Playwright, it’s helpful to see direct examples of how common tests translate. This makes the Cypress to Playwright migration smoother and reduces flakiness.

Example 1: Visiting a page and clicking a button

Cypress code (JavaScript)

.js
it('visit and click', () => { cy.visit('https://example.com'); cy.get('button#start').click(); });

Playwright code (JavaScript)

.js
test('visit and click', async ({ page }) => { await page.goto('https://example.com'); await page.locator('button#start').click(); });

Example 2: Filling a Form Field

Cypress code:

.js
it('fill form', () => { cy.visit('/login'); cy.get('#username').type('user'); cy.get('#password').type('pass'); cy.get('button[type=submit]').click(); });

Playwright code:

.js
test('fill form', async ({ page }) => { await page.goto('/login'); await page.locator('#username').fill('user'); await page.locator('#password').fill('pass'); await page.locator('button[type=submit]').click(); });

Example 3: Waiting for an Element to Appear

Cypress code:

.js
it('wait for element', () => { cy.get('#status', { timeout: 10000 }).should('be.visible'); });

Playwright code

.js
test('wait for element', async ({ page }) => { await page.waitForSelector('#status', { state: 'visible' }); });

Is Playwright worth the switch?

I like thinking of migrations as a journey moving from what’s familiar to what’s more capable.

Teams often start with Cypress because it’s simple and intuitive, but as projects grow, limitations become clear. This is where Playwright testing shows its true value, making the Cypress to Playwright migration worthwhile for most modern QA workflows.

Benefits of Playwright vs Cypress limitations

1. Broader browser coverage:
Unlike Cypress, which is mostly Chrome-focused with limited Firefox and Edge support, Playwright runs seamlessly on Chromium, WebKit, and Firefox. This enables true cross-browser testing and ensures your frontend automation works across all major environments.

2. Native parallelism and isolation:
Playwright allows running multiple tests simultaneously in isolated browser contexts, reducing CI/CD pipeline time and preventing test interference. Cypress, in contrast, runs tests largely in a single browser tab, limiting scalability.

3. Fewer flaky tests due to auto-wait:
Playwright’s built-in auto-waiting handles asynchronous behavior automatically, so tests are less likely to fail due to timing issues. Cypress often requires manual waits or retries, which can make large suites brittle.

4. Headless execution by default:
Playwright is optimized for headless mode, making test runs faster and easier to integrate into CI/CD pipelines. Cypress can run headless, but sometimes requires additional configuration or struggles with multi-browser headless stability.

5. Integrated tracing and debugging tools:
Playwright comes with a Trace Viewer, network monitoring, and step-by-step replay, allowing teams to debug flaky tests efficiently. Cypress debugging is simpler but less detailed for complex automation workflows.

Switching to Playwright is more than a framework change; it’s an investment in scalable, stable, and future-proof test automation. Teams gain cross-browser coverage, faster CI runs, and improved test reliability, making the migration a smart step for long-term efficiency.

When you might still keep Cypress around

I like to think of Cypress and Playwright not just as competitors but as tools with different strengths. While Playwright testing offers cross-browser coverage and scalability, Cypress still has scenarios where it shines.

1. For smaller single-browser UI tests:
If your project primarily targets Chromium-based browsers and the test suite is relatively small, Cypress’s simplicity and developer-friendly syntax make it fast to write and maintain tests. You get quick feedback without the overhead of managing multiple browser contexts.

2. When team members are heavily invested in Cypress syntax:
Teams familiar with Cypress commands and patterns may find it more productive to continue with Cypress, especially for smaller projects or prototypes. The learning curve for Playwright, while manageable, might not be justified for limited test scopes.

3. If no multi-browser or CI/CD scalability is required:
Cypress is sufficient when your frontend automation doesn’t demand parallel execution, cross-browser testing, or complex CI/CD pipelines. For lightweight projects, the overhead of migrating to Playwright might outweigh the benefits.

In short, Cypress remains a valid choice for targeted, small-scale testing, but as soon as your tests need broader coverage, higher reliability, and CI/CD efficiency, a Cypress to Playwright migration becomes worthwhile.

Leveraging TestDino for post-migration analytics

After you have your Playwright environment completely live, it's critical to continue to enhance visibility and control. That's where TestDino comes in, making raw test data into actionable, understandable insights.

  • Failure grouping by AI automatically groups similar failures, allowing for easier identification of repeated issues rather than having to browse through lengthy failure lists.
  • Migration health tracking gives you a live view of flaky tests, pass rate trends, and performance changes. You can instantly see if your new Playwright setup is becoming more stable or needs tuning.
  • Unified Playwright reports combine results, screenshots, and traces in one place. TestDino also sends smart alerts, so you’re notified about critical failures without drowning in noise.

With TestDino, your Playwright test report becomes visual, traceable, and data-driven, helping teams cut debugging time and maintain consistent release confidence.

Common Mistakes During Cypress to Playwright Migration

As teams transition from Cypress to Playwright, there will be some minor gotchas that will impede development or result in silent failures. Identifying these beforehand can prevent hours of future debugging time.

One of the most frequently encountered issues is overlooking async behavior and timeouts. Playwright runs asynchronously by default, so forgetting to await actions or manage timeouts properly can lead to flaky results.

Another challenge is mismanaging selectors. Cypress uses cy.get(), while Playwright relies on locator(). Missing this shift can cause tests to fail silently or miss elements entirely.

Teams also often forget to remove redundant waits. Since Playwright has built-in auto-waiting, keeping manual wait statements only adds unnecessary delays and instability.

Finally, not updating assertions to Playwright’s syntax or structure can lead to false passes or mismatched expectations. A quick syntax audit after migration helps maintain accuracy.

Conclusion

Migrating from Cypress to Playwright isn’t just a technical shift; it’s a strategic move toward building a scalable, future-ready testing ecosystem. Playwright empowers QA teams with multi-browser coverage, faster execution, and reduced flakiness, ensuring your automation keeps pace with evolving product demands.

Beyond speed and flexibility, Playwright’s architecture brings depth to debugging and performance tracking, offering built-in tools for tracing, network analysis, and parallel execution. This means teams spend less time maintaining flaky tests and more time improving real product quality.

When paired with TestDino, your Playwright migration becomes truly data-driven.

TestDino delivers analytics, failure grouping, and real-time trend monitoring, giving you full visibility into every run. Together, Playwright and TestDino help your QA workflow evolve faster, smarter, and more resiliently than ever.

FAQs

No. The migration is straightforward because Playwright’s test structure closely mirrors Cypress. Most effort goes into mapping commands, handling async behavior, and updating selectors.

Get started fast

Step-by-step guides, real-world examples, and proven strategies to maximize your test reporting success