# Testing — 1v9: Convertite en Leyenda Este documento describe el workflow de testing que usamos para verificar el juego de punta a punta. Es reproducible en cualquier máquina con Node.js ≥18 y Python 3 + Playwright. --- ## 1. Validación de sintaxis JS Extraemos el `', open('index.html').read(), re.S).group(1))" node --check /tmp/game.js && echo "JS OK" ``` Esto detecta errores de sintaxis antes de tocar el navegador. --- ## 2. Smoke test local (Playwright) Levantamos un servidor estático y jugamos una carrera completa con un bot, detectando errores de consola y fallos de red: ```bash python3 -m http.server 8899 --bind 0.0.0.0 & ``` Un script Playwright (chromium headless) que: 1. Abre la página en viewport móvil (390×844). 2. Completa la creación de player. 3. Elige una oferta de academia. 4. Juega hasta el resumen (clic en opciones/continuar). 5. Captura **0 errores de consola**, **0 requests fallidos** y que el resumen se muestre. ```python from playwright.async_api import async_playwright async def main(): async with async_playwright() as p: browser = await p.chromium.launch() page = await browser.new_page(viewport={"width":390,"height":844}) errs = [] page.on("pageerror", lambda e: errs.append(str(e))) page.on("console", lambda m: errs.append(m.text) if m.type=="error" else None) page.on("requestfailed", lambda r: errs.append(r.url)) await page.goto("http://127.0.0.1:8899/") # ... click thru ... print("ERRORS:", errs) ``` --- ## 3. Layout check (sin lectura de imágenes) Como el modelo no puede ver screenshots, verificamos el layout programáticamente: - **Overflow horizontal**: `document.documentElement.scrollWidth > window.innerWidth` debe ser `false`. - **Timeline colapsada en mobile**: el `.tl-body` debe tener la clase `closed` por default en viewport <768px. - **Design tokens**: `getComputedStyle(document.documentElement)` debe devolver `--accent-ovr:#d9730a`, etc. --- ## 4. Verificación de mecánicas (tests dirigidos) ### Gating de competencias (1ª división) Empezar en un equipo de **2ª división** y confirmar que NO aparecen eventos internacionales hasta ascender a 1ª. Se rastrea el `dc-cat` de cada decisión contra el `G.div`. ### Cadencia de fichajes Jugar y registrar en qué splits aparecen eventos "Fichaje". Debe ser **≥ split 4** y ~2 por carrera (no en cada split). ### Diversidad de competencias Jugar 10+ carreras y confirmar que aparecen las 5 (First Stand, MSI, EWC, Asian Games, Worlds). ### Stats / backend Verificar que `G.stats` no tenga claves fantasma (`valor`) ni `NaN` al final de la carrera. --- ## 5. Export de imagen Se fuerza el fin de carrera con datos de prueba, se clickea "Descargar imagen" y se valida el PNG con PIL: ```python from PIL import Image img = Image.open(path) print(img.size, img.mode) # 1080x1920 RGBA print(img.convert('RGB').getpixel((100,100))) # ~(10,10,12) dark bg print(img.convert('L').getextrema()) # rango de luminancia (texto presente) ``` --- ## 6. Test final contra producción (HTTPS) Repetimos los smoke tests contra `https://lolero.cbcren.online` (no solo local), para validar el deploy real (Caddy + TLS + serve de logos). --- ## Resultado esperado - 0 errores de consola, 0 requests fallidos. - Resumen alcanzado en 100% de las carreras. - Sin overflow horizontal en desktop ni mobile. - Export 1080×1920 PNG válido. - Las 5 competencias aparecen; fichajes ≥ split 4; 2ª división no va a internacionales.