Cypress runs tests inside the browser — which means no multi-tab testing, no cross-origin support, and limited browser coverage. Playwright controls browsers from outside — giving you true cross-browser testing, parallel execution, and capabilities Cypress simply can't match.
What Playwright Gives You for Free
- Cross-browser — Chromium, Firefox, WebKit (Safari) with one API
-
Auto-waiting — no
cy.wait()or flaky selectors - Multi-tab/multi-origin — test OAuth flows, popups, iframes
- Parallel execution — run tests across workers and shards
- Codegen — record your actions, generate test code
- Trace viewer — debug failures with screenshots, DOM snapshots, network logs
- API testing — test REST endpoints alongside UI
- Component testing — test React/Vue/Svelte components in isolation
Quick Start
npm init playwright@latest
This installs Playwright, creates config, and downloads browsers.
Writing Tests
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
test('user can log in', async ({ page }) => {
await page.goto('/login');
await page.fill('[name=email]', 'user@example.com');
await page.fill('[name=password]', 'securepass');
await page.click('button[type=submit]');
// Auto-waits for navigation and element
await expect(page.locator('h1')).toHaveText('Dashboard');
await expect(page).toHaveURL('/dashboard');
});
Auto-Waiting (No More Flaky Tests)
// Cypress: need explicit waits
cy.get('.button').should('be.visible').click();
cy.wait(1000); // 😬
// Playwright: auto-waits until actionable
await page.click('.button'); // Waits for visible, enabled, stable
await expect(page.locator('.result')).toBeVisible(); // Retries until true
Playwright automatically waits for elements to be visible, enabled, and stable before interacting.
Multi-Tab and Cross-Origin Testing
test('OAuth login flow', async ({ page, context }) => {
await page.goto('/login');
// Click opens OAuth popup in new tab
const [popup] = await Promise.all([
context.waitForEvent('page'),
page.click('#google-login')
]);
// Interact with the popup (different origin!)
await popup.fill('#email', 'user@gmail.com');
await popup.click('#next');
await popup.fill('#password', 'pass');
await popup.click('#submit');
// Back to original page — user is logged in
await expect(page.locator('.user-name')).toHaveText('User');
});
Cypress cannot do this — it's limited to a single origin.
API Testing (Built-In)
test('API: create and verify user', async ({ request }) => {
// Create user via API
const response = await request.post('/api/users', {
data: { name: 'Alice', email: 'alice@test.com' }
});
expect(response.ok()).toBeTruthy();
const user = await response.json();
expect(user.name).toBe('Alice');
// Verify via GET
const getResponse = await request.get(`/api/users/${user.id}`);
const fetched = await getResponse.json();
expect(fetched.email).toBe('alice@test.com');
});
Codegen (Record Tests Visually)
npx playwright codegen https://myapp.com
Opens a browser — click around your app, and Playwright generates test code in real-time.
Trace Viewer (Debug Failures Like a Time Machine)
npx playwright test --trace on
npx playwright show-trace trace.zip
The trace viewer shows: screenshots at each step, DOM snapshot, network requests, console logs — step through your test like a debugger.
Playwright vs Cypress
| Feature | Playwright | Cypress |
|---|---|---|
| Browsers | Chromium, Firefox, WebKit | Chromium, Firefox (no Safari) |
| Multi-tab | Yes | No |
| Cross-origin | Yes | Limited |
| Parallel | Built-in workers/shards | Paid (Cypress Cloud) |
| Auto-waiting | Intelligent | Basic |
| API testing | Built-in | Plugin |
| Mobile emulation | Built-in | No |
| Speed | Faster (parallel) | Slower (single process) |
| Language | TS, JS, Python, Java, C# | JS/TS only |
The Verdict
Playwright is the modern standard for E2E testing. Cross-browser, multi-tab, parallel, with debugging tools that make failures easy to diagnose. If you're starting new E2E tests in 2026, there's no reason to choose Cypress.
Need help building production web scrapers or data pipelines? I build custom solutions. Reach out: spinov001@gmail.com
Check out my awesome-web-scraping collection — 400+ tools for extracting web data.
Top comments (0)