1import * as Playwright from "@alchemy.run/cloudflare-test-tools/e2e/Playwright";
2import { expect, test } from "@playwright/test";
3
4// Specs written against the INTENDED custom-worker-entry behavior (see
5// README): the deployed worker is the user's src/worker-entry.ts, which
6// wraps waku's fetch handler and exports the Counter SQLite DO.
7for (const mode of Playwright.SERVER_METHODS) {
8 test.describe(mode, () => {
9 const it = Playwright.make(mode);
10
11 it("SSR renders the page through the wrapped waku handler", async ({
12 page,
13 server,
14 }) => {
15 const response = await page.goto(server.url.toString());
16 expect(response?.status()).toBe(200);
17 await expect(page.getByTestId("page-marker")).toHaveText("PAGE_MARKER");
18 await expect(page.getByTestId("env-message")).toHaveText(
19 "MESSAGE=hello-from-waku-do-binding",
20 );
21 // The page reads the DO at request time: any non-negative count proves
22 // the COUNTER namespace resolved against the user entry's Counter class.
23 await expect(page.getByTestId("do-count")).toHaveText(/COUNT=\d+/);
24 });
25
26 it("increments the Counter DO across requests via the API route", async ({
27 server,
28 }) => {
29 // Plain HTTP fetch (not `server.fetch`): the live-mode dispatchFetch
30 // wrapper drops RequestInit, losing the POST method. Both modes listen
31 // on a real socket.
32 const post = async (): Promise<number> => {
33 const response = await fetch(new URL("/counter", server.url), {
34 method: "POST",
35 });
36 expect(response.status).toBe(200);
37 const body = (await response.json()) as { count: number };
38 return body.count;
39 };
40
41 const first = await post();
42 const second = await post();
43 // Relative assertion: DO storage may persist across runs locally.
44 expect(second).toBe(first + 1);
45
46 // GET observes the state written by the POSTs — same DO instance.
47 const read = await fetch(new URL("/counter", server.url));
48 expect(read.status).toBe(200);
49 expect(((await read.json()) as { count: number }).count).toBe(second);
50 });
51
52 it("serves the static asset alongside the custom entry", async ({
53 server,
54 }) => {
55 const response = await server.fetch("/hello.txt");
56 expect(response.status).toBe(200);
57 expect(await response.text()).toContain("hello from public/");
58 });
59 });
60}