23 KiB
@suaveplan/testbed
A live demonstration app for every @suaveplan library, running against real services. Each page exercises the actual library API — no stubs, no mocks.
Documentation tree
- console-panel —
ConsolePanelinterceptswindow.console.log,warn, anderroron mount and renders each captured message in an in… - header —
Headeris the top-level application bar for the testbed. It displays the app title on the left and renders `LocaleSwi… - locale-switcher —
LocaleSwitcherrenders a<select>allowing the user to switch between the four supported locales (en,fr,de,… - sidebar —
Sidebarrenders the primary navigation for the testbed as a vertically scrollable nav panel. Routes are grouped by th… - theme-toggle —
ThemeToggleis a button that toggles betweenlightanddarkvisual themes. It applies the theme by setting a `dat… - code-block —
CodeBlockrenders a preformatted code snippet with monospace styling and an optional language label. It is used on li… - demo-card —
DemoCardis the standard wrapper for every interactive library demonstration in the testbed. It provides a consistent… - status-badge —
StatusBadgerenders a colored pill badge indicatingok,error, orpendingstate. It is used on library demo pag… - crypto — (no submodules) <!-- en…
- crypto-page — (no submodules) <!-- en…
- datetime — (no submodules) <!-- en…
- datetime-page — (no submodules) <!-- en…
- extension-test — (no submodules) <!-- en…
- extension-test-page — (no submodules) <!-- en…
- feature-flags — (no submodules) <!-- en…
- feature-flags-page — (no submodules) <!-- en…
- home — (no submodules) <!-- en…
- home-page — (no submodules) <!-- en…
- i18n — (no submodules) <!-- en…
- i18n-page — (no submodules) <!-- en…
- logger — (no submodules) <!-- en…
- logger-page — (no submodules) <!-- en…
- network-broadcast — (no submodules) <!-- en…
- network-broadcast-page — (no submodules) <!-- en…
- network-webrtc — (no submodules) <!-- en…
- network-webrtc-page — (no submodules) <!-- en…
- network-websocket — (no submodules) <!-- en…
- network-websocket-page — (no submodules) <!-- en…
- storage-s3 — (no submodules) <!-- en…
- storage-s3-page — (no submodules) <!-- en…
- surrealdb — (no submodules) <!-- en…
- surrealdb-page — (no submodules) <!-- en…
Overview
The testbed is a React 19 SPA served by a Hono/Bun server. The client runs library demos entirely in the browser (crypto, logger, datetime, i18n, feature-flags) or proxies requests to the server for service-backed operations (S3, SurrealDB, WebRTC signalling, WebSocket relay).
Quick Start
# From monorepo root
bun install
bun run dev --filter=@suaveplan/testbed
# Or directly in this directory
bun run dev
The app starts at http://localhost:3200.
Services
Optional services are detected at page load via a /api/*/status health check. Pages gracefully degrade when services are unavailable.
| Service | Env Vars | Default |
|---|---|---|
| Garage S3 | GARAGE_S3_ENDPOINT, GARAGE_S3_ACCESS_KEY_ID, GARAGE_S3_SECRET_ACCESS_KEY, GARAGE_S3_BUCKET |
testbed |
| SurrealDB | SURREALDB_URL, SURREALDB_USERNAME, SURREALDB_PASSWORD |
root/root |
Running E2E Tests
# All browsers
bun run test:e2e
# Chromium only
bunx playwright test --project=chromium
# Specific spec file
bunx playwright test e2e/libraries/crypto.spec.ts
# Extension tests (requires chromium-extensions project)
bunx playwright test --project=chromium-extensions e2e/extensions/
The Playwright web server auto-starts bun run dev on port 3200 if not already running.
Multi-Session Tests
Multi-session tests in e2e/multi-session/ open multiple browser contexts to simulate real-time scenarios:
- broadcast-channel.spec.ts — sender broadcasts via
BroadcastChannel; receiver tab receives messages. Runs entirely in-browser (no server needed). - websocket-gateway.spec.ts — sender and receiver connect to the WebSocket relay server at
/api/ws. - webrtc-mesh.spec.ts — host and peer pages complete a WebRTC handshake via
/api/signalling. - webrtc-server-failover.spec.ts — verifies graceful handling when the signalling endpoint returns 503.
All multi-session tests use createMultiSession from @suaveplan/testing-e2e/multi-session.
Extension Tests
Extension tests in e2e/extensions/ use launchWithExtension from @suaveplan/testing-e2e/extension-fixture to launch Chromium with a sideloaded test extension.
Place your test extension at e2e/fixtures/test-extension/. The extension should inject <div id="extension-injected">...</div> into the page for detection.
bunx playwright test --project=chromium-extensions
data-testid Contract
Every page exposes these stable selectors for E2E tests:
| Selector | Element |
|---|---|
[data-testid="page-title"] |
<h1> with page/library name |
[data-testid="demo-card"] |
Wraps interactive demo area |
[data-testid="output"] |
Live result display |
[data-testid="console-panel"] |
Console capture panel |
[data-testid="header"] |
Top navigation bar |
[data-testid="sidebar"] |
Left navigation sidebar |
[data-testid="library-card"] |
Library cards on home page |
[data-testid="locale-select"] |
Locale dropdown on i18n page |
[data-testid="message-input"] |
WS/WebRTC/Broadcast input |
[data-testid="send-button"] |
Send button on network pages |
[data-testid="extension-mount"] |
Extension injection target |
[data-status="<status>"] |
Connection status indicator |
Console Panel
Each page has a [data-testid="console-panel"] section that documents the library operations in use. It is informational only — it does not capture actual browser console output. Console baseline tests use attachConsoleMonitor from @suaveplan/testing-e2e/console-monitor to assert no unexpected errors.
Test Control API
In test mode (NODE_ENV=test), the server mounts testControlRoutes at /api/test-control:
| Method | Path | Description |
|---|---|---|
| POST | /api/test-control/disable-route |
Temporarily returns 503 for a given API route |
Used by simulateServerFailure from @suaveplan/testing-e2e/multi-session.
Env-Bridge Variables
| Variable | Used By | Description |
|---|---|---|
GARAGE_S3_ENDPOINT |
Storage S3 page | Garage S3-compatible endpoint URL |
GARAGE_S3_ACCESS_KEY_ID |
Storage S3 page | S3 access key ID |
GARAGE_S3_SECRET_ACCESS_KEY |
Storage S3 page | S3 secret access key |
GARAGE_S3_BUCKET |
Storage S3 page | S3 bucket name (default: testbed) |
SURREALDB_URL |
SurrealDB page | SurrealDB connection URL |
SURREALDB_USERNAME |
SurrealDB page | SurrealDB username (default: root) |
SURREALDB_PASSWORD |
SurrealDB page | SurrealDB password (default: root) |
PORT |
Server | HTTP listen port (default: 3200) |
Routes Manifest
| Path | Library/Feature | Category | Services |
|---|---|---|---|
/ |
Testbed home | home | |
/crypto |
@suaveplan/crypto |
crypto | |
/logger |
@suaveplan/logger |
observability | |
/datetime |
@suaveplan/datetime |
primitives | |
/i18n |
@suaveplan/i18n |
primitives | |
/feature-flags |
@suaveplan/feature-flags |
primitives | |
/storage-s3 |
Storage — S3 | storage | Garage |
/surrealdb |
SurrealDB | database | SurrealDB |
/network-webrtc |
Network — WebRTC | network | Signalling |
/network-websocket |
Network — WebSocket | network | WS relay |
/network-broadcast |
Network — BroadcastChannel | network | |
/extension-test |
Extension Test | extensions |
Port Allocation
| Port | Service |
|---|---|
| 3200 | Testbed dev/prod server |
| 6042 | Storybook |