import { test, expect } from '@playwright/test'; import { ADMIN_BASE } from '../playwright.auth.config'; /** * Real-login E2E tests — runs with AUTH_DEV_AUTOLOGIN=false. * Both apps enforce authentication via middleware. * * Preconditions (`pnpm db:seed` + docker compose running): * - op1@demo.local PIN 1111 * - admin@demo.local password admin1234 * * Run: pnpm test:e2e:auth (no servers running on 3000/3001 — this starts its own) */ // ── Operator — PIN login (baseURL = localhost:3000) ────────────────────────── test('operator: wrong PIN shows error, correct PIN enters the app', async ({ page }) => { await page.goto('/select-operator'); // Picker is accessible without a session (it IS the login page) await expect(page.getByText('op1@demo.local')).toBeVisible({ timeout: 15_000 }); // Select op1 await page.getByRole('button', { name: 'op1@demo.local' }).click(); await expect(page.getByText('Operador selecionado')).toBeVisible(); // Wrong PIN: 9 9 9 9 for (const d of ['9', '9', '9', '9']) { await page.getByRole('button', { name: d }).click(); } await page.getByRole('button', { name: 'Entrar' }).click(); await expect( page.getByText('PIN incorreto ou conta bloqueada. Tente novamente.'), ).toBeVisible({ timeout: 10_000 }); // Digits are cleared after error — type correct PIN for (const d of ['1', '1', '1', '1']) { await page.getByRole('button', { name: d }).click(); } await page.getByRole('button', { name: 'Entrar' }).click(); // Successful login → home page with "Pedir manutenção" CTA await expect(page.getByTestId('btn-request-maintenance')).toBeVisible({ timeout: 15_000 }); }); test('operator: unauthenticated root redirects to picker', async ({ page }) => { await page.goto('/'); // Without autologin and no session, middleware redirects to /select-operator await expect(page).toHaveURL(/\/select-operator/, { timeout: 10_000 }); }); // ── Admin — password login (separate describe gives an isolated browser context // with baseURL = localhost:3001, avoiding cross-port URL confusion) ────────── test.describe('Admin password login', () => { test.use({ baseURL: ADMIN_BASE }); test('protected route redirects to /login without session', async ({ page }) => { await page.goto('/maintenance'); // Middleware redirects to /login (may include ?callbackUrl= query param) await expect(page).toHaveURL(/\/login/, { timeout: 10_000 }); }); test('wrong password shows error, correct password enters the queue', async ({ page }) => { await page.goto('/login'); await expect(page.locator('input#email')).toBeVisible({ timeout: 15_000 }); // Wrong password await page.fill('input#email', 'admin@demo.local'); await page.fill('input#password', 'wrongpassword'); await page.getByRole('button', { name: 'Entrar' }).click(); await expect( page.getByText('Email ou password incorretos. Tente novamente.'), ).toBeVisible({ timeout: 10_000 }); // Correct password await page.fill('input#password', 'admin1234'); await page.getByRole('button', { name: 'Entrar' }).click(); // Successful login → maintenance queue await expect(page).toHaveURL(/\/maintenance$/, { timeout: 15_000 }); await expect( page.getByText('Fila de manutenção').or(page.getByText('pedidos abertos')), ).toBeVisible({ timeout: 10_000 }); }); });