Arseniy Klempner e901f24c9d
feat: consolidate browser testing code into a single package
feat: simplify browser sim image to light push flow
2025-09-05 10:08:16 -07:00

5.0 KiB
Raw Blame History

Waku Browser Tests

Browser-simulated js-waku node running inside headless Chromium, controlled by an Express server. Useful for long-running simulations and realistic verification in CI/Docker.

Architecture

  • Headless browser: Playwright launches Chromium and navigates to a static site built from TypeScript and served by the same server, which exposes window.wakuAPI and window.waku.
  • Server: Express app provides REST endpoints and proxies calls into the browser via page.evaluate(...).
  • Bootstrap module: Small browser-side module in the static site initializes the API and imports @waku/sdk.
  • Shared code: shared/ contains utilities used by tests and for typing.

Prerequisites

  • Node.js 18+
  • Playwright (installed via dev dependency)
  • Docker (optional, for Testcontainers-based tests)

Install & Build

npm install
npm run build

The build compiles the TypeScript server to dist/ and bundles the static site to dist/web/.

Run

# Default configuration (cluster ID 1, auto-sharding)
npm run start:server

# Use cluster ID 2 (for 10k sim compatibility)
npm run start:cluster2

# Use specific cluster and shard
npm run start:cluster2-shard0

# Or with direct CLI arguments
npm run build && node dist/src/server.js --cluster-id=2 --shard=3

This starts the API server and a headless browser.

CLI Arguments

  • --cluster-id=N - Set the Waku cluster ID (default: 1)
  • --shard=N - Set a specific shard for static sharding (0-7, omit for auto-sharding)

Environment variables

  • PORT: API server port (default: 8080; Playwright sets this for tests)
  • WAKU_WS_MULTIADDR: a single ws/wss multiaddr to dial in tests (overrides peers)
  • WAKU_WS_MULTIADDRS: multiple peers as JSON array (e.g. ["/dns4/.../wss/p2p/16U..."]) or comma-separated string; used when WAKU_WS_MULTIADDR is not set

API Endpoints

  • GET / health/status
  • GET /info peer info from the node
  • GET /debug/v1/info debug info/protocols
  • POST /lightpush/v1/message push a message (Waku REST-compatible shape)
  • POST /admin/v1/create-node create a node with networkConfig
  • POST /admin/v1/start-node start the node
  • POST /admin/v1/stop-node stop the node
  • POST /admin/v1/peers dial to peers
  • GET /filter/v2/messages/:contentTopic SSE subscription to messages
  • GET /filter/v1/messages/:contentTopic retrieve queued messages
  • POST /execute helper to execute functions in the browser context (testing/support)

Examples

Push (REST-compatible):

curl -X POST http://localhost:3000/lightpush/v1/message \
  -H "Content-Type: application/json" \
  -d '{
    "pubsubTopic": "/waku/2/rs/1/0",
    "message": {
      "payload": [1,2,3],
      "contentTopic": "/test/1/message/proto"
    }
  }'

Create/Start/Stop:

curl -X POST http://localhost:3000/admin/v1/create-node \
  -H "Content-Type: application/json" \
  -d '{
    "defaultBootstrap": true,
    "networkConfig": { "clusterId": 42, "shards": [0] }
  }'

curl -X POST http://localhost:3000/admin/v1/start-node
curl -X POST http://localhost:3000/admin/v1/stop-node

Dial peers:

curl -X POST http://localhost:3000/admin/v1/peers \
  -H "Content-Type: application/json" \
  -d '{
    "peerMultiaddrs": ["/dns4/example/tcp/8000/wss/p2p/16U..."]
  }'

SSE subscribe:

curl -N "http://localhost:3000/filter/v2/messages/test-topic?clusterId=1&shard=0"

Query queued messages:

curl "http://localhost:3000/filter/v1/messages/test-topic?pageSize=10&ascending=true"

Testing

npm run build
npm test

Playwright will start the server (uses npm run start:server). Ensure the build artifacts exist before running tests.

Docker Usage

Build and run with default configuration:

npm run docker:build
docker run -p 8080:8080 waku-browser-tests:local

Run with cluster ID 2 for 10k sim compatibility:

docker run -p 8080:8080 waku-browser-tests:local --cluster-id=2

Run with specific cluster and shard:

docker run -p 8080:8080 waku-browser-tests:local --cluster-id=2 --shard=0

Or using environment variables:

docker run -p 8080:8080 -e WAKU_CLUSTER_ID=2 -e WAKU_SHARD=0 waku-browser-tests:local

Dockerized tests

tests/docker-server.spec.ts uses Testcontainers. Ensure Docker is running.

Build the image and run only the docker tests locally:

npm run docker:build
npx playwright test tests/docker-server.spec.ts

Notes:

  • The Docker image runs the server with Playwright Chromium and --no-sandbox for container compatibility.
  • Testcontainers will map the container port automatically; the tests probe readiness by waiting for API server running on http://localhost: in logs.

Extending

  • To add new REST endpoints: update src/server.ts and route handlers.
  • To add new browser-executed functions: prefer updating src/assets/bootstrap.js (minimize inline JS in src/server.ts).
  • For shared logic usable in tests, add helpers under shared/.