mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-05-27 09:32:28 +02:00
87ba70acd6
This test asserts that clicking "Remove" on a contact:
1. Surfaces a toast "Removed contact: <name>."
2. Drops the contact from the visible list
The Remove handler in MessagesView dispatches a tight cluster of React
state updates in one event tick:
removeContact(peerId)
locallySavedContactIdsRef.current.delete(peerId)
setContacts(...)
setComposeError('')
setComposeStatus(`Removed contact: ${displayNameForPeer(...)}.`)
Locally those updates settle in <100ms and the toast appears under any
findByText default. Under GitHub Actions runner load — especially the
shared Node.js workers on the "CI Gate / Frontend Tests & Build" step
— the reconcile-and-paint cycle has been measured at ~1.4s, which
exceeds the 1s default findByText timeout.
This is a load-sensitive timing flake, not a real bug — the toast
always renders eventually because the state update chain is purely
synchronous and the displayed text comes from the closure's pre-update
contacts (so the "Remove Me" name is always available when the toast
finally renders).
Historical flake hits in CI on this exact assertion:
PR #226 (zh-CN i18n landing, exposed by i18n parse error)
PR #237 (GitLab mirror parity)
PR #261 (post-#227 audit gap closures)
PR #262 (AIS SPKI pinning — failed post-merge Docker Publish,
skipping image publication for commit 729ea78)
The last one is the worst — a post-merge flake that blocked the
Docker image for an actual security fix from being published. The
subsequent merge of #263 cumulatively re-published the image, but
that's by accident, not by design.
Fix: replace the 1-second findByText with waitFor + 5s timeout +
50ms polling. The 5s ceiling still surfaces a real "toast never
renders" regression with a clear error; it just doesn't get racy
under CI load anymore.
Validation:
Local sequential 10x run of just this test → 10 passed, 0 failed
Full vitest suite → 707 passed, 72 files
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ShadowBroker Frontend
Next.js 16 dashboard with MapLibre GL, Cesium, and Framer Motion.
Development
npm install
npm run dev # http://localhost:3000
API URL Configuration
The frontend needs to reach the backend (default port 8000). Resolution order:
NEXT_PUBLIC_API_URLenv var — if set, used as-is (build-time, baked by Next.js)- Server-side (SSR) — falls back to
http://localhost:8000 - Client-side (browser) — auto-detects using
window.location.hostname:8000
Common scenarios
| Scenario | Action needed |
|---|---|
Local dev (localhost:3000 + localhost:8000) |
None — auto-detected |
LAN access (192.168.x.x:3000) |
None — auto-detected from browser hostname |
| Public deploy (same host, port 8000) | None — auto-detected |
Backend on different port (e.g. 9096) |
Set NEXT_PUBLIC_API_URL=http://host:9096 before build |
| Backend on different host | Set NEXT_PUBLIC_API_URL=http://backend-host:8000 before build |
Behind reverse proxy (e.g. /api path) |
Set NEXT_PUBLIC_API_URL=https://yourdomain.com before build |
Setting the variable
# Shell (Linux/macOS)
NEXT_PUBLIC_API_URL=http://myserver:8000 npm run build
# PowerShell (Windows)
$env:NEXT_PUBLIC_API_URL="http://myserver:8000"; npm run build
# Docker Compose (set in .env file next to docker-compose.yml)
NEXT_PUBLIC_API_URL=http://myserver:8000
Note: This is a build-time variable. Changing it requires rebuilding the frontend.
Theming
Dark mode is the default. A light/dark toggle is available in the left panel toolbar.
Theme preference is persisted in localStorage as sb-theme and applied via
data-theme attribute on <html>. CSS variables in globals.css define all
structural colors for both themes.