Modern QA2026Migration and Comparison
Log inJoin

Course13 Browser Automation with Playwright⊞ Tile viewNew!

Foundations · Chapter 13

Migration and Comparison

Updated Aug 2026

Most teams do not start from zero — they have existing Selenium or Cypress suites that they need to evaluate, maintain, or migrate. Understanding the practical trade-offs between frameworks, and having a migration strategy, is essential knowledge for QA engineers.

Framework Comparison

Feature Playwright Selenium Cypress
Architecture WebSocket to browser HTTP to driver process Runs inside browser
Languages TS/JS, Python, Java, C# Java, Python, JS, C#, Ruby, Go JavaScript/TypeScript only
Browsers Chromium, Firefox, WebKit Chrome, Firefox, Safari, Edge, IE Chromium, Firefox, WebKit (limited)
Auto-waiting Built-in Manual (explicit/implicit waits) Built-in
Network mocking Native page.route() Proxy-based (complex setup) Native cy.intercept()
Parallel execution Built-in workers + sharding Selenium Grid (separate infra) Cypress Cloud (paid) or DIY
Multi-tab support Native Native Not supported
iFrame support frameLocator() switch_to.frame() cy.iframe() (plugin)
Test runner Built-in Bring your own Built-in (Mocha-based)
Mobile testing Device emulation Appium integration Device emulation
Debugging Trace Viewer, UI Mode Browser DevTools Time-travel debugger

Where Each Framework Stands (July 2026)

  • Playwright is on 1.61 and ships first-party AI tooling: Test Agents (planner / generator / healer) and a token-efficient CLI for coding agents (covered in AI-Assisted Testing).
  • Selenium is still on the 4.x line (≈4.41) — Selenium 5 has not shipped; its headline feature is expected to be high-level WebDriver BiDi APIs. Low-level BiDi already works in Selenium 4 (~70% of the CDP surface), and WebdriverIO v9 defaults to BiDi.
  • Cypress v15 added cy.prompt() natural-language test authoring, Cypress Studio (record-and-refine), and self-healing capabilities — making Cypress a real player in AI-assisted authoring.

When to Choose What

Choose Playwright When

  • Starting a new project with no existing test suite
  • Team uses TypeScript, Python, Java, or C#
  • Need cross-browser testing (including WebKit/Safari engine)
  • Need network mocking, multi-tab, or advanced browser control
  • Want built-in test infrastructure (runner, reporter, traces)

Keep Selenium When

  • Large existing Selenium suite with years of investment
  • Team uses Ruby, Go, or other languages Playwright does not support
  • Need real Safari testing (not WebKit approximation)
  • Organization mandates Selenium or uses Selenium Grid infrastructure
  • Integrating with Appium for mobile native testing

Choose Cypress When

  • Team is exclusively JavaScript/TypeScript
  • Testing a single-page application
  • Developer experience and fast feedback loop are the priority
  • Do not need multi-tab or multi-origin testing
  • In-runner AI authoring appeals to the team — Cypress v15's cy.prompt() and Cypress Studio lower the writing barrier

Migrating from Selenium to Playwright

Step 1: Concept Mapping

Selenium Concept Playwright Equivalent
WebDriver / driver Page / page
driver.get(url) page.goto(url)
driver.find_element(By.ID, 'x') page.locator('#x') or page.getByTestId('x')
element.click() locator.click() (with auto-wait)
element.send_keys('text') locator.fill('text')
WebDriverWait + expected_conditions Auto-waiting (built-in)
driver.switch_to.frame() page.frameLocator()
driver.quit() Context/browser cleanup (automatic in test runner)
Selenium Grid Built-in workers + sharding
Page Object with WebDriverWait Page Object with Locators (no waits needed)

Step 2: Migration Strategy

Approach A: Gradual (Recommended)

  1. New tests written in Playwright from day one
  2. Run both suites in CI in parallel
  3. Migrate existing tests by priority (critical paths first)
  4. Decommission Selenium suite when coverage is equivalent

Approach B: Big Bang

  1. Rewrite all tests in Playwright at once
  2. Faster transition but higher risk
  3. Only viable for small suites (< 100 tests)

Step 3: Common Conversion Patterns

# Selenium
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="submit"]'))
)
element.click()

# Playwright — no explicit wait needed
page.get_by_test_id("submit").click()
// Selenium (JS)
await driver.wait(until.elementLocated(By.id('result')), 10000);
const text = await driver.findElement(By.id('result')).getText();
assert.equal(text, 'Success');

// Playwright — web-first assertion retries automatically
await expect(page.locator('#result')).toHaveText('Success');

Migrating from Cypress to Playwright

Cypress Pattern Playwright Equivalent
cy.visit('/page') await page.goto('/page')
cy.get('[data-cy="x"]') page.getByTestId('x')
cy.contains('text') page.getByText('text')
cy.intercept() page.route()
cy.fixture('data.json') Custom fixture or import
beforeEach() test.beforeEach() or fixtures
Cypress Cloud (parallel) Built-in sharding

Key Differences to Watch

  • Cypress commands are automatically chained and retried; Playwright uses async/await explicitly
  • Cypress runs inside the browser (single-origin limitation); Playwright controls from outside (multi-origin supported)
  • Cypress has no multi-tab support; Playwright handles tabs natively

Key Takeaways

  • Playwright offers the best combination of speed, reliability, and features for new projects
  • Selenium remains valid for teams with large existing investments or unsupported language requirements
  • Cypress is strong for SPA-focused JavaScript teams but has architectural limitations
  • Gradual migration (new tests in Playwright, migrate existing by priority) is the safest approach
  • Most Selenium patterns have simpler Playwright equivalents — especially waits and locators