End-to-End Tests with Playwright
Component tests mount a tag in a fake DOM. That catches a great deal and misses one whole category: whether your app works. Real server, real HTML over the wire, real hydration, real browser. That’s end-to-end, and Playwright is how it’s done.
The config wires the two together. playwright.config.cts has a
webServer block: Playwright starts your dev server, waits for the URL to
answer, runs the tests against it, and tears it down. No manual “start the
server first” step, in your terminal or in CI.
Two layers, and the difference matters. request.get("/") fetches the
raw HTML the server sent — no browser, no JavaScript. If your text is in
there, server rendering works, and that’s what a search engine and a slow
phone see first. page.goto("/") then loads the same page in a real
browser and clicks it. If that works, hydration works. Marko’s whole
pitch is that the first layer is fast and the second is small; these are
the two tests that hold it to it.
The spec also gates on console errors — collect them, assert the array is empty. A hydration mismatch usually announces itself there and nowhere else. It’s a pattern worth stealing for every app you write.
-
Open the terminal and run
npx playwright test --list. Two tests. -
Add a third that checks the button already says Count is 4 before anything is clicked:
test("starts at four", async ({ page }) => {await page.goto("/");await expect(page.getByRole("button")).toHaveText(/Count is 4/);}); -
Run
--listagain. Three tests. Playwright parsed your config and your spec, resolved every test, and told you so.
To actually run them: hit the download button at the top of this page.
You get the whole project as a real folder. Then npm install, npx playwright install — that fetches the browsers, a few hundred megabytes,
which is exactly why they aren’t here — and npx playwright test. The same
spec, green, in three real browsers.
You should now see three tests listed. Next: the tools that catch these mistakes before you run anything at all.
- Installing dependencies
- Starting dev server