top of page

Adding Playwright to a Selenium Automation Framework

Writer: Sevdanur GENC
Sevdanur GENC
Oct 3
7 min read

A practical guide to integration usage and better browser tests



A mature Selenium framework represents years of work: reusable workflows, test data, reporting, CI pipelines, and knowledge about the application. Adding Playwright can extend that investment. The most practical starting point is to introduce it as a second browser automation engine and move selected tests gradually.

This article explains what Playwright offers, how to fit it into an existing framework, and which habits make the integration maintainable. The examples use Java, but the architecture applies to Selenium frameworks in other languages. Integration requires adaptation; there is no universal plugin that converts every Selenium suite automatically.

What Playwright brings to browser automation

Playwright automates Chromium, Firefox, and WebKit and provides APIs for Java, JavaScript and TypeScript, Python, and .NET. Its locators, automatic action checks, browser contexts, and debugging tools make it useful for modern web applications. Mobile emulation is useful for responsive web testing; it does not replace testing a native mobile app or a real device. [1]

A Browser represents the running browser. A BrowserContext is an isolated session inside it. A Page represents a tab or popup. Understanding these three objects makes both test isolation and cleanup much easier.

Keep the framework around the engine

Treat browser automation as one layer. Your framework can continue deciding which tests run, supplying data, collecting results, and publishing reports. A Playwright implementation then handles browser actions for the tests assigned to it.

Start with a small, representative flow such as sign in, search, and sign out. Measure reliability, execution time, debugging effort, and maintenance before expanding. Faster tests are a possible outcome, not a guarantee.


Screenshot 1  Official Codegen example emulating an iPhone viewport. Web emulation does not replace native app testing. Source [2].


 

How to integrate Playwright into an existing framework

First, identify where browser calls live. A framework with centralized page objects or keywords is easier to extend than one that exposes WebDriver throughout every test. Where direct calls are scattered, isolate one workflow first rather than redesigning the whole suite at once.


1  Choose an integration boundary

Use separate Playwright test classes for the quickest pilot. For a longer term hybrid framework, add an engine selector such as engine=selenium or engine=playwright. Select the engine per test or suite and keep each scenario on one engine.


2  Reuse the surrounding services

Keep environment settings, Excel or CSV readers, database helpers, test identifiers, and report generation when they have no WebDriver dependency. In a BDD framework, step definitions can delegate to the selected implementation. In a keyword framework, the dispatcher can route supported keywords to the selected engine.


3  Adapt browser behavior explicitly

A Selenium WebElement is not a Playwright Locator. Window handles are not Page objects. Rewrite browser dependent page objects, waits, frame handling, downloads, and assertions. Some CSS and XPath selectors can be reused, but validate their behavior and uniqueness.


4  Define lifecycle and reporting hooks

Create an isolated context for each Playwright test. Before cleanup, collect failure evidence and finalize traces. Send the result and artifact paths to the existing report. Include the engine and browser so failures can be investigated correctly.


5  Add the engine to CI

Install the browser binaries and required operating system dependencies on agents. Pin the library version and use matching browser installations. Confirm proxy, certificate, and download access before relying on an unattended run.

Avoid a shared abstraction that merely renames click and type while exposing every engine detail underneath it. Define a small contract around the capabilities your tests need, with clear handling for unsupported actions. Use separate implementations when the behavior differs materially.

 

A small Java example

Add the com.microsoft.playwright:playwright Maven dependency alongside Selenium. Pin a release validated for your environment. The official installation page currently illustrates version 1.63.0; check its operating system requirements as well as its Java requirements. [1]


<dependency>  <groupId>com.microsoft.playwright</groupId>  <artifactId>playwright</artifactId>  <version>1.63.0</version> </dependency>


From the Maven project folder, install Chromium using Playwright’s Java CLI. Linux CI agents may also need the install --with-deps command. Keep this setup step separate from your test logic.


mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI  -Dexec.args="install chromium"


The command above is wrapped for readability; enter it on one line. The following Java method shows the browser layer for a simple search flow. Replace the example application’s labels and expected text with your application’s contract. It is illustrative code, not a test executed against a live application.


import com.microsoft.playwright.*;

import com.microsoft.playwright.options.AriaRole;

import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;


public class SearchFlow { 

public static void verifySearch(String baseUrl, String query) {   

try (Playwright pw = Playwright.create()) {

      Browser browser = pw.chromium().launch();     

try {       

BrowserContext context = browser.newContext();       

try {         

Page page = context.newPage();         

page.navigate(baseUrl);         

page.getByLabel("Search").fill(query);      

page.getByRole(AriaRole.BUTTON,             

new Page.GetByRoleOptions().setName("Search")

.setExact(true)).click();         

assertThat(page.getByTestId("results"))  

            .containsText(query);       

} finally {         

context.close();       

}     

} finally {       

browser.close();     

}   

} 

}

}


Call this flow from your runner, page object, or keyword implementation. For Java, retain JUnit or TestNG lifecycle hooks and reporting. The Node.js Playwright Test runner’s fixtures, configuration, retries, and built in HTML reporting do not automatically become part of a Java framework. [7]

 

Use recording to accelerate the first draft

