Files
FolderGameChallenge/e2e/app.spec.ts
jimmy 104d6a1d46 feat(play): debug retry step, folder hints, and e2e coverage
- Add buildFsAtSubStart so dev "Retry step" resets the current sub while keeping earlier subs complete; quiz screen clears the selected answer.

- Stop adding hinted files' parent folders to click hints (avoids wrongly highlighting Downloads when already inside it).

- Extend Playwright: localStorage reset, full playthrough through quiz, and a retry-step regression test. Add Vitest for buildFsAtSubStart.

Made-with: Cursor
2026-04-11 19:26:39 +12:00

111 lines
4.3 KiB
TypeScript

import { expect, test } from "@playwright/test";
const SAVE_KEY = "folder-game-challenge:v1";
test.describe("browser", () => {
test.beforeEach(async ({ page }) => {
await page.addInitScript((key) => {
localStorage.removeItem(key);
}, SAVE_KEY);
});
test("home page shows title", async ({ page }) => {
await page.goto("/");
await expect(
page.getByRole("heading", { name: "Folder Game Challenge" }),
).toBeVisible();
});
test("play page loads", async ({ page }) => {
await page.goto("/play");
await expect(page.getByText("Messy desktop")).toBeVisible({
timeout: 15_000,
});
});
test("debug retry step resets current sub without losing prior progress", async ({
page,
}) => {
await page.goto("/play");
await expect(page.getByText("Messy desktop")).toBeVisible({
timeout: 15_000,
});
await page.getByRole("button", { name: "Games" }).first().click();
await page.getByRole("button", { name: "Back" }).click();
await page.getByRole("button", { name: "Documents" }).first().click();
await page.getByRole("button", { name: "Next level" }).click();
await expect(page.getByText(/Drag cat\.png/)).toBeVisible();
await page.getByRole("button", { name: /cat\.png/ }).dragTo(
page.locator("aside").getByRole("button", { name: "Pictures" }),
);
await expect(page.getByText(/Drag homework\.txt/)).toBeVisible();
await page.getByRole("button", { name: "Retry this step (debug)" }).click();
await page.locator("aside").getByRole("button", { name: "Pictures" }).click();
await expect(page.getByRole("button", { name: /cat\.png/ })).toBeVisible();
await expect(page.getByText(/Drag homework\.txt/)).toBeVisible();
});
test("full playthrough through quiz win", async ({ page }) => {
test.setTimeout(120_000);
await page.goto("/play");
await expect(page.getByText("Messy desktop")).toBeVisible({
timeout: 15_000,
});
// Level 0 — Find Documents
await expect(page.getByText(/click the Games folder/)).toBeVisible();
await page.getByRole("button", { name: "Games" }).first().click();
await page.getByRole("button", { name: "Back" }).click();
await page.getByRole("button", { name: "Documents" }).first().click();
await page.getByRole("button", { name: "Next level" }).click();
// Level 1 — Put files away
await expect(page.getByText(/Drag cat\.png/)).toBeVisible();
await page.getByRole("button", { name: /cat\.png/ }).dragTo(
page.locator("aside").getByRole("button", { name: "Pictures" }),
);
await expect(page.getByText(/Drag homework\.txt/)).toBeVisible();
await page.getByRole("button", { name: /homework\.txt/ }).dragTo(
page.locator("aside").getByRole("button", { name: "School" }),
);
await page.getByRole("button", { name: "Next level" }).click();
// Level 2 — Rescue Downloads (starts in Downloads)
await expect(page.getByText(/Drag beach\.jpg/)).toBeVisible();
await expect(page.getByRole("button", { name: /beach\.jpg/ })).toBeVisible();
await page.getByRole("button", { name: /beach\.jpg/ }).dragTo(
page.locator("aside").getByRole("button", { name: "Photos" }),
);
await expect(page.getByText(/Drag budget\.xlsx/)).toBeVisible();
await page.getByRole("button", { name: /budget\.xlsx/ }).dragTo(
page.locator("aside").getByRole("button", { name: "Work" }),
);
await expect(page.getByText(/Drag game-installer/)).toBeVisible();
await page.getByRole("button", { name: /game-installer\.msi/ }).dragTo(
page.locator("aside").getByRole("button", { name: "Installers" }),
);
await page.getByRole("button", { name: "Next level" }).click();
// Level 3 — Quiz
await expect(page.getByRole("heading", { name: "Safe saving" })).toBeVisible();
await page.getByRole("radio", { name: /Documents/i }).check();
await page.getByRole("button", { name: "Submit answer" }).click();
await expect(
page.getByRole("heading", { name: "Desktop repaired" }),
).toBeVisible({ timeout: 15_000 });
});
});
test.describe("API", () => {
test("GET /api/health", async ({ request }) => {
const res = await request.get("/api/health");
expect(res.ok()).toBe(true);
await expect(res.json()).resolves.toEqual({ status: "ok" });
});
});