// Critical-path smoke — the thin regression net described in docs/QA_PLAN.md §4.4. // Keep these fast and stable; grow the suite whenever a manual QA pass finds a UI // regression a click-test could have caught. Deeper flows (login -> pay bill -> // reconcile) get their own spec once a seeded scratch DB + test creds are wired // via a Playwright fixture — see e2e/README.md. const { test, expect } = require('@playwright/test'); test.describe('login page', () => { test('renders the sign-in form', async ({ page }) => { await page.goto('/login'); await expect(page).toHaveTitle(/Bill Tracker/i); await expect(page.getByRole('heading', { name: /sign in/i })).toBeVisible(); await expect(page.locator('#username')).toBeVisible(); await expect(page.locator('#password')).toBeVisible(); await expect(page.getByRole('button', { name: /sign in/i })).toBeVisible(); }); test('rejects empty submit without a crash', async ({ page }) => { const errors = []; page.on('pageerror', (e) => errors.push(e)); await page.goto('/login'); await page.getByRole('button', { name: /sign in/i }).click(); // Still on the login page, no uncaught exception, no white screen. await expect(page.getByRole('heading', { name: /sign in/i })).toBeVisible(); expect(errors, `uncaught page errors: ${errors.map(String).join('\n')}`).toHaveLength(0); }); // Visual-regression baseline. First run writes the snapshot; later runs diff // against it. Re-baseline intentionally with `npm run test:e2e:update`. test('login page matches visual baseline', async ({ page }) => { await page.goto('/login'); await expect(page.getByRole('heading', { name: /sign in/i })).toBeVisible(); await expect(page).toHaveScreenshot('login.png', { fullPage: true }); }); }); test.describe('routing', () => { test('unauthenticated deep link lands on login, not a blank page', async ({ page }) => { await page.goto('/bogus-does-not-exist'); // Protected shell redirects an unauthenticated user to /login; either way the // page must render real content, never a white screen. await expect(page.locator('body')).not.toBeEmpty(); await expect(page).toHaveURL(/\/(login|bogus-does-not-exist)/); }); });