Keeping Code Clean: Linting, Hooks, and Long-Term Governance

In the previous post, we got a large suite running fast in CI. This is the last post in the series, and it covers something that matters more the longer a framework lives. Keeping it healthy after the initial build is done. A framework that looks clean on day one can turn into a mess after six months of multiple people adding tests under deadline pressure. Inconsistent formatting, selectors that break constantly, tests nobody trusts anymore. None of this is really a Playwright problem. It is a team habits problem, and it is solvable with the right tooling in place from early on. ...

April 27, 2024

Maximizing Speed: Worker Optimization and CI Sharding

In the previous post, we got our suite running automatically in GitHub Actions. That works fine when you have thirty tests. It starts to feel slow once you have three hundred. Today we look at getting that feedback loop back down to something reasonable. There are two separate levers here, and it is worth understanding the difference. Workers control how many tests run at once on a single machine. Sharding controls splitting the whole suite across multiple separate machines entirely. You usually want both. ...

April 18, 2024

Automating Quality: Running Playwright in GitHub Actions

In the previous post, we set up reporting and traces so failures are easy to diagnose. None of that matters much if tests only run on your own laptop. Today we wire everything into a CI pipeline, so every pull request gets tested automatically before it can be merged. We will use GitHub Actions here, since it is what most teams already have available, and Playwright has solid first party support for it. ...

April 9, 2024

Debugging with Confidence: Traces, Screenshots, and HTML Reports

In the previous post, we sped up tests by mixing in API calls. Today we cover something every team hits eventually. A test fails overnight in CI, nobody was watching it run, and now someone has to figure out why. This used to mean staring at a stack trace and a screenshot, if you were lucky enough to have a screenshot at all, and guessing at what the page must have looked like. Playwright gives you a lot more to work with than that, and it is worth setting all of it up before you actually need it. ...

March 31, 2024

Speeding Up Execution: Combining API Setup with UI Validation

In the previous post, we looked at why Playwright tests do not need manual sleeps. Today we look at a different kind of speed problem. Tests that spend most of their time on setup steps that have nothing to do with what they are actually testing. Say you are testing the checkout flow. To get there, a real user has to log in, search for a product, add it to the cart, and then go to checkout. If every single checkout test drives all of that through the UI first, you are spending most of your test run clicking through steps you already tested thoroughly somewhere else. That adds up fast across a whole suite. ...

March 22, 2024

Eliminating Flakiness: Auto-Waiting and Web-First Assertions

In the previous post, we used fixtures to clean up test setup. Today we talk about the thing that probably causes more wasted engineering hours than anything else in test automation. Flakiness. If you have worked with older browser automation tools, you know the pattern. A test fails intermittently. Someone adds sleep(2000) right before the failing step. The test passes for a while. Then it starts failing again on a slower CI runner, so someone bumps it to sleep(5000). Now your test suite takes twenty minutes longer to run and it is still not fully reliable. ...

March 13, 2024

Supercharging Tests with Native Playwright Fixtures

In the previous post, we sorted out static and dynamic test data. This time we tackle something that quietly bloats a lot of test suites. Setup code. If you have written more than a handful of Playwright tests, you have probably written a beforeEach block that logs a user in, or sets up a page object, or seeds some starting state. Do that across twenty spec files and you end up with the same boilerplate copied everywhere, and a small change to the login flow means touching every single file. ...

March 4, 2024

Decoupling Data: Managing Test Inputs and Dynamic States

In the previous post, we cleaned up how our tests interact with the UI using the Page Object Model. This time we look at a different kind of mess. Test data. Here is a scenario that plays out on almost every team at some point. Two tests both try to register a new account using the email test@example.com. Run them one at a time and everything is fine. Run them at the same time in a parallel CI job, and one of them fails because the account already exists. Nobody touched the test code. The problem is the data. ...

February 23, 2024

Scaling Maintenance: Implementing the Page Object Model (POM)

In the previous post, we scaffolded a Playwright project and set up a folder structure with an empty pages/ directory sitting there waiting to be used. Today we fill it in properly. Here is a problem I see all the time. A test file has ten tests in it. Every single one of them repeats the same selector for the login button. Then the front end team renames a CSS class, and suddenly all ten tests break at once. You end up doing a find and replace across a dozen files just to fix one small UI change. ...

February 14, 2024

Laying the Foundation: Architecture and Setup for a Playwright Project

Every solid test automation framework starts the same way. You pick a clean folder structure. You get your config right once, early, before you have hundreds of tests depending on it. Playwright makes this part refreshingly easy. TypeScript support is built in from day one. You do not need to bolt on extra plugins or wrestle with a transpiler. This post walks through setting up a Playwright project the way I would actually set one up for a real team. Not a toy demo. Something that can grow to hundreds of tests without turning into a mess. ...

February 5, 2024