The site had exactly one test for most of its life: a GitHub Action step that ran astro build and checked the exit code. If the build didn’t crash, I shipped. This caught typos in frontmatter and not much else — a broken layout, a missing alt attribute, a link that silently 404s, none of that fails a build.
Where I started
I picked Playwright mostly because it could drive a real browser without much setup, and because I’d used it once at a previous job and remembered liking the trace viewer. The first test I wrote was almost insultingly simple:
test('home page loads and has a heading', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
});
That one test caught nothing on its first ten runs. Then I refactored the header component and it caught a missing <h1> within a minute of me breaking it, which is the exact moment a test suite goes from “thing I wrote because I should” to “thing I trust.”
What I added after that
Once the first test proved its worth, adding more felt less like a chore:
- A smoke test that visits every route generated from content collections, not just the ones I remember exist.
- A check that every internal link on the home page resolves to a 200, run against the built output.
- An axe-core scan on the article template, which is where most real accessibility bugs on this site have actually lived.
The part that surprised me
The axe-core scan found a contrast failure in a badge component within the first run — a coral background with white text that looked fine to me on my monitor and failed WCAG AA by a hair. I’d looked at that badge probably fifty times while building it. The test looked at it once and caught what I couldn’t see, which is a good one-sentence argument for why this suite exists at all: not to catch the bugs I’d notice eventually, but the ones I structurally can’t, because I already know what the page is supposed to look like.