Migrating from Selenium to Playwright


If you're familiar with the testing landscape, you're probably already familiar with Selenium and Playwright's popularity as testing libraries. Selenium does have it's advantages but we typically recommend Playwright to our users.

In this article we'll look at:

  • Why Playwright is so much faster
  • Advantages of migrating
  • How each one handles waiting
  • Header control differences
  • Considerations before migrating
  • Key differences to understand
  • Step-by-step conversion process
  • Mapping popular methods
  • Managing browsers without Selenium Grid

By the end you will understand the fundamental differences in approaches between the two libraries, and how to approach converting the code.

Reasons for Playwright's Speed

  1. Browser Contexts and Pages: Playwright uses browser contexts, a lightweight version of browser profiles. This allows for fast and isolated parallel test execution within a single browser instance. In contrast, Selenium often requires launching a new browser instance for each test, which is more resource-intensive and slower.
  2. Native Automation Capabilities: Playwright interacts with browsers using a more native approach. It communicates directly with browser APIs and protocols (like the Chrome DevTools Protocol) which tend to be faster than the WebDriver protocol used by Selenium.
  3. Handling of Modern Web Applications: Playwright is designed to handle modern web applications that use complex JavaScript frameworks and asynchronous operations more efficiently. It provides better handling for AJAX and single-page applications (SPAs).
  4. Built-in Waits: Playwright has automatic waiting for elements to be ready before performing actions. This reduces the need for explicit waits and sleep commands, which are commonly used in Selenium to avoid flaky tests but can slow down test execution.

Advantages of Migrating from Selenium to Playwright

  1. Improved Performance and Efficiency: Faster test execution and more efficient resource utilization can significantly speed up the development and testing cycle.
  2. Enhanced Features: Playwright supports multiple browser engines (Chromium, Firefox, and WebKit), allowing tests to run on all major browsers with the same API. It also supports headless mode for all browsers, which is efficient for continuous integration environments.
  3. Better Handling of Modern Web Technologies: If your application relies heavily on modern JavaScript frameworks or complex front-end technologies, Playwright might provide a more robust testing solution.
  4. Simplified Test Scripts: Playwright’s API is designed to be more user-friendly and straightforward, potentially leading to simpler and more maintainable test scripts.
  5. Advanced Features: Features like network interception, geolocation testing, and mobile emulation are more readily available and easier to use in Playwright.

Managing browsers without Selenium Grid

Selenium Grid is a powerful tool for running scripts across multiple browser instances.

Experimental options exist to let Playwright run on Selenium Grid, but we would recommend using Browserless instead.

Browserless offers a pool of managed browsers, that you can connect to directly with a wsEndpoint. We take care of all the hassle of deploying browsers, such as tidying up abandoned processes, handling concurrencies and keeping up with version updates. All you then have to do is host the scripts.

Differences in waiting for selectors when migrating from Selenium to Playwright

How does each Library wait for selectors to be available? The way Selenium and Playwright handle waiting for selectors or elements to be visible or ready for interaction is a key difference between the two frameworks. This aspect significantly influences how automated tests are written and their reliability.

Waiting with Selenium

  1. Implicit Wait: This is a global setting where Selenium waits for a specified amount of time before throwing an exception if it cannot find an element. However, this can lead to longer test times as it waits for elements even when they are available sooner.
  2. Explicit Wait: These are specific conditions that you define for a particular element. For instance, you can wait for the visibility of an element, for the element to be clickable, or for a specific condition to be met. This requires writing additional code for each wait condition.
  3. Fluent Wait: This is a type of explicit wait that allows more flexibility. You can define the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Additionally, you can ignore specific types of exceptions while waiting.

In Selenium, handling dynamic content, AJAX-loaded elements, or elements that undergo several state changes can be challenging and often requires a combination of different wait strategies.

Waiting with Playwright

Playwright, on the other hand, has a more streamlined approach to waiting for elements:

  1. Auto-Waiting: Playwright automatically waits for elements to be in a state that's ready for interaction before performing actions. This includes being visible, attached to the DOM, and stable (not moving or changing).
  2. State Assertions: Playwright allows you to wait for elements to reach a certain state (visible, hidden, enabled, etc.) without writing additional code for each condition. This is integrated into the actions themselves.
  3. Smart Locators: Playwright locators are capable of auto-waiting for the elements they reference to be available. This reduces the amount of boilerplate code and makes scripts more concise and easier to maintain.
  4. Handling of Asynchronous Operations: Playwright's approach to auto-waiting is particularly effective for modern web applications where elements might load asynchronously or depend on JavaScript execution.

