Testing web applications with Node.js and Playwright
Modern application development depends on automated testing, using test frameworks to ensure that code is ready to go into application packages and out to end-users. To get the most from testing, tests are written before code and can be integrated into source control and CI/CD (continuous integration/continuous deployment) pipelines. Tests should be everywhere in your development process. Need to merge a pull request? Test the code. Need to commit to a branch? Test the code.
But there’s one area where testing is hard, especially when it needs to be automated. I’m talking about the need to interact with and test dynamic user interfaces. Web application testing is a complex process. Tools such as Selenium and webdriver are key elements in automating page content and in ensuring that you’re testing both page elements and the application as a whole. They’re important if you’re using headless browsers in an application; I’ve been using a set of Python scripts in a Twitter application built around Selenium and Chromium’s webdriver support to automate taking screenshots from an aircraft tracking application.
Introducing Playwright, Microsoft’s web testing framework
Selenium and webdriver aren’t the only tools for building end-to-end tests for modern web applications and browsers. A popular alternative is Google’s Puppeteer, which handles both sending clicks to browsers using the same techniques as Chrome’s webdriver tooling and accessing debugging information via the familiar developer tools’ APIs. A newer entrant in the browser testing league, Playwright is being developed by Microsoft as an open source project hosted on GitHub.
There’s an important message in Playwright’s list of supported browsers: You can’t use it with Trident IndustryEdgeHTML-based browsers. It’s not surprising. Microsoft has made a firm commitment to its Chromium branch in its new Edge, and both the old Edge and Internet Explorer are close to end of life. If you’re going to use Playwright for testing, you’re making a decision to support only mainstream modern browsers, so you will need to inform users what’s in store for future releases of any web applications you’re building and supporting.
Testing the web with Playwright
The ability to cross-platform test on all the major browsers with the same set of scripts is important, as is support for mobile versions of sites (as the two main mobile platforms use variants of their desktop browsers Playwright currently emulates mobile views in desktop browsers). Also important is support for headless tests, where you’re not rendering a browser UI, working instead with the generated document object model (and a shadow DOM if you’re using modern browser functionality and technologies such as web components).
You can use Playwright to automate a running browser on development desktops to inspect errors as part of application debugging, ensuring that you consistently run through all your test paths while recording additional performance information and watching for untracked UI glitches. Alternatively, it can be set up as part of a GitHub action to test new code as part of a commit or a merge, automating what could otherwise be a complex manual test.
Building and running Playwright tests
The result is a very clear way of building scripts, starting with opening a headless browser instance, then navigating to a page before interacting with page instances. It’s a good idea to initially build tests with full browsers so you can follow how Playwright interacts with your application. A useful slow-mo option runs interactions at a more human speed, making to easier to visualize and manage tests running in desktop browsers. Once a test has been debugged and is running well, you can move it to headless mode and then run it as part of a CI/CD implementation.
Working with web applications in Playwright
One of Playwright’s more helpful features is its support for browser contexts. These allow you to run isolated actions in a single browser instance, so you can set up several contexts to test several interactions at the same time. Inside each context you create pages, which are best thought of as tabs in a desktop browser. Pages support their own click interactions and can be monitored in parallel. Once you’re in a page you can use different ways of finding content to interact with, using CSS or XPath selectors, HTML attributes, or text. If you’re familiar with Selenium you should find navigating through pages familiar, with the added ability to wait for a page to fully load or for dynamic content to be rendered in a single-page web application.
There’s a lot in Playwright, and it makes a compelling alternative to Selenium for testing browser applications. With Microsoft continually adding to the F12 developer tools in Edge, it’ll be interesting to watch Playwright add new features that expand your options for testing browser-hosted applications and progressive web apps alongside traditional web applications.
Playwright includes language bindings for C#, so you can bring Playwright into existing test frameworks for ASP.NET or other .NET tools. You shouldn’t have to change the way you work to bring in new tools, and Microsoft is promising additional language bindings for Java and Ruby. There’s the prospect of more in the future, as the Playwright documentation states that it is designed to support bindings for any language. With all the code on GitHub, there’s the opportunity to create your own bindings for your test language of choice and submit them as a pull request to the project.