// @ts-check import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Forgot Password — exact UI flow', () => { test.setTimeout(20000); test('SignIn → Forgot → invalid email blocked → valid submit shows success copy', async ({ page }) => { const user = loadTestUser(); const email = (user.email || 'test@example.com').toLowerCase(); // Go to Sign In await page.context().clearCookies(); await page.goto('/signin', { waitUntil: 'networkidle' }); await expect(page.getByRole('heading', { name: /^Sign In$/i })).toBeVisible(); // Click “Forgot your password?” const forgotLink = page.getByRole('link', { name: /^Forgot your password\?$/i }) .or(page.getByText(/^Forgot your password\?$/i)); await expect(forgotLink).toBeVisible({ timeout: 5000 }); await forgotLink.click(); // Forgot page renders await expect(page).toHaveURL(/\/forgot-password(\?|$)/, { timeout: 5000 }); await expect(page.getByRole('heading', { name: /^Forgot your password\?$/i })).toBeVisible(); // Email input present const emailInput = page.getByRole('textbox', { name: /^Email$/i }) .or(page.locator('input[type="email"]')) .first(); await expect(emailInput).toBeVisible(); // Invalid email → inline error “Enter a valid email.” await emailInput.fill('not-an-email'); const sendBtn = page.getByRole('button', { name: /^Send reset link$/i }); await expect(sendBtn).toBeVisible(); await sendBtn.click(); const invalidByHtml5 = await emailInput.evaluate(el => el instanceof HTMLInputElement ? el.validity && !el.validity.valid : false ); // Either native validity blocked submit or inline error appeared const inlineErrVisible = await page.getByText(/^Enter a valid email\.$/i) .isVisible().catch(() => false); expect(invalidByHtml5 || inlineErrVisible).toBeTruthy(); // Valid email → success screen “Check your email” with the address await emailInput.fill(email); await sendBtn.click(); await expect(page.getByRole('heading', { name: /^Check your email$/i })).toBeVisible({ timeout: 7000 }); await expect(page.getByText(new RegExp(email.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'))).toBeVisible(); // Optional: “Back to Sign In” works const backBtn = page.getByRole('button', { name: /^Back to Sign In$/i }) .or(page.getByRole('link', { name: /^Back to Sign In$/i })); if (await backBtn.isVisible().catch(() => false)) { await backBtn.click(); await expect(page).toHaveURL(/\/signin(\?|$)/, { timeout: 5000 }); } }); });