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.
This commit is contained in:
parent
3b04ebceb3
commit
a3f2929ff7
14 changed files with 708 additions and 0 deletions
125
.forgejo/workflows/e2e.yml
Normal file
125
.forgejo/workflows/e2e.yml
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
# 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue