---
name: web-ui-test
description: >-
  Prueba interfaces de aplicaciones web (navegación, interacción, capturas, errores de consola) usando
  un navegador headless vía Playwright CLI — pensado para correr desde un tunnel remoto de VS Code sin
  GUI. Instala Playwright y su navegador automáticamente si no están presentes. Triggers: "prueba esta
  interfaz", "prueba la web app", "test this UI", "revisa la interfaz", "haz un smoke test", "prueba el
  flujo de login/registro/checkout", "captura screenshots de la app".
effort: medium
argument-hint: "[URL a probar, o descripción del flujo a validar]"
---

# web-ui-test — Probar interfaces web con Playwright headless

Prueba interfaces de aplicaciones web navegando, interactuando y capturando evidencia con un navegador
**headless** vía `@playwright/cli`. Diseñada para correr desde un tunnel remoto de VS Code (sin display
local) — nunca intenta abrir un navegador con GUI.

Skill global, autosuficiente: no depende de ningún plugin instalado (por ejemplo `c3po`), solo de
`npm`/`npx` disponibles en el PATH.

## 1. Preflight — verificar/instalar Playwright de forma global

Ejecuta primero, siempre:

```bash
npm ls -g --depth=0 2>/dev/null | grep -q "@playwright/cli" && echo CLI_OK=1 || echo CLI_OK=0
npm ls -g --depth=0 2>/dev/null | grep -qw "playwright" && echo PW_OK=1 || echo PW_OK=0
ls ~/.cache/ms-playwright 2>/dev/null | grep -qi chromium && echo BROWSER_OK=1 || echo BROWSER_OK=0
```

- Si `CLI_OK=0` o `PW_OK=0` → instalar de forma global:
  ```bash
  npm install -g @playwright/cli playwright
  ```
- Si `BROWSER_OK=0` → instalar el navegador **por defecto sin dependencias de sistema**:
  ```bash
  playwright install chromium
  ```
- Si todo ya está OK (`CLI_OK=1`, `PW_OK=1`, `BROWSER_OK=1`) → **saltar este paso por completo** y pasar
  directo a la sección 3.

**Importante**: `@playwright/cli` usa por defecto el canal `chrome` (Google Chrome real, no instalado
aquí), no el Chromium que acabas de instalar con `playwright install chromium`. Por eso **todo comando
que abra un navegador debe incluir `--browser chromium` explícitamente** (ver sección 3) — si lo omites,
falla con `Chromium distribution 'chrome' is not found at /opt/google/chrome/chrome` aunque la
instalación haya sido exitosa.

### Fallback automático (solo si falla, nunca por defecto)

Si al abrir una sesión (sección 3) el error indica librerías de sistema faltantes (mensajes tipo
"missing libraries", "host system is missing dependencies"), reintenta automáticamente, sin preguntar:

```bash
playwright install --with-deps chromium
# si falla por permisos:
sudo npx playwright install-deps chromium
```

Luego repite la operación que había fallado. Este camino solo se dispara ante ese error concreto — no lo
ejecutes de forma preventiva ni la primera vez que instalas el navegador.

## 2. Reglas headless (no negociable)

- **Nunca** pases `--headed` ni cambies `PWDEBUG`. Este entorno es un tunnel remoto sin display: todo
  corre headless, siempre.
- Usa sesiones nombradas (`-s=<slug>`) en kebab-case para trazabilidad y para poder limpiar sesiones
  huérfanas de corridas anteriores.

## 3. Ciclo de vida de sesión — abrir → interactuar → cerrar

Toda tarea sigue el patrón **abrir → interactuar → cerrar**. El cierre es obligatorio, incluso si algo
falló antes (equivalente a un `finally`).

```bash
# Abrir — SIEMPRE con --browser chromium (ver nota en sección 1)
npx @playwright/cli -s=$SESSION open "$URL" --browser chromium

# Interactuar (snapshot → actuar → re-snapshot)
npx @playwright/cli -s=$SESSION snapshot
npx @playwright/cli -s=$SESSION click e15
npx @playwright/cli -s=$SESSION snapshot

# Cerrar (SIEMPRE, incluso si algo anterior falló)
npx @playwright/cli -s=$SESSION close
```

### Comandos disponibles

