Web automation with Playwright

Sumalatha Elliadka
TestVagrant
Published in
6 min readMar 15, 2021

The playwright is an open-source web automation library that is built on top of Puppeteer. It is developed by the authors of Puppeteer and maintained by Microsoft. In this article, let’s look into a web-framework developed using Playwright, Playwright-test and Typescript and explore its capabilities.

Why Playwright

Most of us have worked on web automation at some point of time in our career. The common challenges we face while automating are slowness of test execution, unreliable wait scenarios, the need to write a lot of boiler-plate code for browser setup, and parallel execution, etc. The playwright tries to address these issues and makes test authoring more readable, fast and reliable. Let’s see how we can achieve this in the following sections.

Installation: One of the why factor of using Playwright is, it’s easy to setup! Once you execute the line of code shown below, Playwright downloads binaries for all 3 supported browsers. With a single command, the setup is ready for web-automation!

Browser, Context and Page: Playwright works on the principle of 3 main core concepts: Browser, Context and Page.

  • Browser: First thing we need to run tests is to launch a browser. The playwright does this using the object of Browser class which is nothing but an instance of either Chromium, Firefox or Webkit.
  • Context: Playwright achieves parallelization through browser contexts. In the playwright’s term “Browser Context is an isolated incognito-alike session within a browser instance”.
  • A page is a new tab or pop-up window within a context. Every action on the test will be performed on this object.

Cross-browser support: Playwright supports the most commonly used 3 browser engines: Chromium, Firefox and Webkit. So, tests can be written once and can be executed across all browsers with no or minimal configuration.

Let’s look into the script section of package.json. This uses the playwright’s test-runner.

When line# 7 gets executed, all tests in your suites by default run in all 3 browsers. Of course, it is possible to run in a specific browser.

If Jest is used as a runner then browser information can be set as part of jest-playwright.config.js as shown below to run tests across all browsers.

jest-playwright.config.js

Auto-waiting and reliable execution: One of the advantages of using Playwright is that it auto-waits for UI elements to be available before acting. This makes the test authoring simple and avoids the extra steps of adding explicit waits. For example, let’s look into the POM class below and understand how it works.

When line#16 is executed, the playwright performs checks to see whether the selector is enabled to receive events, whether it’s stable, visible and attached to DOM. After all, these checks are passed, only then it performs a click action on the selector. If wait fails after default timeout of 30 secs, then timeout error will be thrown by the playwright.

It is possible that when a page contains some animation condition or dynamic contents, there is a need to wait for the set amount of time. WaitForTimeout can be used under such scenarios.

Custom waits: For scenarios like lazy page loading, the playwright provides custom wait where tests can wait for a selector to be available. Similarly, it is possible to wait until certain network conditions are met.

Authentication: Authentication is a common feature in web frameworks. Playwright allows to login once and stores the session details, cookies inside a context as shown below. Once this is stored it can be used across all tests within that context and prevents the need for multiple logins. This code has to be part of setup files(in the case of Jest) / test fixtures(in the case of playwright-test runner) so that it can be applied across context objects.

Selectors: Apart from common selectors like id, XPath, CSS, class name etc. supported by other frameworks like Selenium, Playwright can rely on more resilient selectors like text content, accessibility labels to locate elements. Here is an example of locating element using data-test-id.

Playwright Test Runner

The playwright can be easily integrated with JavaScript test runners like Jest, Ava and Mocha. In this blog let’s look at the playwright’s own test runner Playwright-test.

Playwright-test is built, based on the test framework folio and provides inbuilt support for Typescript. It uses expect for assertions and provides spec functions “it, describe etc” for automating tests.

Installation:

Default Arguments: As discussed earlier, the playwright needs page, context, browser objects to author tests. Playwright-test runner takes care of initializing and creating these objects either with default values or based on the configurations provided and make them available for all tests across the project.

Fixtures: Playwright-test runner inherited the concept of test fixtures from Folio. Fixtures are the setup that is required for a test to run. It could be an environment, a state or preconditions. There are 2 types of fixtures supported by the test runner.

  • Test fixtures: These are the setup or conditions that apply to every test.
  • Worker fixtures: Folio uses the concept of workers which are nothing but a process to run each test file. It is possible to apply the fixtures at the process level as well.

Below is a sample scenario of where we can apply authentication per worker process. Please note where the scope is specified as a worker. If nothing is specified, then the default scope applies to all tests. Let us save the file as fixtures.ts

  • Once fixtures are created they can be used inside tests as shown below
  • It’s important to note that once fixtures are defined and built, the test functions “it, describe before each” has to be used from the object that’s being built. It’s not possible to use multiple fixtures inside the same test file.
  • More detailed information on various types of configurations can be found here

CLI to run the tests: Since the playwright’s test runner uses Folio in the background, the command to execute tests requires folio as well. By default, it will allocate one worker process per file and runs all files in parallel. Tests within the file are executed sequentially.

  • browserName: When there is a need to run tests in a specific browser, then this parameter can be passed with the browser name.
  • headFul: If set to true, it will run the tests by opening the browsers. For CI, it is recommended to set it to false. Also running in headless mode executes the tests faster.
  • screenshotOnFaiure: If a test is failed then the screenshot will be stored under test-results
  • reporter: If specified it can generate XML style reporting similar to JUnit

Continuous Integration

The playwright provides a docker image and can be easily integrated as part of CI. Here is a sample `.gilab-ci.yml` for integration with Gitlab.

Conclusion

The playwright is an amazing framework to explore and is just a year old when this blog is written. Since it’s inception it has evolved a lot and has a growing community of users. It’s a node.js library and built for a highly reactive modern web application, which makes tests written using this framework, faster, capable and reliable. It was a great experience to explore this tool and good learning!

Here is the code link which touches upon the concepts explained in this blog.

Thanks to Nishant Sharma who worked with me on Playwright!

Resources:

  1. https://github.com/microsoft/playwright
  2. https://github.com/microsoft/playwright-test
  3. https://github.com/microsoft/folio

Thanks for Reading !!!

--

--