With the additional language support, as well as the ability to execute across modern browser engines Chromium, Firefox, and WebKit – this puts Playwright in the same category as Selenium WebDriver as viable testing solutions for all (not just JS) web testers who need cross-browser testing capabilities for complex applications.
Browsing the Playwright Javadocs was helpful, but I like to evaluate frameworks by actually using them to automate realistic scenarios. So in this post, I’ll share the steps of building a testing project with Playwright which includes Page Objects, and I’ll also compare the Playwright steps to their equivalents in Selenium WebDriver.
How to Install Playwright Java
The first step in getting started with Playwright is adding the dependency to your project. You can get the Playwright client from Maven Repository. I created a new pom.xml file and added the playwright dependency.
Like Selenium WebDriver, Playwright is a browser automation tool and not necessarily limited to a testing framework. In fact, neither of them provide any assertion methods. Therefore, you’ll need to add an assertion library as well. For this example, I’ll use TestNG.
How to Launch Browser in Playwright
The Playwright interface allows you to create specific types of Browser objects. The options are Chromium which is what Chrome and Edge are built upon, Firefox, and WebKit (the engine Safari is built upon). With this Browser object, a launch() method is available which will start a browser instance.
By default, Playwright launches the browser in headless mode, which means you won’t actually see the tests execute. If you want to see the browser open, you can disable headless mode by passing in a LaunchOption.
In addition to setting the headless mode, LaunchOptions provide several other methods including ones to set environment variables and open Chromium dev tools.
How to Launch a Website in Playwright
Now that we have a browser, we can load the application under test – Automation Bookstore. To do so, we need a Page object – which is similar to the WebDriver objects in Selenium. To create the Page object, we call browser.newPage() on line 8. This represents a single tab within the browser window. With this object, we can then navigate to our URL (line 9).
How to Create a Page Object in Playwright
We have our application loaded in the browser, and now we’d like to use the Page Object Model design pattern to create a Java class that represents the Search page of our application.
In order to interact with the web elements, the Page Object class will need access to the Playwright Page object we created above. Again, this is comparable to how we pass the Selenium WebDriver object to Page Object classes so that they can perform browser interaction methods.
I created that SearchPage class and the constructor that accepts the Page object.
The first method I’ll add to this class is search() which will take in text and enter it into a text field. The method to do this is fill(), which takes a locator and the text you’d like entered into the field. You can see the call on line 11.
The element locator for the search field is defined as a String. This is true for all locators used in Playwright; unlike Selenium which uses the By class to allow you to express locators as id, name, XPath, css selector, link text, etc. However, Playwright offers a variety of options to express the locators so all of the ones in Selenium are covered, plus extra flexibility for more expressive locators such as conditions of the elements, chaining, and even access to shadow DOM elements!
Playwright has auto-waiting for elements that you are directly interacting with. Selenium WebDriver often gets a bad rap for things that are out of its control, for example the need to wait for a desired state of the application. In my particular application, there is a slight delay between the time I enter the search query and the time that the results are filtered. Since the search results element is a different element than the one I used the automation tool to interact with (search field), I have to account for this wait in my code, and it doesn’t matter if I use Selenium, Cypress, or Playwright – this remains true.
So here, after entering text into the field, I need to ask Playwright to wait until there are hidden books attached to the DOM. This is shown on lines 4-5.
To demonstrate the DETACHED selector option, I’ll also make a clear() method. In this method, I clear the text field by sending an empty String, then wait for the hidden books element to be detached from the DOM.
How to Get Elements in Playwright
Playwright provides the querySelector() mehod which returns a single element as an ElementHandle object. This is equivalent to Selenium’s WebElement object obtained by findElement(). To get multiple elements that match the locator, Playwright provides querySelectorAll() and this will return a list of elements: List<ElementHandle>.
This is demonstrated in our Page Object class as we get the number of visible books.
Here I use the innerText() method to get the titles of the visible books on line 4.
Now that all of the heavy lifting has been done in the BaseTests and Page Object classes, the tests look exactly like they would if written in Selenium.
There’s Much More
What I’ve demonstrated here is how to use Playwright for some of the most common everyday tasks, however the API boasts a lot more! It can capture screenshots, mock geolocation, emulate mobile device settings, intercept network calls, and much more. It already contains a lot of the features that make Selenium 4 more modern. While Playwright is still very new, it looks extremely promising and I’m definitely keeping my eye on it.