import { expect, test } from "@playwright/test"; import { mockApi, seedAuthenticatedState } from "./support/network.js"; import { isCompactProject } from "./support/projects"; const adminPermissions = [ "admin", "list_bookings", "list_department_daily_reports", "create_department_daily_report_complaints", "department_access_1", ]; const json = (body: unknown, status = 200) => ({ status, contentType: "application/json", body: JSON.stringify(body), }); const buildOverviewPayload = () => ({ data: { department_ids: [1], date: "2026-04-09", date_to: "2026-04-09", metrics: { bookings: { state: "ready", value: 4, out_of: 6, message: null }, complaints: { state: "ready", value: 2, out_of: null, message: null }, night_washes: { state: "ready", value: 1, out_of: null, message: null }, revenue: { state: "ready", value: 2400, out_of: null, message: null }, washes: { state: "ready", value: 8, out_of: null, message: null }, products_sold: { state: "ready", value: 19, out_of: null, message: null }, transactions: { state: "ready", value: 11, out_of: null, message: null }, water_usage: { state: "ready", value: 32, out_of: null, message: null }, overtime: { state: "ready", value: 1.5, out_of: null, message: null }, }, products: [], }, }); async function mockOverviewPageDependencies(page) { await seedAuthenticatedState(page); await mockApi(page, { authenticated: true, permissions: adminPermissions, }); await page.route(/\/departments(\?.*)?$/i, async (route) => { await route.fulfill( json({ data: [{ id: 1, name: "North" }], }) ); }); await page.route(/\/admin\/bookings\/department\/count(\?.*)?$/i, async (route) => { await route.fulfill( json({ data: { data: { message: 5, }, }, }) ); }); await page.route(/\/departments\/self-serve\/enabled(\?.*)?$/i, async (route) => { await route.fulfill( json({ data: { data: { enabled: false, }, }, }) ); }); await page.route(/\/departments\/weather(\?.*)?$/i, async (route) => { await route.fulfill(json({ data: [] })); }); await page.route(/\/departments\/daily-reports\/get(\?.*)?$/i, async (route) => { await route.fulfill( json({ data: { id: 10, department_id: 1, water_usage: 32, notes: "", filled_by: 1, created_at: "2026-04-09 00:00:00", }, }) ); }); await page.route(/\/departments\/daily-reports\/complaints$/i, async (route) => { await route.fulfill(json({ data: { id: 1 } })); }); await page.route(/\/departments\/daily-reports(?:\/overview)?(\?.*)?$/i, async (route) => { const url = new URL(route.request().url()); if (url.pathname.endsWith("/departments/daily-reports/overview")) { await route.fulfill(json(buildOverviewPayload())); return; } await route.fulfill(json({ data: [] })); }); } test.describe("Admin overview mobile", () => { test("keeps modules first, collapses reports by default, and preserves mobile report actions", async ({ page, }, testInfo) => { test.skip(!isCompactProject(testInfo), "Compact-device overview regression"); await mockOverviewPageDependencies(page); await page.goto("/admin/1"); const modules = page.getByTestId("admin-mobile-modules"); const reportsToggle = page.getByTestId("admin-mobile-reports-toggle"); await expect(modules).toBeVisible(); await expect(reportsToggle).toBeVisible(); await expect(page.locator("[data-testid='daily-report-page']")).toHaveCount(0); const modulesBox = await modules.boundingBox(); const reportsBox = await reportsToggle.boundingBox(); expect(modulesBox?.y ?? 0).toBeLessThan(reportsBox?.y ?? Number.MAX_SAFE_INTEGER); expect(await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth)).toBe( false ); await reportsToggle.click(); await expect(page.getByTestId("daily-report-page")).toBeVisible(); await expect(page.getByTestId("date-period-mobile-layout")).toBeVisible(); await expect(page.locator("[data-testid='daily-report-department-controls']")).toHaveCount(0); await page.getByTestId("daily-report-mobile-departments-toggle").click(); await expect(page.getByTestId("daily-report-department-controls")).toBeVisible(); await expect(page.getByTestId("daily-report-department-all")).toBeVisible(); expect(await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth)).toBe( false ); await page.getByTestId("daily-report-complaints-add-button").click(); await expect(page.getByTestId("daily-report-complaints-modal")).toBeVisible(); await expect(page.getByTestId("daily-report-complaints-cancel")).toBeVisible(); await expect(page.getByTestId("daily-report-complaints-submit")).toBeVisible(); const footerFitsViewport = await page.evaluate(() => { const footer = document.querySelector(".complaints-modal-footer__actions"); if (!(footer instanceof HTMLElement)) { return false; } const rect = footer.getBoundingClientRect(); return rect.left >= 0 && rect.right <= window.innerWidth; }); expect(footerFitsViewport).toBe(true); await page.getByTestId("daily-report-complaints-cancel").click(); await expect(page.locator("[data-testid='daily-report-complaints-modal']")).toHaveCount(0); }); });