grocery-app/frontend/tests/household-selection-persistence.spec.ts
2026-05-26 01:30:40 -07:00

124 lines
4.1 KiB
TypeScript

import { expect, test } from "@playwright/test";
function seedAuthStorage(page: import("@playwright/test").Page) {
return page.addInitScript(() => {
localStorage.setItem("token", "test-token");
localStorage.setItem("userId", "1");
localStorage.setItem("role", "admin");
localStorage.setItem("username", "persistent-user");
});
}
async function mockConfig(page: import("@playwright/test").Page) {
await page.route("**/config", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
maxFileSizeMB: 20,
maxImageDimension: 800,
imageQuality: 85,
}),
});
});
}
test("selected household stays active after refreshing on settings and home pages", async ({ page }) => {
await seedAuthStorage(page);
await mockConfig(page);
const households = [
{ id: 1, name: "Alpha Home", role: "owner" },
{ id: 2, name: "Bravo Home", role: "admin" },
];
const storesByHousehold = {
1: [{ id: 101, household_store_id: 1001, name: "Costco", is_default: true }],
2: [{ id: 201, household_store_id: 2001, name: "Trader Joe's", is_default: true }],
};
await page.route("**/households", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(households),
});
});
await page.route("**/households/*/stores", async (route) => {
const householdId = Number(route.request().url().match(/households\/(\d+)\/stores/)?.[1]);
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify(
storesByHousehold[householdId as keyof typeof storesByHousehold] ?? []
),
});
});
await page.route("**/households/*/locations/*/zones", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({ zones: [] }),
});
});
await page.route("**/households/*/locations/*/list/recent", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify([]),
});
});
await page.route("**/households/*/locations/*/list", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({ items: [] }),
});
});
await page.route("**/households/*/members", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify([{ id: 1, username: "persistent-user", role: "owner" }]),
});
});
await page.goto("/");
await expect(page.getByRole("button", { name: "Alpha Home" })).toBeVisible();
const householdTrigger = page.locator(".household-switcher-toggle");
await expect(householdTrigger).toContainText("Alpha Home");
await householdTrigger.click();
const householdDropdown = page.locator(".household-switcher-dropdown");
await expect(householdDropdown).toBeVisible();
await expect(page.locator(".check-mark")).toHaveCount(0);
const triggerBox = await householdTrigger.boundingBox();
const dropdownBox = await householdDropdown.boundingBox();
expect(triggerBox).not.toBeNull();
expect(dropdownBox).not.toBeNull();
expect(Math.abs((dropdownBox?.x ?? 0) - (triggerBox?.x ?? 0))).toBeLessThan(1);
await page.getByRole("button", { name: "Bravo Home", exact: true }).click();
await expect(page.getByRole("button", { name: "Bravo Home" })).toBeVisible();
await expect.poll(() => page.evaluate(() => localStorage.getItem("activeHouseholdId"))).toBe("2");
await page.goto("/settings");
await expect(page.getByRole("button", { name: "Bravo Home" })).toBeVisible();
await page.reload();
await expect(page.getByRole("button", { name: "Bravo Home" })).toBeVisible();
await expect.poll(() => page.evaluate(() => localStorage.getItem("activeHouseholdId"))).toBe("2");
await page.goto("/");
await expect(page.getByRole("button", { name: "Bravo Home" })).toBeVisible();
await expect(page.getByRole("button", { name: "Trader Joe's" })).toBeVisible();
});