Skip to content
Test Automation Frameworks: Selenium vs Cypress vs Playwright Compared

Test Automation Frameworks: Selenium vs Cypress vs Playwright Compared

DodaTech Updated Jun 20, 2026 8 min read

Test automation frameworks provide the structure, libraries, and tools needed to write, organize, and run automated tests — from browser-based UI tests to API tests — in a consistent, maintainable way across environments.

What You’ll Learn

  • How Selenium, Cypress, and Playwright compare (architecture, speed, reliability)
  • When to choose each framework for your project
  • How to integrate automated tests into CI/CD pipelines
  • Best practices for writing maintainable test automation
  • Common test automation pitfalls and solutions

Why Test Automation Matters

Manual testing doesn’t scale. As your application grows, the number of regression tests grows exponentially. Automated tests run in minutes what would take days of manual testing, and they run consistently — no fatigue, no skipped steps, no “it worked on my machine.” Companies with strong test automation deploy 200x more frequently than those without (DORA State of DevOps).

Doda Browser uses automated visual regression testing across all platforms — a UI change that shifts a button by 2 pixels on one OS shouldn’t go unnoticed.

Learning Path

    flowchart LR
  A[Unit Testing] --> B[Integration Testing]
  B --> C[Test Automation<br/>You are here]
  C --> D[CI/CD Pipeline]
  D --> E[Production Monitoring]
  style C fill:#f90,color:#fff
  

Framework Comparison

FeatureSelenium WebDriverCypressPlaywright
ArchitectureBrowser drivers via WebDriver protocolIn-process, runs in browserBrowser-specific protocols (CDP)
LanguageJava, Python, JS, C#, RubyJavaScript/TypeScriptJavaScript/TypeScript, Python, Java, .NET
Browser supportChrome, Firefox, Safari, EdgeChrome-family onlyChrome, Firefox, Safari, Edge
SpeedModerateFastFastest
Network controlLimitedStub/SpyRoute interception, mock APIs
Auto-waitingManual waits requiredAutomaticAutomatic
IFrame supportYesLimitedYes
Mobile testingAppium integrationLimitedMobile Safari/Chrome
DebuggingScreenshots, logsTime-travel, videoTraces, video, screenshots
CommunityLargestLarge, growingLarge, very active

Selenium WebDriver

The veteran framework, supporting multiple browsers and languages.

Setup

npm install selenium-webdriver
# Download ChromeDriver matching your Chrome version

Example

const { Builder, By, until } = require('selenium-webdriver');

async function example() {
  const driver = await new Builder().forBrowser('chrome').build();

  try {
    await driver.get('https://example.com/login');

    // Find and interact with elements
    await driver.findElement(By.id('email')).sendKeys('user@example.com');
    await driver.findElement(By.id('password')).sendKeys('secret123');

    // Wait for element and click
    await driver.wait(
      until.elementIsVisible(driver.findElement(By.css('button[type="submit"]'))),
      5000
    );
    await driver.findElement(By.css('button[type="submit"]')).click();

    // Wait for navigation
    await driver.wait(until.urlContains('/dashboard'), 5000);
    console.log('Login successful!');
  } finally {
    await driver.quit();
  }
}

example();

When to Use Selenium

  • Need to test across multiple browsers (including Safari, legacy IE)
  • Team uses Java, C#, or Python for tests
  • Need mobile testing via Appium
  • Existing investment in Selenium infrastructure

Cypress

Modern, developer-friendly framework with real-time reloading and time-travel debugging.

Setup

npm install cypress --save-dev
npx cypress open

Example

// cypress/e2e/login.cy.js
describe('Login', () => {
  beforeEach(() => {
    cy.visit('https://example.com/login');
  });

  it('logs in successfully', () => {
    cy.get('#email').type('user@example.com');
    cy.get('#password').type('secret123');
    cy.get('button[type="submit"]').click();
    cy.url().should('include', '/dashboard');
    cy.get('.welcome').should('contain', 'Welcome back');
  });

  it('shows error for invalid credentials', () => {
    cy.get('#email').type('wrong@example.com');
    cy.get('#password').type('wrongpass');
    cy.get('button[type="submit"]').click();
    cy.get('.error-message').should('be.visible');
  });

  it('validates empty fields', () => {
    cy.get('button[type="submit"]').click();
    cy.get('#email:invalid').should('exist');
  });
});

When to Use Cypress

  • Frontend-focused team already using JavaScript
  • Need fast, reliable tests for Chrome-based browsers
  • Want time-travel debugging and automatic waiting
  • Testing modern SPAs (React, Vue, Angular)

Playwright

The newest framework, built by Microsoft, offering the fastest execution and broadest features.

Setup

npm install @playwright/test
npx playwright install

Example

// tests/login.spec.js
const { test, expect } = require('@playwright/test');

test.describe('Login', () => {
  test('logs in successfully', async ({ page }) => {
    await page.goto('https://example.com/login');
    await page.fill('#email', 'user@example.com');
    await page.fill('#password', 'secret123');
    await page.click('button[type="submit"]');
    await expect(page).toHaveURL(/\/dashboard/);
    await expect(page.locator('.welcome')).toHaveText('Welcome back');
  });

  test('handles network failure gracefully', async ({ page }) => {
    // Intercept and block login API
    await page.route('**/api/login', route => route.abort());

    await page.goto('/login');
    await page.fill('#email', 'user@example.com');
    await page.fill('#password', 'secret123');
    await page.click('button[type="submit"]');
    await expect(page.locator('.error')).toContainText('Network error');
  });

  test('mobile responsive layout', async ({ page }) => {
    // Test on mobile viewport
    await page.setViewportSize({ width: 375, height: 812 });
    await page.goto('/login');
    await expect(page.locator('.form-container')).toBeVisible();
    // Verify mobile layout
    const box = await page.locator('.form-container').boundingBox();
    expect(box.width).toBeLessThan(400);
  });
});

