Q44 of 48 · Cypress
How would you migrate a legacy Selenium suite to Cypress incrementally?
Short answer
Short answer: Don't rewrite all at once. Set up Cypress alongside Selenium, port the highest-ROI specs first (smoke, top user journeys), keep both running in CI until coverage is parity, then retire Selenium piecewise. Plan 2-4 quarters depending on suite size; resist the urge to translate Selenium 1:1 — re-think test design as you go.
Detail
A 500-test Selenium suite migrated wholesale is a 6-month project that produces an angry team and a still-flaky suite. Incremental wins.
Phase 0 — set up Cypress alongside. Install Cypress, write 5 sample specs, get them running in CI as a separate parallel job (allowed-to-fail initially). The team learns the new framework on a low-stakes surface.
Phase 1 — top journeys. Port the 5-15 specs that cover login, checkout, and the headline feature. These are the smoke tests; if they pass, ship confidence is high. They also exercise the most Cypress patterns (auth, intercept, API setup), exposing gaps in your support package early.
Phase 2 — bug-history coverage. Re-create regression tests for production bugs from the past 12 months. This converts pain into safety net and tells you where to focus.
Phase 3 — parallel run. Both suites run on every PR; failures from either block. Compare stability and runtime; tune Cypress flake out (you'll find some). Track Cypress's escape rate vs Selenium's — when they're at parity, the next phase is safe.
Phase 4 — area-by-area retirement. Pick the area where Cypress has full coverage; delete the corresponding Selenium specs. Repeat until Selenium's footprint is small.
Phase 5 — kill switch. When only legacy or genuinely-Cypress-incompatible specs remain in Selenium (multi-browser, multi-tab), keep that small set and retire the rest.
Where to deliberately diverge from the Selenium tests:
- Don't translate POMs 1:1. Cypress's test isolation,
cy.session, and intercept patterns argue for different abstractions. A small, clean Cypress POM beats a faithful port of a sprawling Selenium one. - Drop dynamic XPath. Selenium suites accumulate elaborate XPath; Cypress's
data-testselectors pluscy.containscover most cases more cleanly. - Replace Thread.sleep with intercept-driven waits. Selenium has
Thread.sleep(1000)everywhere; Cypress's.shouldretry plus aliased intercepts removes them.
Cultural moves:
- Pair Selenium-experts with Cypress-curious engineers. The Selenium people know the existing scenarios; Cypress newcomers bring fresh test-design eyes.
- Track migration progress visibly. A weekly chart of "specs in Selenium / specs in Cypress / parity coverage" keeps momentum and surfaces stalls.
- Don't promise feature parity. Cypress doesn't do native multi-browser at runtime, multi-tab, or some browser APIs Selenium does. Be honest about the gap.
A 500-test suite migration realistically takes 2-4 quarters with one dedicated engineer plus team participation. Faster is rarely better — it sacrifices the parallel-run validation phase.