Playwright vs Selenium vs Cypress + Framework Architecture

Playwright, Selenium and Cypress all automate browsers, but they're built differently — and those differences decide how fast, stable and flexible your suite will be. This page compares them honestly (including where Selenium and Cypress are the better choice), shows the same test written in all three, and ends with the six-layer Playwright framework architecture interviewers ask you to explain.

Advertisement

At a Glance

Aspect Selenium Playwright Cypress
How it talks to the browser W3C WebDriver protocol via a driver per browser (plus BiDi in Selenium 4) Direct protocol connection to browsers it ships and patches Runs inside the browser alongside your app
Languages Java, Python, C#, JavaScript, Ruby, Kotlin JavaScript/TypeScript, Python, Java, .NET JavaScript/TypeScript
Waiting Explicit waits you write Auto-waiting built into actions and assertions Automatic retries built in
Browsers Chrome, Firefox, Edge, Safari (real browsers) Chromium, Firefox, WebKit (Safari's engine, not Safari itself) Chrome family, Firefox, Edge; WebKit experimental
Tabs / multiple windows Yes Yes — pages and contexts Limited — one tab
Parallel runs Via TestNG/JUnit and Selenium Grid Built into the test runner Paid cloud feature or third-party tools
Built-in extras Minimal — you add runner, reports Test runner, trace viewer, API testing, network mocking Runner, time-travel debugging, network stubbing
Mobile Real devices via Appium Device emulation only Viewport emulation only
Best known for Language choice, real browsers, huge ecosystem Speed, stability, modern web apps Developer experience for front-end teams

The Same Test in All Three

Log in as a locked-out user on SauceDemo and check the error.

Selenium (Java + TestNG)

@Test
public void lockedOutUserSeesError() {
    WebDriver driver = new ChromeDriver();
    try {
        driver.get("https://www.saucedemo.com/");
        driver.findElement(By.id("user-name")).sendKeys("locked_out_user");
        driver.findElement(By.id("password")).sendKeys("secret_sauce");
        driver.findElement(By.id("login-button")).click();

        String error = new WebDriverWait(driver, Duration.ofSeconds(10))
                .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[data-test='error']")))
                .getText();
        Assert.assertTrue(error.contains("locked out"));
    } finally {
        driver.quit();
    }
}

Playwright (TypeScript)

import { test, expect } from '@playwright/test';

test('locked-out user sees an error', async ({ page }) => {
  await page.goto('https://www.saucedemo.com/');
  await page.locator('#user-name').fill('locked_out_user');
  await page.locator('#password').fill('secret_sauce');
  await page.locator('#login-button').click();
  await expect(page.locator('[data-test="error"]')).toContainText('locked out');
});

Cypress (JavaScript)

describe('login', () => {
  it('locked-out user sees an error', () => {
    cy.visit('https://www.saucedemo.com/');
    cy.get('#user-name').type('locked_out_user');
    cy.get('#password').type('secret_sauce');
    cy.get('#login-button').click();
    cy.get('[data-test="error"]').should('contain', 'locked out');
  });
});

Notice what's missing from the Playwright and Cypress versions: an explicit wait and browser clean-up. Playwright's expect(...).toContainText() retries until the text appears, and the runner manages the browser for you. Convert your own snippets between the three in the Selenium ⇄ Playwright ⇄ Cypress Translator.

Playwright vs Selenium

Interview answer: "Both automate browsers, but Selenium drives them through the WebDriver protocol and relies on explicit waits I write, while Playwright connects to the browser directly and auto-waits for elements to be ready. Playwright also ships a test runner with parallelism, tracing and API testing built in. Selenium's strengths are language choice, real branded browsers including Safari, a huge ecosystem and Appium for mobile — which is why many enterprises still run large Selenium suites."

When Selenium is still the better fit

  • A large, working Selenium suite — rewriting it rarely pays off quickly.
  • Teams that work in Java, C#, Python or Ruby and want the widest language and library support.
  • Testing on real branded browsers (for example real Safari) or through cloud grids already in place.
  • Mobile testing alongside web through Appium, using the same WebDriver skills.

Detailed comparison: Selenium vs Playwright.

Playwright vs Cypress

Analogy: Cypress is a security guard inside the building — it sees everything happening in its own building very clearly, but can't easily follow someone into a second building (another tab or domain). Playwright is a controller outside the building, able to open and watch several buildings at once.

Interview answer: "Cypress runs inside the browser alongside the application, which gives it an excellent debugging experience, but it's JavaScript-only and limited with multiple tabs and cross-origin flows. Playwright controls the browser from outside, so it handles multiple pages, contexts and origins, supports several languages, and parallelises for free."

When Cypress is a good choice

  • Front-end JavaScript teams who want tests next to the application code.
  • Single-origin web apps without multi-tab flows.
  • Teams that value Cypress's interactive runner and component testing.

Why Many Teams Choose Playwright

  • Auto-waiting removes most synchronisation code — the biggest source of flaky UI tests.
  • Isolated browser contexts make parallel tests fast and independent.
  • Trace viewer shows every step, DOM snapshot and network call of a failed CI run.
  • API testing and network mocking in the same tool.
  • Three browser engines from one install.

Playwright's Limitations

  • No Internet Explorer and no real branded Safari — WebKit is close, not identical.
  • No native mobile apps — emulation only; use Appium for real devices.
  • A younger ecosystem than Selenium, with fewer third-party integrations in some enterprises.
  • Large parallel runs need CPU and memory; plan your CI agents accordingly.

Interview answer: "Playwright isn't the right choice when you need legacy browsers, real Safari or native mobile apps, or when a large, stable Selenium suite already covers the product — the tool should follow the project's requirements, not popularity."

Designing a Playwright Framework: Six Layers

Layer Contains Rule
1. Tests tests/*.spec.ts — scenarios and assertions No locators or raw page calls
2. Page objects pages/*.ts — locators and user actions UI changes are fixed only here
3. Fixtures Custom fixtures that create page objects, logged-in states and data Setup lives here, not in tests
4. Test data JSON files and data builders No hard-coded values in tests
5. Utilities API helpers, date/random helpers Reusable and stateless
6. Configuration and reports playwright.config.ts (baseURL, projects, retries, reporters), traces, screenshots, HTML report Environments switch through config, not code
// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';

export class LoginPage {
  readonly username: Locator;
  readonly password: Locator;
  readonly submit: Locator;
  readonly error: Locator;

  constructor(private readonly page: Page) {
    this.username = page.locator('#user-name');
    this.password = page.locator('#password');
    this.submit = page.locator('#login-button');
    this.error = page.locator('[data-test="error"]');
  }

  async login(user: string, pass: string) {
    await this.username.fill(user);
    await this.password.fill(pass);
    await this.submit.click();
  }
}

Why POM? "It separates UI details from test logic, so a changed locator is fixed in one place, tests read like user journeys, and new modules only need a new page class and tests." To log in once and reuse the session across tests, see Playwright Storage State.

The "Biggest Challenge" Answer

  • Challenge: flaky failures from dynamic content and slow API responses — tests clicked elements that were visible but not yet updated.
  • Action: replaced manual timeouts with web-first assertions (toBeVisible, toHaveText), waited on specific network responses where needed, used role- and test-id-based locators, and reviewed traces for every CI failure.
  • Result: a stable suite — give your real numbers, such as "retries dropped from 12% of runs to under 1%".

From Real Projects

I've built my automation skills on Selenium with Java and TestNG, and that background maps well onto Playwright: page classes become page objects, TestNG groups and parallel runs become projects and workers, and explicit waits become auto-waiting and web-first assertions. If you're coming from Selenium too, focus on those differences first. Testing Testsigma — a platform where users write automated tests in plain English — meant thinking like its users, who are testers themselves. Understanding how each tool talks to the browser explains most of their differences.

📚 Official documentation: Playwright documentation · Cypress documentation

FAQs

What is the difference between Playwright and Selenium?

Selenium uses the WebDriver protocol and explicit waits and supports many languages and real browsers; Playwright connects directly to its bundled browsers, auto-waits, and includes a runner with parallelism, tracing and API testing.

What is the difference between Playwright and Cypress?

Cypress runs inside the browser, is JavaScript-only and limited with multiple tabs and origins; Playwright controls browsers externally, supports several languages, multiple pages and contexts, and free parallel runs.

Is Selenium outdated?

No. It remains the standard for multi-language teams, real-browser coverage and mobile via Appium, and Selenium 4 added BiDi and Selenium Manager. Playwright is often faster to write and more stable for modern web apps.

What are Playwright's limitations?

No Internet Explorer, WebKit instead of real Safari, no native mobile apps, and resource-heavy large parallel runs.

How is a Playwright framework structured?

Tests, page objects, fixtures, test data, utilities, and configuration with reports — with setup in fixtures and environments in playwright.config.ts.