Files
featherChat/warzone/docs/TESTING_E2E.md
Siavash Sameni 81954b1b0c v0.0.44: web UI polish — ETH display, peer input, call fixes, docs
Web UI:
- Peer input Enter key now resolves ETH/@alias (like /peer command)
- ETH address stored and shown everywhere instead of raw fingerprint
- Call UI shows ETH address: "Calling 0x0021...", "In call with 0x9D70..."
- Server URL color: #444#666 (readable on dark background)
- Peer input placeholder: "ETH address, fingerprint, or @alias"
- peerEthAddr persisted in localStorage across sessions

Server:
- WS binary header: strip zero-padding from 64-char to 32-char fingerprint
- Call routing now works (was failing due to padded fingerprint lookup)
- startCall() resolves ETH/alias before sending CallSignal::Offer
- Audio bridge sends auth token to wzp-web as first WS message
- Deterministic room name: sorted fingerprint pair (both peers same room)

Docs updated:
- SERVER.md: WZP integration section (components, running, TLS, auth flow)
- USAGE.md: voice call usage for web and TUI
- LLM_HELP.md: call architecture, key files, environment vars
- LLM_BOT_DEV.md: note that bots cannot participate in calls
- TESTING_E2E.md: updated WZP prerequisites with correct flags

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 08:32:31 +04:00

12 KiB

featherChat End-to-End Testing Guide

Version: 0.0.43


Prerequisites

Local Testing

# Build everything
cargo build --release --bin warzone-server --bin warzone-client
wasm-pack build crates/warzone-wasm --target web --out-dir ../../wasm-pkg

# Binaries
./target/release/warzone-server
./target/release/warzone-client

Two-Server Testing (Federation)

# Server Alpha
./warzone-server --bind 0.0.0.0:7700 --federation alpha.json --enable-bots --bots-config bots.json

# Server Bravo
./warzone-server --bind 0.0.0.0:7700 --federation bravo.json --enable-bots --bots-config bots.json

Voice Call Testing (requires WZP relay)

# Terminal A: WZP relay (QUIC audio SFU)
./wzp-relay --listen 0.0.0.0:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate

# Terminal B: WZP web bridge (browser WebSocket <-> QUIC)
./wzp-web --port 8080 --relay 127.0.0.1:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate

# Terminal C: featherChat server with relay address
export WZP_RELAY_ADDR=127.0.0.1:8080
./warzone-server

Test 1: Basic Messaging (TUI ↔ TUI)

Setup

# Terminal 1: Server
./target/release/warzone-server

# Terminal 2: User A
./target/release/warzone-client init
./target/release/warzone-client register --server http://localhost:7700
./target/release/warzone-client tui --server http://localhost:7700

# Terminal 3: User B
WARZONE_HOME=~/.warzone-b ./target/release/warzone-client init
WARZONE_HOME=~/.warzone-b ./target/release/warzone-client register --server http://localhost:7700
WARZONE_HOME=~/.warzone-b ./target/release/warzone-client tui --server http://localhost:7700

Steps

  1. User A: Note the ETH address shown at startup (e.g., 0x85e3D8...)
  2. User B: /peer 0x85e3D8e4a6EEfc048fc80497773D440Bf3487D2b
  3. User B: Type Hello! and press Enter
  4. User A: Should see the message with ✓ (sent) → ✓✓ (delivered)
  5. User A: /r Hi back! (reply)
  6. User B: Should see the reply

Verify

  • Messages delivered in real-time (< 1 second)
  • ✓ appears on send, ✓✓ on delivery
  • Timestamps show [HH:MM]
  • ETH address shown in header
  • /info shows both ETH and fingerprint

Test 2: Basic Messaging (Web ↔ Web)

Setup

  1. Open browser tab 1: http://localhost:7700
  2. Click "Generate Identity" → note the ETH address
  3. Open browser tab 2 (incognito): http://localhost:7700
  4. Click "Generate Identity"

Steps

  1. Tab 2: Paste Tab 1's ETH address in the peer input box
  2. Tab 2: Type "Hello from web!" → Send
  3. Tab 1: Should see the message
  4. Tab 1: /peer <tab2_eth_address> → Type "Hi!" → Send
  5. Tab 2: Should see the reply

Verify

  • Messages show with 🔒 prefix (E2E encrypted)
  • ETH address shown in header (click to copy)
  • Markdown renders (bold, code, etc.)
  • Scrollbar visible and working

Test 3: TUI ↔ Web Cross-Client

