Framework review: Playwright

Photo by Fatih Kฤฑlฤฑรง on Unsplash

Playwright enables end-to-end testing. Test modern single page apps, across all modern browsers, using in your preferred language (JS, TS, Java, C#, Python).

โ€” Official website


Example of automation at GitHub.

Use cases ๐Ÿฅˆ

Automate end-to-end (E2E) tests using the UI. It also supports mocks.

Learning curve ๐Ÿฅˆ

Most test frameworks behave similarly, so for me it’s just a matter of learning their syntax. The official doc was not sufficient to get started, so while I was coding I had the reference API by my side. When I was not sure how to do something, I simply enabled the “record mode” and let Playwright generate the test code of my actions.

Language ๐Ÿฅ‡

Lots of flexibility, as you can choose from five languages to write your tests (personally, I picked JavaScript and VS Code). Since the API is very low level, more than basic knowledge is required to code and understand the tests.

Ecosystem ๐Ÿ˜ญ

My IDE autocomplete was limited. You can debug your test code using breakpoints in VS Codeโ€ฆ but you need multiple watches, as you can’t evaluate expressions. Part of Playwright’s pitch is cross-browser testing. Indeed it’s super easy to enable it but super flaky to use. In my case, Firefox was (mostly) fine, Chrome returned page errors (which I had to ignore) and Safari was 3x slower (when it didn’t fail straight away) โ€“ both issues were false positives.

Readability ๐Ÿ˜ญ

Verbose and an eyesore. A simple assertion takes three lines — thankfully expect-playwright reduces it to one. Something concise and intuitive in Cypress (page.get.first) is obscure in Playwright (page.$$). The test code reads like back-end code, with async and await keywords on every line. Sometimes you need to explicitly wait for page loads (are we back to the Selenium days?).

Extensibility ๐Ÿฅ‰

You can run tests with its own runner, Playwright Test, or you can use Jest — developers will be familiar with its syntax and the test results report in the CLI is a lot better. It supports the PageObject Model.

Maintainability ๐Ÿฅ‰

Hard to debug. When the toHaveText() assertion fails, it outputs the whole page HTML in the error log, which is a nightmare to review. Slower than expected, if the tests ran in parallel I didn’t even notice it.

Documentation ๐Ÿฅˆ

I started with the official doc and an online course. It’s the typical, “it works and looks fine” until you try a real world scenario. I had to follow community guides to unblock myself. There’s also some official tutorials. On the bright side, the doc is complete and easy to search.


I had a bad time and, given the effort, I was not proud of what I achieved.