Playwright vs Selenium: Head to Head Comparison


playwright vs selenium

In this article, we will explore some of the critical aspects of test automation by comparing two prominent tools: Selenium and Playwright.

Selenium, a widely adopted tool, has a good hold in the test automation community for years.

On the other hand, Playwright is a newer, emerging tool that promises to bring a futuristic approach to test automation.

Our focus will be on understanding the technical differences between these tools, examining how they operate under the hood. Rather than simply determining which tool is better, we aim to provide insights into their respective architectures, capabilities, and unique features.

This comparison will help you understand the strengths and potential use cases for each tool, aiding you in making an informed decision based on your specific testing needs.

We can see how the respective APIs interact with browsers and how communication happens.

Playwright

Selenium

Websocket- connection

HTTP- connection

Bi-directional

one – direction

Persistent

Request -> response

Playwright:

Playwright Architecture

Selenium:

Selenium Architecture

Playwright

Selenium

Playwright Core: With playwright core we can directly import browser modules (i.e chromium, firefox etc) and we can create browser contexts, pages and actions.

In Selenium, the WebDriver API uses browser-specific drivers (e.g., ChromeDriver for Chrome, GeckoDriver for Firefox). The WebDriver interacts with the browser driver through the HTTP protocol, launching and managing a browser instance. This process requires setting up and configuring the correct driver for the desired browser.

Use browser contexts to provide isolated sessions within the same browser instance.

Typically uses separate browser instances to achieve session isolation.

Faster and more resource efficient when creating new sessions.

Slower and more resource intensive when launching new sessions.

Simple and streamlined API for managing contexts.

More complex setup for managing multiple isolated sessions.

@playwright/test’: Second and easy approach is to use the ‘@playwright/test’ package. This package wraps the playwright core.
It provides a test runner and include ‘tests and assertions’ out of the box.

TestNG’ is a testing framework for Java that provides functionalities similar to those of @playwright/test. This also supports fixtures[annotations], parallelisation, assertions, test configurations. The thing is the setup and integration is little bit complex when compared to Playwright.

Playwright:

First approach:

const { chromium } = require('playwright');

(async () => {
    // Launch a new browser instance
    const browser = await chromium.launch({ headless: false });

    // Create a new browser context
    const context = await browser.newContext();

    // Open a new page/tab
    const page = await context.newPage();

    await page.goto('https://www.example.com');
    await page.click('selector');
    await browser.close();
})();

Second approach:

const { test, expect } = require('@playwright/test');

test.describe('My Test Suite', () => {

    test('Basic Navigation Test', async ({ page }) => {

              //here we can directly goto the url, sending the 'page' as an argument
               await page.goto('https://www.example.com');
               await expect(page).toHaveTitle('Example Domain');
               await page.click('selector');
               await page.fill('input#search', 'Playwright');

            });
});

Selenium:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumExample {
    public static void main(String[] args) {
        // Set the path to the browser driver
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");

        // Instantiate a WebDriver (ChromeDriver in this case)
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.example.com");
        driver.findElement(By.id("element_id")).click();
        driver.quit();
    }
}

Here we can see how the tools ensure that the browser and page elements are in the expected state before performing further actions or assertions

Playwright

Selenium

Automatic waits

Yes, Playwright automatically waits for elements to be ready before performing actions

No, requires explicit wait statements to handle readiness

Assertions with auto waiting

Built-in, Playwright assertions automatically wait for the conditions to be met

Requires explicit waits or custom conditions to handle timing issues

Explicit waiting

Supports explicit waits using methods like waitForSelectorwaitForEvent

Supports explicit waits using WebDriverWait and ExpectedConditions

Timeout configuration

Configurable at multiple levels (e.g., per action, per test, globally)

Configurable via setScriptTimeoutsetPageLoadTimeout, and implicitlyWait

  • In Playwright, automatic waits are built into the framework to help manage the synchronization of actions with the state of the webpage

  • Playwright automatically waits for elements to be ready before performing actions like clicking, typing, or asserting

  • Assertions with auto-waiting are a powerful feature that helps ensure your tests are robust and reliable. These assertions automatically retry until the expected condition is met or a timeout is reached

// Navigate to a page and wait for it to load
  await page.goto('http://example.com');
  // Wait for an element to be visible and click it
  await page.click('button#submit');
//assertion with auto wait
await expect(page.locator('h1')).toHaveText('Example Domain');
//explicit or manual wait
await page.waitForTimeout(3000); // Wait for 3 seconds

Implicit Wait:

  • Applies to all elements in the WebDriver instance. Once set, it will be used for the lifetime of the WebDriver object.

  • It’s used to instruct the WebDriver to wait for a certain period when trying to locate an element before throwing a NoSuchElementException.

    Explicit Wait:

  • Applies only to the specific element(s) and condition(s) for which it is set. It needs to be specified each time for each condition.

  • It’s used to wait for a specific condition to occur before proceeding further in the code execution. Commonly used conditions include element visibility, element clickability, and presence of an element.

