Causa raíz, encontrada reproduciéndolo con el bundle de producción en local
—con el servidor de desarrollo NO se ve, y por eso llevaba semanas dándose por
un artefacto del navegador sin pantalla:
if ((centerStored !== [0, 0] || geolocation.get()) && geoInit) {
center.set(centerStored || geolocation.get());
geoInit = false;
}
`centerStored !== [0, 0]` compara contra un array recién creado: es SIEMPRE
cierto. En un navegador nuevo —sin centro en localStorage y con la
geolocalización todavía sin resolver— eso hacía `center.set(undefined)` y dejaba
`geoInit` en false, o sea para siempre. Un `<MapContainer>` sin `center` no
recibe `setView`, y un mapa de Leaflet sin vista no carga capa base ni teselas
ni dispara `whenReady`, con lo que tampoco se creaba la suscripción por
viewport. En desarrollo no pasaba porque la geolocalización llegaba a tiempo.
Y de paso el "Actualizando…" que no se quitaba nunca: las suscripciones se
creaban dentro de un `Tracker.autorun` ANIDADO en el withTracker. La computación
de fuera no dependía de `mapSize`, así que `loading` se calculaba con
`subscription` a undefined y no volvía a recalcularse; además cada pasada del
withTracker dejaba otro autorun sin parar. Ahora las suscripciones se crean en
la propia computación reactiva, que es donde Meteor sabe pararlas al invalidarse.
MapReady, además, vigila el contenedor con un ResizeObserver: su comprobación de
tamaño solo podía reintentar con el evento `resize` de Leaflet, que no se emite
si nadie llama a invalidateSize(). No era la causa de esto, pero hacía que la
comprobación no sirviera de nada.
La suite e2e deja de usar selectores por id: TestUtils.testId() los devuelve solo
en desarrollo, así que contra el bundle de producción —lo que levanta el job
nocturno— no existían y la suite entera habría fallado esta noche.
Verificado contra bundle de producción: /fires pasa de 0 teselas y 0 capas a 12
teselas, capa base y las dos suscripciones por viewport, sin "Actualizando…".
90 tests de servidor, 16 e2e y smoke REST byte-idéntico.
|
||
|---|---|---|
| .. | ||
| support | ||
| tests | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.js | ||
| README.md | ||
| seed.js | ||
| staging-qa.mjs | ||
Suite e2e (Playwright)
Cubre en navegador los flujos que la suite de servidor no puede ver: registro y
acceso, alta y baja de una zona desde el mapa, que la unión de zonas se pinte
en /subscriptions y en /zones, comentario en el detalle de un fuego, y cambio
de idioma.
El motivo de que exista: el 2026-07-30 suscribirse a una zona congeló staging (la unión bloqueaba el event loop y DDP dejaba de responder). Ningún test de servidor habría visto eso — el navegador sí.
⚠️ Contra qué se puede correr
Solo contra un stack desechable: docker-compose.e2e.yml o un servidor de
desarrollo local. La siembra (e2e/seed.js) borra colecciones, y los tests
crean usuarios y zonas. playwright.config.js se niega a arrancar si
E2E_BASE_URL apunta a testfuegos.comunes.org o a los dominios de producción.
Uso
Stack efímero completo (lo mismo que hace el CI):
docker compose -f docker-compose.e2e.yml up -d --build
npm --prefix e2e ci
npx --prefix e2e playwright install --with-deps chromium
E2E_BASE_URL=http://localhost:3300 npm --prefix e2e test
docker compose -f docker-compose.e2e.yml down -v
Contra un servidor de desarrollo (ciclo rápido mientras se escriben tests):
docker run -d --name tcef-e2e-mongo -p 27021:27017 --tmpfs /data/db mongo:7 --replSet rs0 --bind_ip_all
docker exec tcef-e2e-mongo mongosh --quiet --eval 'rs.initiate({_id:"rs0",members:[{_id:0,host:"localhost:27017"}]})'
docker cp e2e/seed.js tcef-e2e-mongo:/tmp/seed.js && docker exec tcef-e2e-mongo mongosh --quiet fuegos /tmp/seed.js
export PATH="$HOME/.meteor:$PATH"
MONGO_URL='mongodb://localhost:27021/fuegos?replicaSet=rs0&directConnection=true' \
MONGO_OPLOG_URL='mongodb://localhost:27021/local?replicaSet=rs0&directConnection=true' \
ROOT_URL=http://localhost:3100 meteor --settings settings-ci.json --port 3100
npm --prefix e2e test # E2E_BASE_URL por defecto: http://localhost:3100
Ver el informe del último fallo: npm --prefix e2e run report.
Dependencias externas
El navegador carga las teselas de CartoDB y el script de Google Maps (el
autocompletado de lugares). El runner necesita salida a internet; sin ella los
mapas no llegan a pintarse y los tests de zona fallan. La clave de Google puede
ir vacía: Gkeys ya no se queda esperándola.
Lo que la suite documenta como roto
i18n.spec.js deja un test.fixme para un bug real: el idioma elegido en el
perfil no sobrevive a una recarga (se guarda en la cuenta y se aplica al
iniciar sesión, pero al recargar vuelve al idioma del navegador). Está ahí para
que aparezca en cada ejecución en vez de perderse en una nota.