From 5bbc197369f281ff0efccb1250a6d2303b30d988 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Sun, 29 Mar 2026 20:34:56 +0400 Subject: [PATCH] docs: comprehensive E2E testing guide (15 test scenarios + quick smoke test) Co-Authored-By: Claude Opus 4.6 (1M context) --- warzone/docs/TESTING_E2E.md | 409 ++++++++++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 warzone/docs/TESTING_E2E.md diff --git a/warzone/docs/TESTING_E2E.md b/warzone/docs/TESTING_E2E.md new file mode 100644 index 0000000..e75c2d9 --- /dev/null +++ b/warzone/docs/TESTING_E2E.md @@ -0,0 +1,409 @@ +# featherChat End-to-End Testing Guide + +**Version:** 0.0.43 + +--- + +## Prerequisites + +### Local Testing + +```bash +# 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) + +```bash +# 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) + +```bash +# Start WZP web bridge (from warzone-phone repo) +./wzp-web --bind 0.0.0.0:8080 --relay 127.0.0.1:4433 + +# Start WZP relay +./wzp-relay --bind 0.0.0.0:4433 + +# Set relay address for featherChat +export WZP_RELAY_ADDR=127.0.0.1:8080 +``` + +--- + +## Test 1: Basic Messaging (TUI ↔ TUI) + +### Setup +```bash +# 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 +- [x] Messages delivered in real-time (< 1 second) +- [x] ✓ appears on send, ✓✓ on delivery +- [x] Timestamps show [HH:MM] +- [x] ETH address shown in header +- [x] `/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 ` → Type "Hi!" → Send +5. **Tab 2**: Should see the reply + +### Verify +- [x] Messages show with 🔒 prefix (E2E encrypted) +- [x] ETH address shown in header (click to copy) +- [x] Markdown renders (**bold**, `code`, etc.) +- [x] 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 ` → Send message +3. **TUI**: Should see the message with terminal bell +4. **TUI**: `/r Hello from terminal!` +5. **Web**: Should see the reply + +### Verify +- [x] Cross-client encryption works (TUI encrypts, Web decrypts and vice versa) +- [x] 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 +- [x] Group creation works +- [x] Auto-join on `/g` +- [x] Messages fan-out to all members +- [x] `/gmembers` shows online status (● / ○) + +--- + +## Test 5: Federation (Two Servers) + +### Setup +```bash +# 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`: +```json +{"server_id":"alpha","shared_secret":"test123","peer":{"id":"bravo","url":"http://127.0.0.1:7701"}} +``` + +`bravo.json`: +```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 ` → Send message +5. **User B**: Should receive the message + +### Verify +- [x] Server logs show "Federation: connected to peer" +- [x] `GET /v1/federation/status` returns `"peer_connected": true` +- [x] Messages route across servers transparently +- [x] Key bundles proxy via federation (no "Peer not registered") +- [x] 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 +- [x] SHA-256 integrity check passes +- [x] File appears in downloads directory +- [x] 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 ` +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 +- [x] Call bar appears in web when peer is set +- [x] Incoming call notification (pulsing animation in web, bell in TUI) +- [x] Call state updates in header (TUI) / call bar (web) +- [x] Hangup/reject cleans up state on both sides + +--- + +## Test 8: Voice Call Audio (requires WZP relay) + +### Prerequisites +```bash +# Terminal 1: WZP relay +./wzp-relay --bind 0.0.0.0:4433 + +# Terminal 2: WZP web bridge +./wzp-web --bind 0.0.0.0:8080 --relay 127.0.0.1:4433 + +# 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 +- [x] "Audio: connecting to ..." message appears +- [x] "Audio: connected — mic active" confirms WS to relay +- [x] Audio flows bidirectionally +- [x] Audio stops on hangup +- [x] No audio leak after call ends + +--- + +## Test 9: Bot API + +### Setup +```bash +# 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 +```python +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 +- [x] BotFather creates bot and returns token +- [x] Bot receives plaintext messages (not encrypted) +- [x] Bot replies appear in chat +- [x] Markdown in bot replies renders correctly +- [x] 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 ` +5. **Web**: Connection should drop + +### Verify +- [x] `/devices` shows device IDs and connection times +- [x] `/kick` disconnects the target device +- [x] Max 5 devices per identity enforced + +--- + +## Test 12: Friend List + +### Steps +1. **User A**: `/friend ` +2. **User A**: `/friend` (no args) — should list User B with online/offline status +3. **User A**: `/unfriend ` +4. **User A**: `/friend` — should show empty + +### Verify +- [x] Friend list persists across restarts (encrypted on server) +- [x] Online/offline status shown +- [x] 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 +- [x] "[session reset]" message appears +- [x] 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 +- [x] `/backup` creates file immediately +- [x] Auto-backup runs every 5 minutes +- [x] 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 +- [x] Legacy (raw bincode) still works +- [x] Envelope `[WZ][v1][len][payload]` accepted +- [x] 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 ` +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 ` → 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 |