S3.3: pixel components: name-plate dialog titles, sunken fields, raised tabs, notched badges, XP bars, inventory slots, guide hint bubbles, game-over errors with Continue

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-09 12:23:17 -04:00
1 parent a6036308b7
commit 08ff96eec8
19 files changed
+149 -86

No files matched your search

+14
View File
@@ -60,7 +60,21 @@ test("text uses the bundled pixel font, and the palette follows the day part, se
await page.keyboard.press("Escape");
await expect(dialog).toHaveCount(0);
// Progress is an XP bar announced as a value; hints are spoken by the guide in a bubble.
await page.getByRole("button", { name: "Home" }).click();
await expect(page.getByRole("progressbar", { name: "Goal progress" })).toHaveAttribute("aria-valuenow", "0");
// On the roster the only agent holds the largest budget, and the bar says it compares budgets, not spend.
await page.getByRole("button", { name: "Team", exact: true }).click();
await expect(page.getByRole("progressbar", { name: "Budget compared with the largest agent budget" })).toHaveAttribute("aria-valuenow", "100");
await page.getByRole("button", { name: "Work", exact: true }).click();
const hint = page.getByRole("note").filter({ hasText: "Only a task runs" });
await expect(hint.locator(".hint-speaker svg.pixel-icon")).toHaveCount(1);
// Tabs are raised pixel tabs; fields are sunken pixel boxes.
const views = page.getByRole("radiogroup", { name: "View" });
expect(await views.locator("[aria-checked=true]").evaluate((tab) => getComputedStyle(tab).borderBottomColor === getComputedStyle(tab).backgroundColor)).toBe(true);
await page.getByRole("button", { name: "Settings" }).click();
expect(await page.getByRole("combobox", { name: "Theme" }).evaluate((field) => [getComputedStyle(field).borderTopWidth, getComputedStyle(field).borderRadius])).toEqual(["2px", "0px"]);
await page.getByRole("combobox", { name: "Theme" }).selectOption("dark");
await expect(root).toHaveAttribute("data-theme", "dark");
await page.getByRole("combobox", { name: "Theme" }).selectOption({ label: "Follow the clock" });
+4
View File
@@ -33,6 +33,10 @@ test("a record that breaks one page leaves the rest of the app working", async (
await page.getByRole("button", { name: "Approvals" }).click();
const failure = page.getByRole("alert").filter({ hasText: "This page could not be shown." });
await expect(failure).toContainText("Approval risk tone is missing.");
// A failure reads as a game over, with Continue to try again; the same fault fails the same way.
await expect(failure).toContainText("GAME OVER");
await failure.getByRole("button", { name: "Continue" }).click();
await expect(failure).toContainText("Approval risk tone is missing.");
await page.getByRole("button", { name: "Home" }).click();
await expect(failure).toHaveCount(0);
await expect(page.getByRole("button", { name: "Approvals" })).toBeVisible();
+2 -1
View File
@@ -35,7 +35,8 @@ test("a first load that fails says why, keeps retrying, and recovers", async ()
await expect(failure).toContainText(/attempt [2-9]/);
setDraft(null);
await page.getByRole("button", { name: "Retry now" }).click();
await expect(failure).toContainText("GAME OVER");
await page.getByRole("button", { name: "Continue" }).click();
await expect(page.getByRole("heading", { name: "Welcome" })).toBeVisible();
await app.close();
});