- **Navegación**: `open <url> --browser chromium`, `goto <url>`, `go-back`, `go-forward`, `reload`
- **Inspección**: `snapshot` (árbol de accesibilidad con refs `e15`, `e21`...), `screenshot [--full-page] --filename ...`, `pdf --filename ...`
- **Interacción**: `click <ref>`, `fill <ref> "texto"`, `type "texto"`, `select <ref> "valor"`, `check/uncheck <ref>`, `upload /ruta/archivo`
- **Teclado/mouse**: `press <tecla>`, `hover <ref>`, `drag <ref-origen> <ref-destino>`
- **Pestañas**: `tab-list`, `tab-new <url> --browser chromium`, `tab-select <n>`, `tab-close <n>`
- **Estado de auth**: `state-save <archivo.json>`, `state-load <archivo.json>`
- **Diagnóstico**: `console error`, `network`, `eval "() => document.readyState"`
- **Gestión de sesiones**: `list`, `close`, `close-all`, `kill-all`

## 4. Verificación de carga de página

Antes de interactuar con el contenido, confirma que la página cargó:

```bash
npx @playwright/cli -s=$SESSION eval "() => document.readyState"
```

- `"complete"` → continuar
- `"loading"` / `"interactive"` → esperar ~2s y reintentar (máx. 3 chequeos, sin `sleep` arbitrario más
  allá de esa espera corta)

## 5. Secuencia estándar de captura

Cuando la tarea es "revisar/probar esta página":

```bash
mkdir -p .local/screenshots

npx @playwright/cli -s=$SESSION open "$URL" --browser chromium
npx @playwright/cli -s=$SESSION eval "() => document.readyState"
npx @playwright/cli -s=$SESSION screenshot --filename .local/screenshots/$SESSION-viewport.png
npx @playwright/cli -s=$SESSION screenshot --full-page --filename .local/screenshots/$SESSION-full.png
npx @playwright/cli -s=$SESSION snapshot --filename .local/screenshots/$SESSION-snapshot.md
npx @playwright/cli -s=$SESSION console error
npx @playwright/cli -s=$SESSION close
```

**Artefactos siempre a disco** en `.local/screenshots/` (relativo al directorio del proyecto actual).
Nunca vuelques el snapshot completo, HTML crudo, o el contenido de las capturas en el chat — solo reporta
las rutas y un resumen.

## 6. Flujos interactivos (probar un flujo, no solo una página)

Cuando el usuario pide validar un flujo (login, checkout, registro, etc.):

1. `snapshot` para obtener refs frescos.
2. Actuar (`click`/`fill`/`select`/`check`) sobre esos refs.
3. **Re-snapshot después de cualquier acción que cambie el DOM** — los refs quedan obsoletos tras
   mutaciones.
4. Si un elemento esperado no aparece tras 2 reintentos con snapshot fresco, repórtalo como fallo del
   paso en vez de seguir a ciegas.
5. Captura screenshot en cada momento relevante del flujo (no solo al final).

## 7. App local vs URL remota

- Si el usuario pide probar "la app" sin dar URL y el proyecto tiene un servidor de desarrollo definible
  (`package.json` con script `dev`/`start`, etc.), levanta ese servidor primero y espera a que responda
  antes de abrir la sesión de Playwright.
- Si el usuario da una URL explícita, úsala directamente sin intentar levantar nada.

## 8. Formato de reporte final

Resumen breve, no el contenido crudo:

```
URL probada: ...
Sesión: ...
Acciones realizadas: ...
Artefactos: .local/screenshots/...-viewport.png, .../...-full.png, .../...-snapshot.md
Errores de consola: {cantidad, o "ninguno"}
Hallazgos: {bugs de UX/funcionalidad si los hay}
Estado de la sesión: cerrada / falló el cierre (requiere kill-all)
```

## 9. Limpieza y recuperación

- Cierra la sesión siempre, incluso si algo falló antes.
- Si el cierre mismo falla, ejecuta `npx @playwright/cli kill-all` como recuperación.
- Si hay sospecha de sesiones huérfanas de una corrida anterior, revisa con `npx @playwright/cli list`
  antes de abrir una nueva con el mismo nombre.

## Qué NO hacer

- No pases `--headed` ni intentes abrir una GUI: este entorno no tiene display.
- No vuelques snapshots de DOM, HTML o contenido de screenshots en el texto de respuesta — guarda a
  disco y reporta la ruta.
- No dejes una sesión abierta al terminar, ni siquiera cuando algo falló.
- No interactúes con refs sin un snapshot fresco después de cambios en el DOM.
- No instales dependencias de sistema (`--with-deps` / `sudo apt`) de forma preventiva — solo como
  fallback automático ante un error concreto de librerías faltantes (ver sección 1).
