Documentation
¶
Overview ¶
Package websocketrecord provides recording and replay of WebSocket message exchanges for provider smoke tests.
It is the WebSocket analog of httprecord (HTTP) and subprocessrecord (subprocess I/O). Use it to record real WebSocket interactions and replay them in tests without network access.
A Recorder starts a local proxy. In record mode, the proxy forwards messages to the target and records every data message. In replay mode, the proxy replays the recorded script and verifies each client message. Discard a recording when the live exchange fails so a partial fixture is never replayed.
Recording format is NDJSON where each line is a JSON object with direction, message type and content:
{"dir":">","msg":"{\"type\":\"request\"}"}
{"dir":"<","type":"binary","data":"AQID"}
Text messages omit the type. Binary messages use base64 data.
Example ¶
package main
import (
"context"
"fmt"
"github.com/coder/websocket"
"github.com/maruel/genai/websocketrecord"
)
func main() {
rec, err := websocketrecord.New("testdata/example")
if err != nil {
fmt.Println("New:", err)
return
}
defer func() { _ = rec.Close() }()
if err := rec.Start(""); err != nil {
fmt.Println("Start:", err)
return
}
c, _, err := websocket.Dial(context.Background(), rec.WSURL(), &websocket.DialOptions{})
if err != nil {
fmt.Println("Dial:", err)
return
}
defer func() { _ = c.CloseNow() }()
if err := c.Write(context.Background(), websocket.MessageText, []byte("hello")); err != nil {
fmt.Println("Write:", err)
return
}
_, data, err := c.Read(context.Background())
if err != nil {
fmt.Println("Read:", err)
return
}
fmt.Println(string(data))
}
Output: HELLO
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type NormalizeFunc ¶ added in v0.11.0
type NormalizeFunc func(typ websocket.MessageType, data []byte) []byte
NormalizeFunc rewrites a WebSocket payload before recording and comparison.
Returning the input unchanged is allowed. The recorder still forwards the original payload while recording; only the fixture and replay comparison use the normalized form.
type Recorder ¶
type Recorder struct {
// Normalize rewrites payloads before recording and replay comparison.
Normalize NormalizeFunc
// contains filtered or unexported fields
}
Recorder records or replays WebSocket messages through a local proxy.
Call Start to start the proxy, then point the client at URL or WSURL. Call Close when done, or Discard when the recording failed.
func New ¶
New creates a Recorder for the given path.
The path should not include the ".ndjson" extension; it is appended automatically. If a fixture file exists, the recorder replays it. An empty fixture replays no frame: a probe the client refused before it dialed leaves one, and its position in the sequence must stay. Otherwise the recorder records.
func (*Recorder) Close ¶ added in v0.11.0
Close stops the proxy and closes the fixture file. In record mode it removes an empty fixture because no exchange was recorded.
func (*Recorder) Discard ¶ added in v0.11.0
Discard stops the proxy and removes a recorded fixture. It does not remove the fixture in replay mode. Call it when a live recording fails and must not be replayed.
func (*Recorder) Start ¶ added in v0.11.0
Start starts the local proxy.
target is the base URL the client is configured with, in http, https, ws or wss: the proxy forwards each dial to it, keeping the dialed path. It is required in record mode and ignored in replay mode.