import { expect, impersonate, navigate, seed, test, } from "./helpers/playwright"; test.describe("Navigation", () => { test("desktop navigation", async ({ page }) => { await seed(page); await impersonate(page); await navigate({ page, url: "/" }); // SideNav visible with section headings await expect(page.getByRole("heading", { name: "Events" })).toBeVisible(); await expect(page.getByRole("heading", { name: "Friends" })).toBeVisible(); await expect(page.getByRole("heading", { name: "Streams" })).toBeVisible(); // View all links present const viewAllLinks = page.getByRole("link", { name: /View all/ }); await expect(viewAllLinks.first()).toBeVisible(); // SideNav collapse/uncollapse const collapseButton = page.getByTestId("sidenav-collapse-button"); await collapseButton.click(); await expect( page.getByRole("heading", { name: "Events" }), ).not.toBeVisible(); await collapseButton.click(); await expect(page.getByRole("heading", { name: "Events" })).toBeVisible(); // TopNavMenus — Play await page.getByRole("button", { name: "Play" }).click(); const playMenu = page.locator("[class*='menuContent']"); await expect(playMenu.getByRole("link", { name: "SendouQ" })).toBeVisible(); await expect(playMenu.getByRole("link", { name: "Scrims" })).toBeVisible(); await playMenu.getByRole("link", { name: "SendouQ" }).click(); await expect( playMenu.getByRole("link", { name: "SendouQ" }), ).not.toBeVisible(); await navigate({ page, url: "/" }); // TopNavMenus — Tools await page.getByRole("button", { name: "Tools" }).click(); const toolsMenu = page.locator("[class*='menuContent']"); await expect( toolsMenu.getByRole("link", { name: "Analyzer" }), ).toBeVisible(); await page.keyboard.press("Escape"); // TopNavMenus — Community await page.getByRole("button", { name: "Community" }).click(); const communityMenu = page.locator("[class*='menuContent']"); await expect( communityMenu.getByRole("link", { name: "Builds" }), ).toBeVisible(); await page.keyboard.press("Escape"); // SideNav footer — user info await expect(page.getByTestId("notifications-button")).toBeVisible(); }); test("mobile navigation", async ({ page }) => { await page.setViewportSize({ width: 375, height: 667 }); await seed(page); await impersonate(page); await navigate({ page, url: "/" }); // Tab bar visible const menuTab = page.getByRole("button", { name: "Menu" }); const friendsTab = page.getByRole("button", { name: "Friends" }); const calendarTab = page.getByRole("button", { name: "Events" }); const chatTab = page.getByRole("button", { name: "Chat" }); const youTab = page.getByRole("button", { name: "You" }); await expect(menuTab).toBeVisible(); await expect(friendsTab).toBeVisible(); await expect(calendarTab).toBeVisible(); await expect(chatTab).toBeVisible(); await expect(youTab).toBeVisible(); // Menu panel — open and verify contents await menuTab.click(); const mobileMenu = page.getByLabel("Menu", { exact: true }); await expect( mobileMenu.getByRole("link", { name: "SendouQ" }), ).toBeVisible(); await expect( mobileMenu.getByRole("link", { name: "Analyzer" }), ).toBeVisible(); await expect( mobileMenu.getByRole("link", { name: "Builds" }), ).toBeVisible(); await expect( page.locator("h3").filter({ hasText: "Streams" }), ).toBeVisible(); // Switch from menu to friends panel via ghost tab // Ghost tabs are invisible overlays; use dispatchEvent to trigger them // nth(1) = "friends" ghost tab (0=menu, 1=friends, 2=tourneys, 3=chat, 4=you) await page .locator("[class*='ghostTab']:not([class*='ghostTabBar'])") .nth(1) .dispatchEvent("click"); await expect( mobileMenu.getByRole("link", { name: "SendouQ" }), ).not.toBeVisible(); const friendsViewAll = page.getByRole("link", { name: /View all/ }); await expect(friendsViewAll).toBeVisible(); // Switch to You panel via ghost tab (nth(4) = "you") await page .locator("[class*='ghostTab']:not([class*='ghostTabBar'])") .nth(4) .dispatchEvent("click"); // You panel shows user info (username link) await expect(page.locator("[class*='youPanelUsername']")).toBeVisible(); // Switch to calendar panel via ghost tab (nth(2) = "tourneys") await page .locator("[class*='ghostTab']:not([class*='ghostTabBar'])") .nth(2) .dispatchEvent("click"); const tourneysViewAll = page.getByRole("link", { name: /View all/ }); await expect(tourneysViewAll).toBeVisible(); // Close panel via X button await page.locator("button:has(svg.lucide-x)").first().click(); await expect(tourneysViewAll).not.toBeVisible(); }); test("tablet navigation", async ({ page }) => { await page.setViewportSize({ width: 768, height: 1024 }); await seed(page); await impersonate(page); await navigate({ page, url: "/" }); // SideNav not visible as permanent sidebar await expect( page.getByRole("heading", { name: "Events" }), ).not.toBeVisible(); await expect( page.getByRole("heading", { name: "Friends" }), ).not.toBeVisible(); // Hamburger opens SideNav modal const modalTrigger = page.getByTestId("sidenav-modal-trigger"); await modalTrigger.click(); await expect(page.getByRole("heading", { name: "Events" })).toBeVisible(); await expect(page.getByRole("heading", { name: "Friends" })).toBeVisible(); await expect(page.getByRole("heading", { name: "Streams" })).toBeVisible(); await expect( page.getByRole("link", { name: /View all/ }).first(), ).toBeVisible(); // Close modal by pressing Escape await page.keyboard.press("Escape"); await expect( page.getByRole("heading", { name: "Events" }), ).not.toBeVisible(); // TopNavMenus still work await page.getByRole("button", { name: "Play" }).click(); const tabletPlayMenu = page.locator("[class*='menuContent']"); await expect( tabletPlayMenu.getByRole("link", { name: "SendouQ" }), ).toBeVisible(); await page.keyboard.press("Escape"); // MobileNav hidden await expect(page.getByRole("button", { name: "Menu" })).not.toBeVisible(); }); });