Impact on Test Writing and Reliability

  • Selenium: Writing tests in Selenium often requires a good understanding of the different wait conditions and how to apply them effectively. This can make test scripts longer and more complex. Inadequate waiting strategies can lead to flaky tests, where tests fail intermittently due to timing issues.
  • Playwright: Playwright's auto-waiting reduces the need for complex wait-related code, making test scripts more straightforward and less prone to errors related to timing and element visibility.

Playwright's auto-waiting capabilities offer a more robust and efficient way to handle dynamic and asynchronously loaded content compared to Selenium's more manual and explicit wait strategies. This difference can lead to more reliable, maintainable, and concise test scripts when using Playwright.

Network manipulation and Header control comparison

The handling of headers, particularly when dealing with proxies and authentication, is indeed an area where Selenium and Playwright differ. This difference stems from their underlying architectures and the way they interact with browsers

Selenium and Header Limitations

  • Limited Manipulation of Network Traffic: Selenium primarily interacts with web pages through the WebDriver protocol, which limits its ability to manipulate network traffic, including headers. Selenium doesn't natively support modifying network requests or responses, which is essential for tasks like setting custom headers or interacting with proxies that require authentication via headers.
  • Proxy Authentication Challenges: When it comes to authenticating proxies, Selenium typically relies on browser capabilities or system settings for proxy configurations. However, it lacks the ability to authenticate proxies using custom headers. This is a significant limitation when dealing with certain types of secure proxies or testing scenarios that require header manipulation.
  • Workarounds: To overcome these limitations, testers often have to rely on external tools or browser extensions, which can be cumbersome and less reliable. This adds complexity to test setups and can limit the scope of what can be tested effectively with Selenium.

Playwright and Advanced Header Control

  • Advanced Network Interception and Modification: Playwright provides more granular control over network interactions. It allows for intercepting and modifying network requests and responses. This capability includes altering headers before they are sent to the server or after they are received from the server.
  • Authenticating Proxies via Headers: Playwright's advanced network manipulation capabilities enable setting custom headers, including authentication headers for proxies. This makes it more suitable for testing applications behind authenticated proxies or in environments where header manipulation is essential for testing.
  • Built-in Support for Different Scenarios: Playwright's API includes built-in methods for handling different network scenarios, including setting headers, which simplifies the process and reduces the need for external tools or complex configurations.

Impact on Testing Capabilities

  • Selenium may be more challenging to use in scenarios requiring detailed manipulation of network traffic, especially when it involves header modifications for proxy authentication or similar purposes. The limitations might necessitate additional tools or setups.
  • Playwright, with its more advanced network handling capabilities, is better suited for testing environments where manipulating headers, including for proxy authentication, is critical. This makes Playwright a more versatile tool for modern web application testing, especially in complex network scenarios.

The ability to manipulate network headers, particularly for authenticating proxies, is a clear advantage of Playwright over Selenium. Playwright's architecture and API design provide more flexibility and control in this area, making it a more suitable choice for testing in environments where such capabilities are essential.

Considerations Before Migrating from Selenium to Playwright

  • Learning Curve: Teams familiar with Selenium will need to invest time in learning Playwright and adapting to its API and concepts.
  • Codebase Overhaul: Existing Selenium scripts would need to be rewritten for Playwright, which can be a significant effort depending on the size of the test suite.
  • Compatibility and Integration: Ensure that Playwright integrates well with your current tech stack and CI/CD pipeline.

Migrating from Selenium to Playwright could be beneficial for projects that require faster test execution, are heavily reliant on modern web technologies, or could benefit from the advanced features Playwright offers. However, it's important to weigh the benefits against the investment required for migration and the learning curve involved.

You're migrating from Selenium to Playwright, but where to start?

Converting Selenium scripts into Playwright scripts involves several steps, as the two frameworks have different syntax and architectural approaches.

While there are AI converters such as the ones from Rayrun and The Python Code, it is best to always thoroughly check the output. That means you need to understand the differences, the process and common mappings.

Understanding Key Differences

  1. Syntax and API Differences: Familiarize yourself with Playwright's API and syntax, which differ significantly from Selenium's. Playwright offers a more streamlined and modern approach to browser automation.
  2. Async/Await Pattern: Playwright uses JavaScript promises extensively, and its API is asynchronous. This means you'll often use the async/await pattern in your scripts.
  3. Browser Contexts and Pages: Understand how Playwright uses browser contexts and pages, which is different from how Selenium handles browser windows and tabs.
  4. Selector Engine: Playwright has a powerful selector engine that supports text selectors, CSS selectors, and XPath, and can handle dynamic content more efficiently.