Steps

  1. Start TUI (User A) and Web (User B) as above
  2. Web: /peer <TUI_eth_address> → Send message
  3. TUI: Should see the message with terminal bell
  4. TUI: /r Hello from terminal!
  5. Web: Should see the reply

Verify

  • Cross-client encryption works (TUI encrypts, Web decrypts and vice versa)
  • Receipts flow correctly between clients

Test 4: Group Messaging

Steps

  1. User A: /gcreate testgroup
  2. User A: /g testgroup
  3. User B: /g testgroup (auto-joins)
  4. User A: Type "Hello group!" → Send
  5. User B: Should see UserA [#testgroup]: Hello group!
  6. User B: Type "Reply!" → Send
  7. User A: Should see the reply

Verify

  • Group creation works
  • Auto-join on /g
  • Messages fan-out to all members
  • /gmembers shows online status (● / ○)

Test 5: Federation (Two Servers)

Setup

# Server Alpha (Terminal 1)
./warzone-server --bind 0.0.0.0:7700 --federation alpha.json

# Server Bravo (Terminal 2)
./warzone-server --bind 0.0.0.0:7701 --data-dir ./data-bravo --federation bravo.json

alpha.json:

{"server_id":"alpha","shared_secret":"test123","peer":{"id":"bravo","url":"http://127.0.0.1:7701"}}

bravo.json:

{"server_id":"bravo","shared_secret":"test123","peer":{"id":"alpha","url":"http://127.0.0.1:7700"}}

Steps

  1. User A connects to Alpha (port 7700)
  2. User B connects to Bravo (port 7701)
  3. Wait 5 seconds for federation presence sync
  4. User A: /peer <UserB_eth_address> → Send message
  5. User B: Should receive the message

Verify

  • Server logs show "Federation: connected to peer"
  • GET /v1/federation/status returns "peer_connected": true
  • Messages route across servers transparently
  • Key bundles proxy via federation (no "Peer not registered")
  • Aliases resolve across servers

Test 6: File Transfer

Steps

  1. Set up two peers (TUI or Web)
  2. Sender: /file /path/to/small-file.txt (must be < 10MB)
  3. Receiver: Should see "Incoming file..." → chunk progress → "File saved: ..."
  4. Verify the file at ~/.warzone/downloads/small-file.txt

Verify

  • SHA-256 integrity check passes
  • File appears in downloads directory
  • Progress shown per chunk

Test 7: Call Signaling

Steps (Web ↔ Web)

  1. User A: Set peer to User B
  2. User A: Click 📞 Call button (or /call)
  3. User B: Should see "📞 Incoming call" with Accept/Reject buttons
  4. User B: Click ✓ Accept
  5. Both: Should see "Call connected!" / "🔊 In call"
  6. Either: Click "End Call" (or /hangup)
  7. Both: Should see "Call ended"

Steps (TUI ↔ TUI)

  1. User A: /call <peer_address>
  2. User A: Header shows yellow "📞 Calling..."
  3. User B: "📞 Incoming call from ... — /accept or /reject"
  4. User B: /accept
  5. User A: Header shows green "🔊 0:00" timer
  6. User A or B: /hangup

Verify

  • Call bar appears in web when peer is set
  • Incoming call notification (pulsing animation in web, bell in TUI)
  • Call state updates in header (TUI) / call bar (web)
  • Hangup/reject cleans up state on both sides

Test 8: Voice Call Audio (requires WZP relay)

Prerequisites

# Terminal 1: WZP relay (QUIC audio SFU)
./wzp-relay --listen 0.0.0.0:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate

# Terminal 2: WZP web bridge (browser WebSocket <-> QUIC)
./wzp-web --port 8080 --relay 127.0.0.1:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate

# Terminal 3: featherChat server
WZP_RELAY_ADDR=127.0.0.1:8080 ./warzone-server

Steps

  1. Open two browser tabs to http://localhost:7700
  2. Tab 1: Set peer to Tab 2
  3. Tab 1: Click 📞 Call
  4. Tab 2: Click ✓ Accept
  5. Both: Allow microphone access when prompted
  6. Speak into mic — other tab should hear audio
  7. End call

Verify

  • "Audio: connecting to ..." message appears
  • "Audio: connected — mic active" confirms WS to relay
  • Audio flows bidirectionally
  • Audio stops on hangup
  • No audio leak after call ends

Test 9: Bot API

Setup

# Server with bots enabled
./warzone-server --enable-bots --bots-config bots.json

Create a bot via BotFather

  1. Open web client
  2. /peer @botfather
  3. Type /newbot TestEchoBot
  4. Note the token from BotFather's reply

Run echo bot

import requests, time
TOKEN = "YOUR_TOKEN_HERE"
API = f"http://localhost:7700/v1/bot/{TOKEN}"
offset = 0
while True:
    r = requests.post(f"{API}/getUpdates", json={"offset": offset, "timeout": 30}).json()
    for u in r.get("result", []):
        offset = u["update_id"] + 1
        msg = u.get("message", {})
        text, cid = msg.get("text"), msg.get("chat", {}).get("id")
        if text and cid:
            requests.post(f"{API}/sendMessage", json={"chat_id": cid, "text": f"Echo: {text}"})
    time.sleep(0.1)

Test messaging the bot

  1. /peer @testechobot
  2. Type "Hello bot!"
  3. Bot should reply "Echo: Hello bot!"

Verify

  • BotFather creates bot and returns token
  • Bot receives plaintext messages (not encrypted)
  • Bot replies appear in chat
  • Markdown in bot replies renders correctly
  • Inline keyboards render as clickable buttons (if bot sends reply_markup)

Test 10: System Bots (from config)

Verify

  1. Start server with --bots-config bots.json
  2. Check data/bot-tokens.txt exists with all tokens
  3. Open web client — welcome screen shows "Available bots: @helpbot, @codebot, ..."
  4. /peer @helpbot → Send "hello" → Bot should respond (if bot process is running)

Test 11: Device Management

Steps

  1. Connect with TUI
  2. Open web client (same identity or different)
  3. TUI: /devices — should list both sessions
  4. TUI: /kick <web_device_id>
  5. Web: Connection should drop

Verify

  • /devices shows device IDs and connection times
  • /kick disconnects the target device
  • Max 5 devices per identity enforced

Test 12: Friend List

Steps

  1. User A: /friend <UserB_address>
  2. User A: /friend (no args) — should list User B with online/offline status
  3. User A: /unfriend <UserB_address>
  4. User A: /friend — should show empty

Verify

  • Friend list persists across restarts (encrypted on server)
  • Online/offline status shown
  • Add/remove works

Test 13: Session Recovery

Steps

  1. Establish a session between two peers (exchange messages)
  2. Delete one peer's session DB: rm -rf ~/.warzone/db/
  3. Restart that peer's TUI
  4. Other peer sends a message
  5. Should see "[session reset]" and then re-establish

Verify

  • "[session reset]" message appears
  • Subsequent messages work after re-X3DH

Test 14: Auto-Backup

Steps

  1. Start TUI client
  2. Wait 5 minutes (or use /backup for immediate)
  3. Check ~/.warzone/backups/ for .wzbk files
  4. Only 3 most recent should exist

Verify

  • /backup creates file immediately
  • Auto-backup runs every 5 minutes
  • Old backups rotated (max 3)

Test 15: Protocol Versioning

Steps

  1. Send a message normally — raw bincode (legacy format)
  2. Check server logs — should accept it
  3. Upgrade client to send envelope format in the future
  4. Old server should still accept legacy
  5. New server accepts both

Verify

  • Legacy (raw bincode) still works
  • Envelope [WZ][v1][len][payload] accepted
  • Future version envelope rejected with clear error

Quick Smoke Test (5 minutes)

If you only have 5 minutes, test these:

  1. ./warzone-server --enable-bots --bots-config bots.json
  2. Open http://localhost:7700 in two browser tabs
  3. Tab 1: Generate identity
  4. Tab 2: Generate identity, /peer <tab1_eth_address>
  5. Tab 2: Send "Hello!" → Tab 1 should see bold text
  6. Tab 1: /peer @botfather/newbot QuickBot → Note token
  7. Start echo bot with the token (Python script above)
  8. Tab 1: /peer @quickbot → "test" → Should get "Echo: test"
  9. Tab 1: /peer <tab2_address> → Click 📞 Call → Tab 2: Accept
  10. Both: Should see "Call connected!" (audio needs WZP relay running)

Troubleshooting

Issue Cause Fix
"Peer not registered" Peer hasn't registered keys Peer needs to open client first
"[message could not be decrypted]" Stale session or cached bundle Clear localStorage (web) or delete session DB
"alias not found" Bot/alias doesn't exist on this server Check --enable-bots, wipe data + restart
No audio WZP relay not running Start wzp-relay + wzp-web + set WZP_RELAY_ADDR
Federation not working Peer server down or wrong config Check GET /v1/federation/status on both
"connection limit reached" 5 devices max /devices/kick old ones
Version mismatch (web) Old service worker cached Hard refresh (Cmd+Shift+R)
Bot not responding Bot process not running Check bot process is polling getUpdates