import { expect, test } from "@playwright/test"; test.describe("Navigation", () => { test.beforeEach(async ({ page }) => { await page.goto("/auth/signin"); await page.fill('input[type="email"]', "admin@planarchy.dev"); await page.fill('input[type="password"]', "admin123"); await page.click('button[type="submit"]'); await expect(page).toHaveURL(/\/(dashboard|resources)/); }); test("main nav links navigate correctly", async ({ page }) => { const navRoutes = [ { label: "Dashboard", url: "/dashboard" }, { label: "Timeline", url: "/timeline" }, { label: "Allocations", url: "/allocations" }, { label: "Resources", url: "/resources" }, { label: "Projects", url: "/projects" }, ]; for (const route of navRoutes) { const navLink = page.locator(`nav a >> text="${route.label}"`).first(); await navLink.click(); await page.waitForLoadState("networkidle"); await expect(page).toHaveURL(new RegExp(route.url)); } }); test("sidebar collapse and expand works", async ({ page }) => { await page.goto("/dashboard"); await page.waitForLoadState("networkidle"); // Find the collapse button (contains "Collapse" text) const collapseBtn = page.locator("nav button", { hasText: "Collapse" }); if ((await collapseBtn.count()) > 0) { await collapseBtn.click(); await page.waitForTimeout(300); // After collapsing, the sidebar should be narrow (72px) const nav = page.locator("nav").first(); const box = await nav.boundingBox(); if (box) { expect(box.width).toBeLessThan(100); } // Expand again — the button should still be visible as an icon const expandBtn = page.locator("nav button").filter({ has: page.locator("svg") }).last(); await expandBtn.click(); await page.waitForTimeout(300); const boxExpanded = await nav.boundingBox(); if (boxExpanded) { expect(boxExpanded.width).toBeGreaterThan(200); } } }); test("preferences modal opens via sidebar button", async ({ page }) => { await page.goto("/dashboard"); await page.waitForLoadState("networkidle"); const prefsBtn = page.locator("nav button", { hasText: "Preferences" }); if ((await prefsBtn.count()) > 0) { await prefsBtn.click(); await expect(page.locator("text=Preferences")).toBeVisible({ timeout: 5000 }); // Should show theme/mode controls await expect( page.locator("text=Light").or(page.locator("text=Dark").or(page.locator("text=System"))), ).toBeVisible(); // Close the modal await page.keyboard.press("Escape"); } }); test("mobile hamburger menu opens sidebar on small viewport", async ({ page }) => { // Set a mobile viewport size await page.setViewportSize({ width: 375, height: 812 }); await page.goto("/dashboard"); await page.waitForLoadState("networkidle"); // The hamburger button should be visible on mobile const hamburgerBtn = page.locator("button").filter({ has: page.locator("svg") }).first(); await expect(hamburgerBtn).toBeVisible({ timeout: 5000 }); await hamburgerBtn.click(); await page.waitForTimeout(300); // Mobile sidebar overlay should appear with nav links await expect(page.locator("text=Dashboard")).toBeVisible(); await expect(page.locator("text=Timeline")).toBeVisible(); // Close button should be visible in mobile sidebar const closeBtn = page .locator("nav button") .filter({ has: page.locator("svg") }) .first(); if ((await closeBtn.count()) > 0) { await closeBtn.click(); } }); });