/** * Sprint 4 — Etapa 8: smoke tests de los flujos críticos introducidos por el sprint * (auth, biblioteca con Supabase, catálogo de recursos). * * Los tests "sin auth" verifican el guard de rutas protegidas — corren sin storageState. * Los tests "con auth" usan la sesión real generada por tests/e2e/setup/auth-setup.ts. */ import { test, expect } from '@playwright/test' // ─── Sin auth — deben pasar sin sesión ──────────────────────────────────────── test.describe('Sin sesión', () => { test('login page renders — botón de Google visible', async ({ page }) => { await page.goto('/login') await expect(page.getByRole('button', { name: /iniciar sesión con google/i })).toBeVisible() }) test('protected route / redirects to login', async ({ page }) => { await page.goto('/') await expect(page).toHaveURL(/\/login/) }) test('protected route /workspace redirects to login', async ({ page }) => { await page.goto('/workspace/fake-id') await expect(page).toHaveURL(/\/login/) }) test('protected route /recursos redirects to login', async ({ page }) => { await page.goto('/recursos') await expect(page).toHaveURL(/\/login/) }) }) // ─── Con auth — requieren sesión de test ────────────────────────────────────── test.describe('Con sesión', () => { test.use({ storageState: 'tests/e2e/setup/auth-state.json' }) test('library loads after auth — sin errores 500', async ({ page }) => { const errors: string[] = [] page.on('response', (r) => { if (r.status() >= 500) errors.push(r.url()) }) await page.goto('/') await page.waitForLoadState('networkidle') expect(errors).toHaveLength(0) }) test('library — sin errores 406 en queries de simulations', async ({ page }) => { const errors406: string[] = [] page.on('response', (r) => { if (r.status() === 406 && r.url().includes('simulations')) errors406.push(r.url()) }) await page.goto('/') await page.waitForLoadState('networkidle') expect(errors406).toHaveLength(0) }) test('catalog page loads at /recursos', async ({ page }) => { await page.goto('/recursos') await expect(page.getByRole('heading', { name: /catálogo de recursos/i })).toBeVisible() }) test('app header shows user avatar', async ({ page }) => { await page.goto('/') // El trigger del dropdown de usuario tiene title={user.name} (ver AppHeader.tsx) await expect(page.locator('header button[title]').first()).toBeVisible() }) test('import BPMN — navega al workspace', async ({ page }) => { await page.goto('/import') await page.getByText('Proceso lineal simple').click() await expect(page).toHaveURL(/\/workspace\//, { timeout: 15_000 }) }) })