todos-contra-el-fuego-web/.forgejo/workflows/e2e.yml
vjrj a3f2929ff7 test(e2e): browser suite for the flows the server tests cannot see
Playwright under e2e/, its own npm project so Meteor never sees the dependency
(.meteorignore keeps the directory out of the bundle — a config file at the app
root is otherwise eagerly loaded into the server and crashes it).

Covers what the phase asked for: sign up / log in, creating a zone from the map
and watching the union get painted on /subscriptions and /zones, removing it
again, commenting on a fire, and switching language. The zone spec is the flow
that froze staging on 2026-07-30 — it passes only if the server is still
answering DDP while the union is recomputed.

docker-compose.e2e.yml is a throwaway stack (Mongo on tmpfs, no named volume) so
the destructive seeds cannot be pointed at anything real by accident;
playwright.config.js refuses to start against the staging or production domains.

i18n.spec.js leaves a test.fixme on a real bug found while writing it: the
language chosen in the profile does not survive a page reload.
2026-08-01 18:44:09 +02:00

125 lines
5 KiB
YAML

# Suite de navegador (Playwright) + smoke REST contra un stack EFÍMERO.
#
# POR QUÉ NOCTURNO Y NO EN CADA PUSH: esto construye el bundle de producción
# entero (`meteor build`, lo mismo que hace la imagen) y además baja un Chromium.
# aaron es un host compartido con `capacity: 1`: si esto corriera en cada push,
# la forja se quedaría sin turno. Los tests de servidor (build-image.yml) sí van
# en cada push y son los que bloquean la imagen.
#
# POR QUÉ NO USA docker compose: el runner no tiene socket de Docker (ver la nota
# de build-image.yml) — así que en vez de levantar docker-compose.e2e.yml, este
# job construye el bundle y lo arranca dentro de su propio contenedor, con Mongo
# como service container. El compose sigue siendo la forma de correrlo en local.
#
# ⚠️ Las dos siembras (smoke/seed.js y e2e/seed.js) BORRAN colecciones. Aquí eso
# es seguro porque el Mongo es un service container que muere con el job. Jamás
# apuntes esto a testfuegos.comunes.org.
name: e2e
on:
schedule:
# 04:15 UTC, con el runner libre.
- cron: '15 4 * * *'
workflow_dispatch:
jobs:
e2e:
runs-on: docker
container:
image: node:22-bookworm
# El pico es el `meteor build`, igual que en el job de la imagen.
options: --memory=4g --memory-swap=4g --cpus=3
services:
mongo:
image: mongo:7
# Nodo suelto, sin replica set: los service containers no dejan cambiar
# el comando de arranque. Sin oplog Meteor cae a polling (cada 10s), así
# que los tests que esperan a la unión tardan más — por eso sus timeouts
# son de 60s. En local (docker-compose.e2e.yml) sí hay replica set.
options: >-
--health-cmd "mongosh --quiet --eval 'db.adminCommand({ping:1}).ok'"
--health-interval 5s --health-timeout 5s --health-retries 20
env:
METEOR_ALLOW_SUPERUSER: '1'
NODE_OPTIONS: --dns-result-order=ipv4first --no-network-family-autoselection
METEOR_RELEASE: '3.1'
MONGO_URL: mongodb://mongo:27017/fuegos
ROOT_URL: http://localhost:3000
PORT: '3000'
BASE_URL: http://localhost:3000
E2E_BASE_URL: http://localhost:3000
SETTINGS: settings-ci.json
steps:
- name: Herramientas
run: |
set -e
apt-get update -qq
apt-get install -y --no-install-recommends \
curl ca-certificates git python3 python-is-python3 make g++ >/dev/null
# mongosh por npm: el cliente no viene en node:22 y el service container
# de mongo no es accesible con `docker exec` desde el job.
npm install -g mongosh@2 >/dev/null
- name: Descargar el código
env:
TOKEN: ${{ github.token }}
run: |
set -e
mkdir -p src
wget -q -O src.tar.gz \
"http://x-access-token:${TOKEN}@forgejo:3000/api/v1/repos/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
tar xzf src.tar.gz -C src --strip-components=1
rm -f src.tar.gz
- name: Instalar meteor-tool
run: curl -fsSL "https://install.meteor.com/?release=${METEOR_RELEASE}" | sh
- name: Construir el bundle de producción
run: |
set -e
cd src
meteor npm ci --no-audit --no-fund
meteor build /tmp/build --directory --server-only
cd /tmp/build/bundle/programs/server && npm install --omit=dev --no-audit --no-fund
- name: Arrancar el servidor
run: |
set -e
cd /tmp/build/bundle
METEOR_SETTINGS="$(cat "${GITHUB_WORKSPACE}/src/settings-ci.json")" \
node main.js > /tmp/server.log 2>&1 &
for i in $(seq 1 90); do
wget -qO /dev/null "http://127.0.0.1:3000/" && break
sleep 2
done
wget -qO /dev/null "http://127.0.0.1:3000/" || { echo "El servidor no arrancó:"; tail -50 /tmp/server.log; exit 1; }
# El smoke va primero y con su propia siembra: compara respuestas byte a
# byte contra snapshots, así que cualquier dato que dejen los e2e (una
# suscripción, la unión recalculada) lo haría fallar.
- name: Smoke REST
run: |
set -e
cd src
mongosh --host mongo --quiet fuegos smoke/seed.js
node smoke/run.js
- name: Suite e2e
run: |
set -e
cd src
mongosh --host mongo --quiet fuegos e2e/seed.js
npm --prefix e2e ci --no-audit --no-fund
npx --prefix e2e playwright install --with-deps chromium
npx --prefix e2e playwright test
# Sin `actions/upload-artifact` (action JS, ver fase 9 §3): al menos el log
# del servidor y la lista de trazas quedan en la salida del job.
- name: Diagnóstico en caso de fallo
if: failure()
run: |
echo "===== últimas 200 líneas del servidor ====="
tail -200 /tmp/server.log || true
echo "===== trazas de Playwright ====="
ls -R src/e2e/test-results 2>/dev/null | head -50 || true