// ABOUTME: E2E tests for the exercise plan reference page. // ABOUTME: Tests phase display, training guidelines, and current status. import { expect, test } from "@playwright/test"; test.describe("plan page", () => { test.describe("unauthenticated", () => { test("redirects to login when not authenticated", async ({ page }) => { await page.goto("/plan"); // Should redirect to login await expect(page).toHaveURL(/\/login/); }); }); test.describe("authenticated", () => { // These tests require TEST_USER_EMAIL and TEST_USER_PASSWORD env vars test.beforeEach(async ({ page }) => { const email = process.env.TEST_USER_EMAIL; const password = process.env.TEST_USER_PASSWORD; if (!email || !password) { test.skip(); return; } // Login via the login page await page.goto("/login"); await page.waitForLoadState("networkidle"); const emailInput = page.getByLabel(/email/i); const hasEmailForm = await emailInput.isVisible().catch(() => false); if (!hasEmailForm) { test.skip(); return; } await emailInput.fill(email); await page.getByLabel(/password/i).fill(password); await page.getByRole("button", { name: /sign in/i }).click(); // Wait for redirect to dashboard then navigate to plan await page.waitForURL("/", { timeout: 10000 }); await page.goto("/plan"); }); test("displays exercise plan page with title", async ({ page }) => { // Check for plan page title const heading = page.getByRole("heading", { name: "Exercise Plan" }); await expect(heading).toBeVisible(); }); test("shows current cycle status section", async ({ page }) => { await page.waitForLoadState("networkidle"); // Wait for page to finish loading - look for Current Status or error state const statusSection = page.getByRole("heading", { name: "Current Status", }); // Use text content to find error alert (avoid Next.js route announcer) const errorAlert = page.getByText(/error:/i); try { // Wait for Current Status section to be visible (data loaded successfully) await expect(statusSection).toBeVisible({ timeout: 10000 }); // Should show day number await expect(page.getByText(/day \d+/i)).toBeVisible({ timeout: 5000 }); // Should show training type await expect(page.getByText(/training type:/i)).toBeVisible({ timeout: 5000, }); // Should show weekly limit await expect(page.getByText(/weekly limit:/i)).toBeVisible({ timeout: 5000, }); } catch { // If status section not visible, check for error alert await expect(errorAlert).toBeVisible({ timeout: 5000 }); } }); test("shows all 5 phase cards", async ({ page }) => { await page.waitForLoadState("networkidle"); // Check for Phase Overview section const phaseOverview = page.getByRole("heading", { name: "Phase Overview", }); const hasPhaseOverview = await phaseOverview .isVisible() .catch(() => false); if (hasPhaseOverview) { // Should show all 5 phase cards using data-testid await expect(page.getByTestId("phase-MENSTRUAL")).toBeVisible(); await expect(page.getByTestId("phase-FOLLICULAR")).toBeVisible(); await expect(page.getByTestId("phase-OVULATION")).toBeVisible(); await expect(page.getByTestId("phase-EARLY_LUTEAL")).toBeVisible(); await expect(page.getByTestId("phase-LATE_LUTEAL")).toBeVisible(); } }); test("shows strength training reference table", async ({ page }) => { await page.waitForLoadState("networkidle"); // Check for Strength Training section const strengthSection = page.getByRole("heading", { name: /strength training/i, }); const hasStrength = await strengthSection.isVisible().catch(() => false); if (hasStrength) { // Should have exercise table const table = page.locator("table"); await expect(table).toBeVisible(); // Check for some exercises await expect(page.getByText("Squats")).toBeVisible(); await expect(page.getByText("Push-ups")).toBeVisible(); await expect(page.getByText("Plank")).toBeVisible(); } }); test("shows rebounding techniques", async ({ page }) => { await page.waitForLoadState("networkidle"); // Check for Rebounding Techniques section const reboundingSection = page.getByRole("heading", { name: /rebounding techniques/i, }); const hasRebounding = await reboundingSection .isVisible() .catch(() => false); if (hasRebounding) { // Should show techniques section - use first() for specific match await expect( page.getByText("Health bounce, lymphatic drainage"), ).toBeVisible(); } }); test("shows weekly guidelines", async ({ page }) => { await page.waitForLoadState("networkidle"); // Check for Weekly Guidelines section const weeklySection = page.getByRole("heading", { name: "Weekly Guidelines", }); const hasWeekly = await weeklySection.isVisible().catch(() => false); if (hasWeekly) { // Should show guidelines for each phase - use exact matches await expect( page.getByRole("heading", { name: "Menstrual Phase (Days 1-3)" }), ).toBeVisible(); await expect( page.getByRole("heading", { name: "Follicular Phase (Days 4-14)" }), ).toBeVisible(); } }); }); });