WebDriver driver = new ChromeDriver();

        // Implicit wait
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.get("https://example.com");
//Explicit wait
        WebDriverWait wait = new WebDriverWait(driver, 10);
        WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element_id")));

Playwright

Selenium

Chromium, Firefox, Webkit

Chrome, Safari, Edge, Firefox, Internet Explorer, Opera

Supports mobile view ports

Supports mobile view ports

Supports headed and headless modes

Supports headed and headless mode

Not very much suitable for cross-browser testing

Highly suitable for cross-browser testing

Playwright can run your tests in multiple browsers and configurations by setting up projects in the config.

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    /* Test against desktop browsers */
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
    /* Test against mobile viewports. */
    {
      name: 'Mobile Chrome',
      use: { ...devices['Pixel 5'] },
    },
    {
name: 'Mobile Safari',
      use: { ...devices['iPhone 12'] },
    },
    /* Test against branded browsers. */
    {
      name: 'Google Chrome',
      use: { ...devices['Desktop Chrome'], channel: 'chrome' }, // or 'chrome-beta'
    },
    {
      name: 'Microsoft Edge',
      use: { ...devices['Desktop Edge'], channel: 'msedge' }, // or 'msedge-dev'
    },
  ],
});

Launching different browsers using the respective webDrivers.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ChromeTest {
    public static void main(String[] args) {
        // Set the path to the ChromeDriver executable
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");

        // Initialize the ChromeDriver
        WebDriver driver = new ChromeDriver();

        // Navigate to a website
        driver.get("https://www.example.com");

        // Perform actions
        // ...

        // Close the browser
        driver.quit();
    }
}
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class FirefoxTest {
    public static void main(String[] args) {
        // Set the path to the GeckoDriver executable
        System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");

        // Initialize the FirefoxDriver
        WebDriver driver = new FirefoxDriver();

        // Navigate to a website
        driver.get("https://www.example.com");

        // Perform actions
        // ...

        // Close the browser
        driver.quit();
    }
}

Playwright

Selenium

Automatic test sharding across workers

Manual configuration needed

Automatically balances load across workers

Requires custom setup in Grid

Playwright:

-By default, Playwright runs test files in parallel
-In order to achieve even greater parallelization, you can further scale Playwright test execution by running tests on multiple machines simultaneously. We call this mode of operation “sharding”

playwright parallel

playwright.dev/docs/test-sharding#sharding-..

image4

Selenium:

In Selenium, test sharding is typically achieved through various strategies depending on the testing framework and setup you are using:

TestNG:

<suite name="Suite" parallel="methods" thread-count="4">
  <test name="Test">
    <classes>
      <class name="com.example.YourTestClass"/>
    </classes>
  </test>
</suite>

Selenium Grid:’

{
  "capabilities": [
    {
      "browserName": "chrome",
      "maxInstances": 5
    },
    {
      "browserName": "firefox",
      "maxInstances": 5
    }
  ],
  "maxSession": 10
}

Types of testing supported

                Playwright

                    Selenium

Web UI testing

Web UI testing

API testing 

In built not supported

Visual Regression

NA

Accessibility testing

NA

Load Testing- K6 integration

Load Testing- Jmeter integration

Component Testing [Experimental phase]

Similar to JUnit, Mockito

Supporting languages

                    Playwright

                  Selenium

Javascript/Typescript

Java

Python

C#

C#

Python

Java

Ruby, Kotlin

Performance: Selenium vs Playwright

        Playwright

Selenium

startup time

Playwright is designed to be fast. It launches browsers in a headless mode by default, which reduces the startup time significantly.

Selenium tends to have a longer startup time, especially when using Selenium Grid to distribute tests across multiple machine

parallel Execution

Playwright supports parallel test execution out-of-the-box with minimal configuration, enabling faster test runs

Selenium supports parallel execution through frameworks like TestNG and JUnit, and through Selenium Grid. However, setting up and managing Selenium Grid can be complex and time-consuming

Flakiness

Less flaky

Moderately Flaky

Dependencies

Playwright

Selenium


Browser libraries

Built-in (playwright install handles browser installation)

Separate downloads required (ChromeDriver, GeckoDriver, etc.)

Testing Framework

Playwright/test (built-in testing framework) 

TestNG, PyTest, Appium

Shared/Cloud Environment

Microsoft Playwright Testing

Selenium Grid

Community support

                  Playwright

                Selenium

Upcoming tool, moderately available

Highly available, used by many people

And finally both Playwright and Selenium offer compelling advantages. Playwright, with its modern architecture and native support for multiple browsers contexts, waiting, reporting, debugging etc represents a robust solution for engineers looking for speed and simplicity in managing concurrent tests across various environments.

Selenium, on the other hand, stands as the time-tested giant with extensive browser support and a vast community, making it a versatile choice for complex, long-term projects.

Source: This blog was originally published at testgrid.io

Comments

Popular posts from this blog

How to Inspect Elements on Discord

A Guide to Android Emulators for Chromebook

Top Generative AI-Based Testing Tools in the Market