import { test, expect } from '@playwright/test'; import { ADMIN_BASE } from '../playwright.config'; /** * E2E for MAI CALL v0.3 — shift report page. * * Preconditions (met by `pnpm db:seed` + running docker compose): * - Demo Factory tenant with 6 sample maintenance requests created "today" * - AUTH_DEV_AUTOLOGIN=true on admin-web (set in playwright.config.ts) * * The `waitForLoadState('networkidle')` call is also a regression guard for * the fetch-storm fix: if the 'today' window ever starts recomputing on every * render again (new query key → continuous refetch), networkidle is never * reached and this test fails at that line. */ test('shift report: renders with seed data and reacts to window selection', async ({ page }) => { await page.goto(`${ADMIN_BASE}/maintenance/report`); // networkidle = fetch-storm sentinel: continuous refetch would never settle await page.waitForLoadState('networkidle'); // Title visible await expect(page.getByRole('heading', { name: 'Relatório de turno' })).toBeVisible(); // Default window is "Hoje" — label starts with "Hoje —" await expect(page.getByText(/^Hoje —/)).toBeVisible(); // Seed creates 6 requests "today" → Pedidos card must show > 0 const pedidosCard = page.locator('div.rounded-xl').filter({ hasText: /^Pedidos/ }).first(); await expect(pedidosCard).toBeVisible(); const pedidosText = await pedidosCard.locator('p.text-2xl').textContent(); expect(parseInt(pedidosText ?? '0')).toBeGreaterThan(0); // "Resposta média" card must be present and non-empty const respostaCard = page.locator('div.rounded-xl').filter({ hasText: /^Resposta média/ }).first(); await expect(respostaCard).toBeVisible(); const respostaValue = respostaCard.locator('p.text-2xl'); const respostaText = await respostaValue.textContent(); expect(respostaText?.trim().length).toBeGreaterThan(0); // "Por posto" table must have at least one data row await expect(page.locator('table tbody tr').first()).toBeVisible(); // Imprimir button exists (don't click — triggers native print dialog) await expect(page.getByRole('button', { name: 'Imprimir' })).toBeVisible(); // ── Reactivity: switching to Tarde changes the window label ────────────── await page.getByRole('button', { name: 'Tarde' }).click(); await expect(page.getByText(/^Turno da Tarde —/)).toBeVisible(); // Switch back to Hoje await page.getByRole('button', { name: 'Hoje' }).click(); await expect(page.getByText(/^Hoje —/)).toBeVisible(); }); test('shift report: accessible from the maintenance queue link', async ({ page }) => { await page.goto(`${ADMIN_BASE}/maintenance`); await expect(page.getByRole('link', { name: 'Relatório de turno' })).toBeVisible(); await page.getByRole('link', { name: 'Relatório de turno' }).click(); await expect(page).toHaveURL(`${ADMIN_BASE}/maintenance/report`); await expect(page.getByRole('heading', { name: 'Relatório de turno' })).toBeVisible(); // "← Fila" back link works await page.getByRole('link', { name: 'Fila' }).click(); await expect(page).toHaveURL(`${ADMIN_BASE}/maintenance`); });