Stream Recording
Record WebSocket and SSE (Server-Sent Events) streams with full timing fidelity, then replay them as mocks. Perfect for capturing real-time API behavior and creating reproducible test fixtures.
Overview
Section titled “Overview”Stream recording captures:
- WebSocket: Bidirectional message streams with frame types (text, binary, ping/pong, close)
- SSE: Server-sent event streams with event types, IDs, and retry hints
Each recording preserves:
- Message content and encoding
- Precise timing between frames
- Connection metadata (path, headers, query params)
- Protocol-specific details (close codes, subprotocols)
Quick Start
Section titled “Quick Start”1. Start mockd
Section titled “1. Start mockd”mockd serve --config mocks.json2. Start Recording via Admin API
Section titled “2. Start Recording via Admin API”# Start recording WebSocket traffic on a specific pathcurl -X POST http://localhost:4290/stream-recordings/start \ -H "Content-Type: application/json" \ -d '{"protocol": "websocket", "path": "/ws/chat", "name": "chat-session"}'3. Generate Traffic
Section titled “3. Generate Traffic”Connect to your WebSocket or SSE endpoint through mockd:
# WebSocketwscat -c ws://localhost:4280/ws/chat
# SSEcurl -N http://localhost:4280/events4. Stop Recording and View
Section titled “4. Stop Recording and View”# Stop recordingcurl -X POST http://localhost:4290/stream-recordings/{id}/stop
# List recordings via CLImockd stream-recordings listID PROTOCOL PATH STATUS FRAMES DURATION SIZE01HXYZ123456 websocket /ws/chat complete 42 12.3s 8.2 KB01HXYZ789012 sse /events complete 15 5.1s 2.1 KB5. Convert to Mock
Section titled “5. Convert to Mock”# Convert to mock configmockd stream-recordings convert 01HXYZ123456 -o chat-scenario.json
# Start with the mockmockd serve --config chat-scenario.jsonRecording via Admin API
Section titled “Recording via Admin API”Start Recording
Section titled “Start Recording”curl -X POST http://localhost:4290/stream-recordings/start \ -H "Content-Type: application/json" \ -d '{ "protocol": "websocket", "path": "/ws/chat", "name": "chat-session-1" }'Response:
{ "sessionId": "01HXYZ123456789ABCDEF", "protocol": "websocket", "path": "/ws/chat"}Stop Recording
Section titled “Stop Recording”curl -X POST http://localhost:4290/stream-recordings/01HXYZ123456/stopList Recordings
Section titled “List Recordings”# All recordingscurl http://localhost:4290/stream-recordings
# Filter by protocolcurl "http://localhost:4290/stream-recordings?protocol=websocket"
# Filter by pathcurl "http://localhost:4290/stream-recordings?path=/ws/chat"Get Recording Details
Section titled “Get Recording Details”curl http://localhost:4290/stream-recordings/01HXYZ123456Export Recording
Section titled “Export Recording”curl -X POST http://localhost:4290/stream-recordings/01HXYZ123456/export \ -o recording.jsonConvert to Mock
Section titled “Convert to Mock”curl -X POST http://localhost:4290/stream-recordings/01HXYZ123456/convert \ -H "Content-Type: application/json" \ -d '{"simplifyTiming": true}' \ -o mock-config.jsonCLI Commands
Section titled “CLI Commands”List Recordings
Section titled “List Recordings”# Basic listmockd stream-recordings list
# Filter by protocolmockd stream-recordings list --protocol websocket
# Filter by statusmockd stream-recordings list --status complete
# JSON outputmockd stream-recordings list --json
# Paginationmockd stream-recordings list --limit 10 --offset 20Show Recording Details
Section titled “Show Recording Details”mockd stream-recordings show 01HXYZ123456
# JSON outputmockd stream-recordings show 01HXYZ123456 --jsonOutput:
ID: 01HXYZ123456789ABCDEFName: chat-session-1Protocol: websocketPath: /ws/chatStatus: completeStarted: 2024-01-15T10:30:00ZEnded: 2024-01-15T10:30:12ZDuration: 12.3sFrames: 42File Size: 8.2 KB
WebSocket Details: Text Frames: 38 Binary Frames: 2 Ping/Pong: 2 Close Code: 1000Export Recording
Section titled “Export Recording”# Export to stdoutmockd stream-recordings export 01HXYZ123456
# Export to filemockd stream-recordings export 01HXYZ123456 -o recording.jsonConvert to Mock Config
Section titled “Convert to Mock Config”# Basic conversionmockd stream-recordings convert 01HXYZ123456
# With timing normalizationmockd stream-recordings convert 01HXYZ123456 --simplify-timing
# Output to filemockd stream-recordings convert 01HXYZ123456 -o scenario.json
# Fine-tune timingmockd stream-recordings convert 01HXYZ123456 \ --simplify-timing \ --min-delay 50 \ --max-delay 2000Delete Recording
Section titled “Delete Recording”# Soft delete (recoverable)mockd stream-recordings delete 01HXYZ123456
# Skip confirmationmockd stream-recordings delete 01HXYZ123456 --force
# Permanent deletemockd stream-recordings delete 01HXYZ123456 --permanentStorage Management
Section titled “Storage Management”# View storage statsmockd stream-recordings stats
# Permanently remove soft-deleted recordingsmockd stream-recordings vacuumActive Sessions
Section titled “Active Sessions”# List recordings in progressmockd stream-recordings sessionsRecording Format
Section titled “Recording Format”Recordings are stored as JSON files with this structure:
{ "formatVersion": "1.0", "id": "01HXYZ123456789ABCDEF", "name": "chat-session-1", "protocol": "websocket", "status": "complete", "startTime": "2024-01-15T10:30:00Z", "endTime": "2024-01-15T10:30:12Z", "duration": 12345, "metadata": { "path": "/ws/chat", "headers": {"Authorization": "[REDACTED]"}, "query": {"room": "general"} }, "websocket": { "subprotocol": "chat.v1", "frames": [ { "direction": "s2c", "type": "text", "data": "{\"type\":\"welcome\"}", "timestamp": "2024-01-15T10:30:00.100Z", "relativeMs": 100 }, { "direction": "c2s", "type": "text", "data": "{\"type\":\"join\",\"room\":\"general\"}", "timestamp": "2024-01-15T10:30:00.250Z", "relativeMs": 250 } ], "closeCode": 1000, "closeReason": "Normal closure" }, "stats": { "frameCount": 42, "textFrames": 38, "binaryFrames": 2, "pingPongs": 2, "fileSizeBytes": 8432 }}Frame Direction
Section titled “Frame Direction”c2s- Client to server (sent by client)s2c- Server to client (sent by server)
Message Types (WebSocket)
Section titled “Message Types (WebSocket)”text- UTF-8 text framebinary- Binary frame (base64 encoded in JSON)ping- Ping control framepong- Pong control frameclose- Close control frame
SSE Recording Structure
Section titled “SSE Recording Structure”{ "protocol": "sse", "sse": { "events": [ { "type": "message", "data": "Hello world", "id": "evt-001", "timestamp": "2024-01-15T10:30:00.100Z", "relativeMs": 100 } ] }}Sensitive Data Handling
Section titled “Sensitive Data Handling”By default, mockd redacts sensitive headers:
AuthorizationCookie/Set-CookieX-API-KeyX-Auth-Token
Custom Redaction
Section titled “Custom Redaction”Configure in mockd.yaml:
recording: filterHeaders: - Authorization - X-Custom-Secret filterBodyKeys: - password - secret - $.user.ssn redactValue: "[REDACTED]"Storage Configuration
Section titled “Storage Configuration”recording: dataDir: ~/.local/share/mockd/recordings maxBytes: 524288000 # 500MB warnPercent: 80 # Warn at 80% capacityStorage location defaults:
- Linux:
~/.local/share/mockd/recordings/ - macOS:
~/Library/Application Support/mockd/recordings/ - Windows:
%LOCALAPPDATA%\mockd\recordings\
Use Cases
Section titled “Use Cases”Capture Production Behavior
Section titled “Capture Production Behavior”Record real WebSocket traffic from production to create accurate test fixtures:
# Start mockd and the proxymockd serve
# Start recording via Admin APIcurl -X POST http://localhost:4290/stream-recordings/start \ -H "Content-Type: application/json" \ -d '{"protocol": "websocket", "path": "/ws", "name": "prod-traffic"}'
# Run your app (configure to use mockd as WebSocket proxy)WS_URL=ws://localhost:4280/ws npm test
# Stop recording and convert to mockscurl -X POST http://localhost:4290/stream-recordings/{id}/stopmockd stream-recordings convert {id} -o fixtures/chat.jsonIntegration Testing
Section titled “Integration Testing”Create reproducible stream mocks for CI/CD:
# Start mockd with recorded scenariomockd start --config fixtures/chat.json
# Run tests against mocknpm testDebug Timing Issues
Section titled “Debug Timing Issues”Analyze frame timing in recordings:
mockd stream-recordings show 01HXYZ123456 --json | jq '.websocket.frames[] | {relativeMs, direction, type}'Admin API Reference
Section titled “Admin API Reference”| Method | Endpoint | Description |
|---|---|---|
| GET | /stream-recordings | List recordings |
| GET | /stream-recordings/stats | Storage statistics |
| GET | /stream-recordings/sessions | Active recording sessions |
| POST | /stream-recordings/start | Start recording |
| POST | /stream-recordings/vacuum | Remove soft-deleted |
| GET | /stream-recordings/{id} | Get recording |
| DELETE | /stream-recordings/{id} | Delete recording |
| POST | /stream-recordings/{id}/stop | Stop recording session |
| POST | /stream-recordings/{id}/export | Export as JSON |
| POST | /stream-recordings/{id}/convert | Convert to mock config |
Next Steps
Section titled “Next Steps”- Replay Modes - Learn about Pure, Synchronized, and Triggered replay
- SSE Streaming - SSE mock configuration
- Admin API - Stream recording API endpoints