import { test, expect, Page } from "@playwright/test"; async function loginViaApi(page: Page, email: string, password: string): Promise<{ access_token: string; active_role: string }> { const res = await page.request.post("http://localhost:3000/api/auth/login", { data: { email, password }, headers: { "Content-Type": "application/json", Accept: "application/json" }, }); if (!res.ok()) { const text = await res.text(); throw new Error(`Login API failed (${res.status()}): ${text}`); } const data = await res.json(); return { access_token: data.access_token, active_role: data.user?.active_role || data.active_role || "JOB_SEEKER", }; } async function injectAuth(page: Page, email: string, token: string, role: string) { await page.goto("http://localhost:3000/"); await page.evaluate( ({ email, token, role }) => { const payload = { email, fullName: "Test User", name: "Test User", displayName: "Test User", roleKey: role.toLowerCase(), role: role.toLowerCase(), active_role: role, selectedProfessionalRole: role, user: { id: "test-id", email, full_name: "Test User", active_role: role }, }; window.sessionStorage.setItem("nxtgauge_access_token", token); window.sessionStorage.setItem("nxtgauge_frontend_access_token", token); window.localStorage.setItem("nxtgauge_auth_user", JSON.stringify(payload)); window.localStorage.setItem("nxtgauge_user", JSON.stringify(payload)); window.localStorage.setItem("nxtgauge_signup_profile_v1", JSON.stringify(payload)); }, { email, token, role } ); } test.describe("Dashboard Role Resolution", () => { test("TUTOR login should show TUTOR role in dashboard sidebar", async ({ page }) => { const email = "testtutora2026@example.com"; const password = "Test1234!"; // Step 1: Login via API const { access_token, active_role } = await loginViaApi(page, email, password); console.log(`[API Login] email=${email}, role=${active_role}, token=${access_token.slice(0, 20)}...`); // Step 2: Inject auth into browser await injectAuth(page, email, access_token, active_role); // Step 3: Navigate to dashboard with role param await page.goto(`http://localhost:3000/dashboard?role=${active_role}`); await page.waitForLoadState("networkidle"); await page.waitForTimeout(3000); // Wait for effects and bundle load // Step 4: Check Active Role badge const url = page.url(); console.log(`[Dashboard] URL: ${url}`); const activeRoleLocator = page.locator("aside").locator("text=Active Role").locator("..").locator("p").last(); const activeRoleText = await activeRoleLocator.textContent().catch(() => "NOT FOUND"); console.log(`[Dashboard] Active Role text: "${activeRoleText}"`); // Step 5: Check sidebar items const sidebarNav = page.locator("aside nav"); const sidebarItems = await sidebarNav.locator("button").allTextContents(); console.log(`[Dashboard] Sidebar items: ${sidebarItems.join(", ")}`); // Step 6: Take screenshot await page.screenshot({ path: `test-results/dashboard-${active_role.toLowerCase()}-role-check.png`, fullPage: true, }); // Assertions await expect(activeRoleLocator).toContainText(active_role); }); test("PHOTOGRAPHER login should show PHOTOGRAPHER role in dashboard sidebar", async ({ page }) => { // Try to find a photographer account - use check-email API to discover const email = "ashwinkumars0088@gmail.com"; const password = "Test1234!"; // First check if this email has PHOTOGRAPHER role const checkRes = await page.request.post("http://localhost:3000/api/auth/check-email", { data: { email }, headers: { "Content-Type": "application/json", Accept: "application/json" }, }); let targetRole = "PHOTOGRAPHER"; if (checkRes.ok()) { const checkData = await checkRes.json(); console.log(`[Check Email] ${email}:`, checkData); if (checkData?.active_role) { targetRole = checkData.active_role; } } // Try to login let token: string; try { const loginResult = await loginViaApi(page, email, password); token = loginResult.access_token; if (loginResult.active_role && loginResult.active_role !== "JOB_SEEKER") { targetRole = loginResult.active_role; } } catch { console.log(`[Login] ${email} login failed, trying API login with different approach`); // Try without password for discovery const checkData = await (await page.request.post("http://localhost:3000/api/auth/check-email", { data: { email }, headers: { "Content-Type": "application/json", Accept: "application/json" }, })).json(); console.log(`[Check Email Result]:`, checkData); // If we can't login, at least verify the role detection await page.goto("http://localhost:3000/login"); await page.fill("#login-email", email); await page.waitForTimeout(500); await page.screenshot({ path: "test-results/login-email-check.png" }); return; } console.log(`[API Login] email=${email}, role=${targetRole}`); await injectAuth(page, email, token, targetRole); await page.goto(`http://localhost:3000/dashboard?role=${targetRole}`); await page.waitForLoadState("networkidle"); await page.waitForTimeout(3000); const url = page.url(); console.log(`[Dashboard] URL: ${url}`); const activeRoleLocator = page.locator("aside").locator("text=Active Role").locator("..").locator("p").last(); const activeRoleText = await activeRoleLocator.textContent().catch(() => "NOT FOUND"); console.log(`[Dashboard] Active Role text: "${activeRoleText}"`); const sidebarNav = page.locator("aside nav"); const sidebarItems = await sidebarNav.locator("button").allTextContents(); console.log(`[Dashboard] Sidebar items: ${sidebarItems.join(", ")}`); await page.screenshot({ path: `test-results/dashboard-${targetRole.toLowerCase()}-role-check.png`, fullPage: true, }); await expect(activeRoleLocator).toContainText(targetRole); }); test("direct dashboard navigation with role param should show correct role", async ({ page }) => { // This test just verifies the URL param is respected await page.goto("http://localhost:3000/dashboard?role=PHOTOGRAPHER"); await page.waitForLoadState("networkidle"); await page.waitForTimeout(2000); const url = page.url(); console.log(`[Dashboard] URL: ${url}`); const activeRoleLocator = page.locator("aside").locator("text=Active Role").locator("..").locator("p").last(); const activeRoleText = await activeRoleLocator.textContent().catch(() => "NOT FOUND"); console.log(`[Dashboard] Active Role text: "${activeRoleText}"`); const sidebarNav = page.locator("aside nav"); const sidebarItems = await sidebarNav.locator("button").allTextContents(); console.log(`[Dashboard] Sidebar items: ${sidebarItems.join(", ")}`); await page.screenshot({ path: "test-results/dashboard-direct-role-param.png", fullPage: true, }); // Should show PHOTOGRAPHER sidebar (with Leads/My Responses), not JOB_SEEKER (with Jobs/My Applications) await expect(activeRoleLocator).toContainText("PHOTOGRAPHER"); expect(sidebarItems).toContain("Leads"); expect(sidebarItems).not.toContain("Jobs"); }); });