Playwright: The Modern E2E Testing Framework That Replaced Cypress for Many Teams

Playwright runs real browsers in parallel, supports multiple tabs and origins in one test, and has a codegen recorder - here is why teams are switching from Cypress and how to get started.

Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

May 7, 2026
7 min read
Playwright: The Modern E2E Testing Framework That Replaced Cypress for Many Teams

Why Teams Switch From Cypress

One AI engineering post, weekly

LLM benchmarks, prompt techniques, and token-cost breakdowns — not another AI news roundup.

Cypress was the gold standard for E2E testing from 2018-2022. Playwright (launched by Microsoft in 2020) has since overtaken it for many teams because of four specific limitations Cypress has that Playwright does not:

  1. Multiple browsers in one test run - Playwright tests against Chromium, Firefox, and WebKit simultaneously
  2. Multiple tabs and origins - Playwright can open two tabs and test cross-tab communication
  3. No port 4000 restriction - Playwright talks to any URL, including production
  4. Faster - Playwright uses a CDP/WebSocket bridge instead of running inside the browser iframe

Installation

bash
pnpm add -D @playwright/test
npx playwright install   # installs Chromium, Firefox, WebKit
typescript
// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./e2e",
  fullyParallel: true,
  reporter: "html",
  use: {
    baseURL: "http://localhost:3000",
    trace: "on-first-retry",
  },
  projects: [
    { name: "chromium", use: { ...devices["Desktop Chrome"] } },
    { name: "firefox", use: { ...devices["Desktop Firefox"] } },
    { name: "mobile", use: { ...devices["iPhone 15"] } },
  ],
  webServer: {
    command: "pnpm dev",
    url: "http://localhost:3000",
    reuseExistingServer: !process.env.CI,
  },
});

Team workspace

Ship faster with chat, meetings, and projects in one place — Zlyqor.

Start free

Writing Tests With Role-Based Locators

Playwright prefers getByRole() locators because they test accessibility at the same time:

typescript
import { test, expect } from "@playwright/test";

test("create a task", async ({ page }) => {
  await page.goto("/projects/proj-123");

  // Prefer getByRole over CSS selectors
  await page.getByRole("button", { name: "Add Task" }).click();
  await page.getByRole("textbox", { name: "Task title" }).fill("Fix login bug");
  await page.getByRole("button", { name: "Save" }).click();

  // Assert the task appears
  await expect(page.getByText("Fix login bug")).toBeVisible();
  await expect(page.getByRole("status")).toHaveText("Task created");
});

Test Fixtures for Auth

typescript
// e2e/fixtures.ts
import { test as base } from "@playwright/test";

type Fixtures = { authenticatedPage: Page };

export const test = base.extend<Fixtures>({
  authenticatedPage: async ({ page }, use) => {
    await page.goto("/login");
    await page.getByLabel("Email").fill("test@example.com");
    await page.getByLabel("Password").fill("testpass123");
    await page.getByRole("button", { name: "Sign in" }).click();
    await page.waitForURL("/dashboard");
    await use(page);
  },
});

// In tests:
import { test } from "./fixtures";

test("view dashboard", async ({ authenticatedPage: page }) => {
  await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});

API Testing

Playwright can test your API routes directly - no browser needed:

typescript
import { test, expect } from "@playwright/test";

test("POST /api/tasks", async ({ request }) => {
  const response = await request.post("/api/tasks", {
    data: { title: "New task", projectId: "proj-123" },
    headers: { Authorization: "Bearer test-token" },
  });

  expect(response.status()).toBe(201);
  const body = await response.json();
  expect(body).toMatchObject({ title: "New task" });
});

Codegen - Record Your Tests

bash
# Open the browser and record interactions as Playwright test code
npx playwright codegen http://localhost:3000

The codegen recorder generates test code in real-time as you click through the app. It is a starting point - you will clean it up - but it dramatically speeds up writing the initial test skeleton.

Parallel Runs and CI

bash
# Run all tests in parallel
npx playwright test

# Run with UI for debugging
npx playwright test --ui

# CI: run headless with retries
CI=true npx playwright test --retries=2

References: Playwright · GitHub · VS Code extension

#playwright#e2e-testing#testing#automation#typescript

// discussion

Comments

0/4000
Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

Visionary technologist, software engineer, and machine learning specialist. Founder and CEO of Pristren, directing engineering teams that ship production-grade AI/ML pipelines, mission-critical full-stack applications, and developer tooling. Creator of Zlyqor, the unified team workspace platform. Author of 540+ technical guides and benchmark research reports on large language models, agentic workflows, Model Context Protocol (MCP), and modern web stacks.

PristrenZlyqor