Step-by-Step Conversion Process

  1. Set Up Playwright: Install Playwright and set up your environment. Ensure you have Node.js installed, as Playwright is a Node.js library.
  2. Create a Basic Playwright Script: Start by writing a simple Playwright script to open a browser, navigate to a page, and perform basic actions. This will help you get familiar with the basic structure and commands.
  3. Map Selenium Commands to Playwright: Identify the Selenium commands in your scripts and find their Playwright equivalents. For instance, translating Selenium's findElement to Playwright's page.locator, we've shared a few below to help you get an idea of the most basic ones.
  4. Handle Waits and Asynchrony: Adjust your scripts to handle Playwright’s automatic waiting and the async nature of its API. Replace explicit waits from Selenium with Playwright's auto-wait features.
  5. Implement Advanced Features: If your Selenium scripts use advanced features like handling iframes, file uploads, or downloads, learn how Playwright handles these scenarios.
  6. Run and Debug: Run your Playwright scripts and debug any issues. Pay special attention to timing issues or element selectors that might behave differently in Playwright.
Mapping Selenium commands to Playwright

For a detailed method-by-method comparison, please refer to the complete documentation of both Selenium and Playwright. This would allow you to align specific methods from Selenium with their counterparts in Playwright, considering the unique features and capabilities each framework offers. However, here's a table comparing the most popular methods used in both libraries so you get an idea of what changes you'll be facing when migrating from Selenium to Playwright.

Action DescriptionSelenium MethodPlaywright Method
Click on an Elementconst clickable = await driver.findElement(By.id(‘clickable’));<br>await driver.actions().<br>move({ origin: clickable }).<br>pause(1000).<br>press().<br>pause(1000).<br>sendKeys(‘abc’).<br>perform();await page.getByRole(‘button’).click();
Double Click on an ElementSimilar to Click, but use doubleClick() method in Selenium actions chain.await page.getByText(‘Item’).dblclick();
Right Click on an ElementSimilar to Click, but specify the right button in the Selenium actions chain.await page.getByText(‘Item’).click({ button: ‘right’ });
Shift Click on an ElementSimilar to Click, but add a shift key action in the Selenium actions chain.await page.getByText(‘Item’).click({ modifiers: [‘Shift’] });
Hover Over an ElementUse moveToElement() method in Selenium actions chain.await page.getByText(‘Item’).hover();
Fill Text InputUse sendKeys() method on the element found in Selenium.await page.getByRole(‘textbox’).fill(‘Peter’);
Check/Uncheck Checkboxes and Radio ButtonsUse click() method on the element in Selenium for checking. For unchecking, conditionally use click() if checked.await page.getByLabel(‘I agree to the terms above’).check();
Select Options in DropdownUse Select class in Selenium and methods like selectByVisibleText() or selectByValue().await page.getByLabel(‘Choose a color’).selectOption(‘blue’);
Type CharactersUse sendKeys() in Selenium.await page.locator(‘#area’).pressSequentially(‘Hello World!’);
Upload FilesUse sendKeys() on file input element in Selenium with the file path.await page.getByLabel(‘Upload file’).setInputFiles(path.join(__dirname, ‘myfile.pdf’));
Focus on an ElementUse WebElement‘s sendKeys(Keys.TAB) in Selenium to navigate to the element.await page.getByLabel(‘Password’).focus();
Drag and DropUse dragAndDrop() method in Selenium actions chain.await page.locator(‘#item-to-be-dragged’).dragTo(page.locator(‘#item-to-drop-at’));

Tools and Resources

  • Documentation and Guides: Leverage Playwright's official documentation and community guides. They often have sections for users migrating from other frameworks like Selenium.
  • Playwright Test Runner: If you're using a test runner with Selenium, consider using Playwright’s test runner, which is optimized for Playwright scripts.
  • Refactoring Tools: While there are no direct conversion tools, IDEs like Visual Studio Code can help refactor and debug your code efficiently.

Considerations on converting code from Selenium to Playwright

  • No Direct Conversion: Keep in mind that there's no automated way to directly convert Selenium scripts to Playwright. It requires manual effort.
  • Learning Curve: There may be a learning curve, especially around Playwright’s async nature and its different approach to browser automation.


Converting from Selenium to Playwright is a manual process that involves understanding the differences between the two frameworks, mapping commands, and adjusting to Playwright’s way of handling browser interactions. While it can be time-consuming, the benefits of Playwright’s modern approach and features might be well worth the effort for many projects.

If you want to take hosting the browsers off of your to-do list, then sign up for a 7-day trial of Browserless.

Share this article

Ready to try the benefits of Browserless?