Playwright Codegen opens a browser and an Inspector window. As you interact with the application, it generates actions and locators. Use it to explore a workflow, discover selectors, and establish a starting point. It can also record visibility, text, and value assertions. [2]


mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI  -Dexec.args="codegen https://your-test-application.example"


Screenshot 2  Official Playwright documentation example of Codegen at a fixed desktop viewport. Source [2].


Before committing generated code, replace literal data with parameters, move repeated workflows into reusable methods, and add assertions that express the business outcome. Review the locator choices and remove recorded passwords or tokens.

For keyword driven frameworks, translate the recording into generic operations such as FILL_FIELD, CLICK_BUTTON, and VERIFY_TEXT. Keep labels, values, and expected results as parameters. Define exactly what VERIFY_TEXT means: exact text, contained text, or a visible match within a specified region.

 

Tips that improve reliability

Use locators that explain intent

Prefer roles with accessible names, labels for inputs, and agreed test IDs. Scope locators to the relevant form, dialog, or row when names repeat. A strict locator error can reveal an ambiguity worth fixing. Using first() just to silence it may select the wrong element. [4]


Wait for the outcome that matters

Playwright checks conditions such as visibility, stability, and whether an element can receive events before a click. That does not prove a business operation has completed. Follow actions with retrying assertions on the expected result, URL, or application state. Avoid fixed sleeps, blanket timeout increases, and routine forced clicks. [3]


Capture events around the triggering action

Register a popup or download wait before triggering the action. The callback pattern avoids missing an event that happens quickly. Switch to the returned Page explicitly and assert its expected content.


Page popup = page.waitForPopup(() ->   

page.getByText("Open report",       

newPage.GetByTextOptions().setExact(true)).click());

assertThat(popup.getByRole(AriaRole.HEADING,   

new Page.GetByRoleOptions().setName("Report").setExact(true)))   

.isVisible();


Isolate state and control parallelism

Use a new context for each test and independent data for tests that change application state. In Java, Playwright objects are not thread safe. A straightforward parallel design gives each worker its own Playwright instance and uses its objects on that worker’s thread. Increase worker counts only after checking agent capacity and application limits. [7, 8]


Make diagnostics part of the framework

Use a headed browser and slow motion while investigating locally. In CI, save screenshots on failure and retain traces according to a deliberate policy. Artifact collection should preserve the original exception, including when a browser crash prevents a screenshot. Do not let retries hide a persistent defect.

Authentication reuse can reduce setup time, but saved state may contain credentials or session tokens. Keep it out of source control, use controlled test accounts, and refresh it when sessions expire. [2]

 

Screenshots traces and responsive testing

A screenshot answers what the page looked like at one moment. A trace helps explain the sequence: actions, DOM snapshots, logs, source locations, and network activity. Start context tracing before the flow and stop it to save a ZIP before closing the context. Link that artifact from the existing report. [5]


context.tracing().start(new Tracing.StartOptions()   

.setScreenshots(true).setSnapshots(true).setSources(true));

// Execute the flow. Export in teardown before context.close().

context.tracing().stop(new Tracing.StopOptions()

.setPath(java.nio.file.Paths.get("artifacts/trace.zip")));



Screenshot 3  Official Playwright Trace Viewer example showing the timeline and recorded actions. Source [5].

Use unique artifact folders for each run, test, engine, and retry attempt. Create those folders first. Treat traces and screenshots as potentially sensitive: they can expose page content and network data. Review artifacts before publishing them with a blog or sharing outside the team.


Check more than one viewport

Include a desktop viewport and a smaller responsive viewport in the pilot. Emulation helps reveal layout changes that make a menu, checkbox, or button behave differently. Keep assertions focused on the same user outcome across layouts.

 

What about Selenium Grid

Running two engines in one framework is different from running Playwright on Selenium Grid. Playwright documents an experimental Grid integration for Selenium 4 with Google Chrome and Microsoft Edge. It connects through Chrome DevTools Protocol and has compatibility risks. It is not a general route to all browsers or a way to convert an existing WebDriver session into a Playwright test. [6]

Evaluate that option separately if existing Grid capacity is a requirement. Otherwise, start with Playwright’s own browser launch flow and keep the integration boundary in your framework.


A practical rollout

Choose a small flow, preserve the existing test identifiers and data inputs, and add Playwright behind a clear engine selection. Validate the pilot locally and on CI. Compare the engines using the same expected outcomes, and record where failures come from: the application, locator assumptions, test data, or infrastructure.

Expand when the pilot demonstrates a maintenance benefit. Keep Selenium for coverage that still needs it, and let the framework provide a consistent way to run tests and inspect results. The value of the integration is the ability to choose an engine while retaining the framework’s accumulated knowledge.


References and screenshot credits

Technical guidance checked against official Playwright documentation on October 3, 2026. Screenshots reproduced from those documentation pages; their example appearance may differ from your installed version. The code examples are illustrative and require adaptation to your application.


[1] Installation

[2] Test generator and screenshot examples

[3] Auto waiting

[4] Locators

[5] Trace Viewer and screenshot example

[6] Selenium Grid experimental integration

[7] Java test runners

[8] Java multithreading

Comments


©2026 by Sevdanur Genc

bottom of page