1import * as Playwright from "@alchemy.run/cloudflare-test-tools/e2e/Playwright";
2import { expect, test } from "@playwright/test";
3
4for (const method of Playwright.SERVER_METHODS) {
5 test.describe(method, () => {
6 const it = Playwright.make(method);
7
8 it("renders the homepage", async ({ page, server }) => {
9 const response = await page.goto(server.url.toString());
10 expect(response?.status()).toBe(200);
11 await page.waitForLoadState("networkidle");
12 await page.evaluate(() => document.fonts.ready);
13
14 await expect(page).toHaveScreenshot("index.png", {
15 animations: "disabled",
16 maxDiffPixelRatio: 0.03,
17 });
18
19 expect(await page.textContent("button.counter")).toBe("Count is 0");
20 await page.click("button.counter");
21 expect(await page.textContent("button.counter")).toBe("Count is 1");
22 });
23
24 it("routes unmatched paths to the worker API route", async ({ server }) => {
25 // No static asset matches /api/hello, so the request falls through to
26 // the user worker (src/server.ts wired via `main`).
27 const body = await server.fetchJson<{ message: string; source: string }>(
28 "/api/hello",
29 );
30 expect(body).toMatchObject({ message: "Hello World", source: "worker" });
31 });
32
33 it("still serves static assets ahead of the worker", async ({ server }) => {
34 const response = await server.fetch("/favicon.svg");
35 expect(response.status).toBe(200);
36 expect(await response.text()).toContain("<svg");
37 });
38
39 it("returns the worker's 404 for unknown paths (not_found_handling: none)", async ({
40 server,
41 }) => {
42 // not_found_handling: "none" — the asset layer never falls back to a
43 // 404 page or SPA shell; the unmatched request reaches the worker,
44 // which owns the 404.
45 const response = await server.fetch("/definitely/not/a/route");
46 expect(response.status).toBe(404);
47 expect(await response.text()).toBe("Not Found");
48 });
49 });
50}