diff --git a/playwright.config.mjs b/playwright.config.mjs index 51fee49..fd19e36 100644 --- a/playwright.config.mjs +++ b/playwright.config.mjs @@ -1,7 +1,12 @@ import { defineConfig, devices } from '@playwright/test'; -// La demo se verifica en WebKit, en escritorio y en un iPhone real de perfil. -// Un solo worker: las pruebas comparten la base de la demo y algunas escriben. +// Por omisión se prueba el portal local. Con BASE apuntando a otra dirección +// se prueba ese despliegue y no se arranca ningún servidor: +// $env:BASE="https://instademo.urieljareth.org"; npx playwright test +const BASE = process.env.BASE ?? 'http://localhost:4180'; +const esLocal = BASE.includes('localhost') || BASE.includes('127.0.0.1'); + +// Un solo worker: las pruebas comparten la base y algunas escriben. export default defineConfig({ testDir: './tests', fullyParallel: false, @@ -9,7 +14,7 @@ export default defineConfig({ retries: 0, reporter: [['list'], ['html', { open: 'never', outputFolder: 'tests/reporte' }]], use: { - baseURL: 'http://localhost:4180', + baseURL: BASE, locale: 'es-MX', timezoneId: 'America/Mexico_City', screenshot: 'only-on-failure', @@ -19,10 +24,14 @@ export default defineConfig({ { name: 'webkit', use: { ...devices['Desktop Safari'], viewport: { width: 1440, height: 900 } } }, { name: 'webkit-movil', use: { ...devices['iPhone 13'] } }, ], - webServer: { - command: 'node server/index.mjs', - url: 'http://localhost:4180/api/auth/demo', - reuseExistingServer: true, - timeout: 30_000, - }, + ...(esLocal + ? { + webServer: { + command: 'node server/index.mjs', + url: `${BASE}/salud`, + reuseExistingServer: true, + timeout: 30_000, + }, + } + : {}), }); diff --git a/tests/portal.spec.mjs b/tests/portal.spec.mjs index c05ca93..b4d290c 100644 --- a/tests/portal.spec.mjs +++ b/tests/portal.spec.mjs @@ -503,12 +503,27 @@ test.describe('Legibilidad y responsividad', () => { test('se puede navegar con el teclado desde la entrada', async ({ page }) => { await page.goto('/'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - const enfocado = await page.evaluate(() => document.activeElement?.className ?? ''); - expect(enfocado).toContain('tarjeta-rol'); + // Hay que esperar a que las tarjetas existan: se pintan cuando responde + // la API, y tabular antes deja el foco en cualquier otra cosa. + await expect(page.locator('.tarjeta-rol').first()).toBeVisible(); + + // Se tabula hasta llegar a una tarjeta de acceso, sin fijar cuántos + // saltos hacen falta: lo que se prueba es que sea alcanzable, no la + // posición exacta en el orden. + let enTarjeta = false; + for (let i = 0; i < 8 && !enTarjeta; i++) { + await page.keyboard.press('Tab'); + enTarjeta = await page.evaluate(() => Boolean(document.activeElement?.closest?.('.tarjeta-rol'))); + } + expect(enTarjeta, 'las tarjetas de acceso deben alcanzarse con el tabulador').toBeTruthy(); + + // Y el foco tiene que verse. + const contorno = await page.evaluate(() => getComputedStyle(document.activeElement).outlineStyle); + expect(contorno).not.toBe('none'); + await page.keyboard.press('Enter'); await page.waitForURL('**/portal'); + await expect(page.locator('.barra__nav .nav-item').first()).toBeVisible(); }); test('Escape cierra la ventana de edición sin guardar', async ({ page }) => {