When to Use Playwright

  • Need the fastest test execution
  • Testing across Chromium, Firefox, and WebKit
  • Need network interception and API mocking
  • Want built-in mobile viewport testing
  • Building new test infrastructure from scratch

CI/CD Integration

# .github/workflows/test.yml — Playwright example
name: E2E Tests
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    services:
      app:
        image: myapp:latest
        ports:
          - 3000:3000

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install dependencies
        run: npm ci
      - name: Install Playwright
        run: npx playwright install --with-deps
      - name: Run tests
        run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 7

Parallel Execution

# Playwright — run across 4 workers
npx playwright test --workers=4

# Cypress — run in parallel (paid plan)
npx cypress run --parallel

# Selenium — Grid mode
java -jar selenium-server.jar hub
java -jar selenium-server.jar node --hub http://localhost:4444

Choosing the Right Framework

Decision Matrix

If you need…Choose…
Cross-browser testing (all major browsers)Playwright or Selenium
Fast feedback in developmentCypress or Playwright
Mobile web testingPlaywright (mobile viewports) or Appium
Multiple programming languagesSelenium (Java, Python, C#, Ruby, JS)
API + UI testing in one frameworkPlaywright (built-in API testing)
Enterprise with existing Java/SeleniumKeep Selenium, consider adding Playwright

Migration Path

Moving from Selenium to Playwright:

// Selenium style
driver.findElement(By.id("email")).sendKeys("user@example.com");

// Playwright equivalent
page.fill("#email", "user@example.com");
// or
page.locator("#email").fill("user@example.com");

Common Test Automation Mistakes

1. Flaky Tests

Tests that pass sometimes and fail sometimes destroy trust in the suite.

Fix: Use automatic waiting (Playwright, Cypress auto-wait). Remove time.sleep() and fixed waits. Fix race conditions.

2. Testing Through the UI When Not Needed

Every UI test is slower and more brittle than an API or unit test.

Fix: Follow the test pyramid. Test business logic at the unit level, interactions at the integration level, and only critical journeys at the UI level.

3. No Page Object Model

Tests with duplicated selectors and navigation logic are hard to maintain.

// BAD: selectors duplicated across tests
test('login', async ({ page }) => {
  await page.fill('#email', 'user@example.com');
  await page.fill('#password', 'secret123');
  await page.click('button[type="submit"]');
});

// GOOD: Page Object Model
class LoginPage {
  constructor(page) {
    this.page = page;
    this.emailInput = page.locator('#email');
    this.passwordInput = page.locator('#password');
    this.submitButton = page.locator('button[type="submit"]');
  }

  async login(email, password) {
    await this.emailInput.fill(email);
    await this.passwordInput.fill(password);
    await this.submitButton.click();
  }
}

test('login', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.login('user@example.com', 'secret123');
});

4. Over-reliance on End-to-End Tests

Hundreds of E2E tests are slow and flaky. The test pyramid applies to automation too.

Fix: 10 well-chosen E2E tests are worth more than 100 fragile ones.

5. Not Running Tests in CI

Tests that only run on a developer’s machine don’t protect the codebase.

Fix: Every PR must run the test suite. Block merging on test failures.

6. Testing in Production

Automated tests that run against production risk corrupting data and alerting users.

Fix: Use staging or dedicated test environments. If you must test in production, use read-only operations and isolated test accounts.

7. No Reporting or Debugging

Tests that fail without screenshots, logs, or traces are hard to diagnose.

Fix: Enable video recording, screenshot on failure, and detailed logging in all test frameworks.

Practice Questions

1. What are the three main browser automation frameworks compared in this tutorial?

Selenium WebDriver, Cypress, and Playwright.

2. What is the architectural difference between Selenium and Playwright?

Selenium uses the WebDriver protocol through browser-specific drivers. Playwright uses browser-native protocols (Chrome DevTools Protocol for Chromium) directly, making it faster and more reliable.

3. When would you choose Cypress over Playwright?

When you need time-travel debugging, automatic waiting, and are testing Chrome-based browsers only. Cypress is great for frontend-focused JavaScript teams.

4. What is the Page Object Model and why is it important?

A design pattern where each page or component has a class encapsulating its selectors and interaction methods. It reduces duplication and makes tests more maintainable.

5. How do you handle flaky tests in CI?

Use automatic waiting instead of fixed delays, isolate tests (no shared state), retry flaky tests with a limit, and investigate root causes immediately.

Challenge: Take an existing Selenium test suite and migrate one critical test to Playwright. Compare execution time, reliability, and code readability. Document the differences.

FAQ

Should I use one framework for all testing?
Ideally, yes — using one framework reduces context switching and simplifies infrastructure. Playwright is the strongest candidate for a single framework.
Can I combine Selenium and Playwright?
You can, but it adds complexity. If you’re starting fresh, pick one. If migrating from Selenium, move gradually by framework or by test category.
Which framework is fastest?
Playwright is generally fastest because it uses browser-native protocols and parallel execution out of the box.
Do I need a separate API testing tool?
Playwright includes built-in API testing via request context. For simple API testing, you don’t need a separate tool.
How do I test mobile browsers?
Playwright has built-in mobile viewport emulation. For real device testing, use BrowserStack or Sauce Labs with any framework.

What’s Next

TutorialWhat You’ll Learn
Continuous Testing in CI/CDIntegrating tests into the delivery pipeline
Playwright Testing GuideDeep dive into Playwright features
Cypress Testing GuideDeep dive into Cypress features

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-20.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro