Documentation
¶
Overview ¶
Package replaytest implements a record→worker-mock→replay pipeline for deterministic, fully-local front-end testing.
The pipeline captures live proxy traffic into a scenario, serves the recorded API responses back from an in-page web worker during replay, and drives a headless browser against the mocked app so automation runs without touching any real backend. Fuzz mutators perturb the recorded responses to probe front-end resilience, and a breadth-exploration step partitions seeds for fan-out across browser-debugger subagents.
Units:
- scenario: on-disk scenario model (.agnt/replaytests/<name>.json)
- match: request matching of live calls against recorded entries
- fuzz: response mutators (empty_array, http_error, ...)
- domsig: DOM signature capture/diff for pass/fail assertions
- worker_bundle: the in-page web worker that serves recorded responses
- recorder: assembles scenarios from captured proxy traffic
- report: scenario run report model (<name>.report.json)
- driver: headless-chrome replay driver with in-page network mock
- refine: LLM-assisted scenario cleanup (needs an API key)
- explore: seed partitioning for subagent breadth exploration
- store: scenario/report persistence
All record/refine/replay/explore actions are license-gated behind license.CapAdvancedTesting (Pro: advanced_testing).
Index ¶
- func DOMSignature(html string, volatileAttrs []string) string
- func Explore(ctx context.Context, sc *Scenario, rep *Report, runner BreadthRunner, ...) error
- func GenerateBundle(s *Scenario, preset string) (string, error)
- func PresetNames() []string
- func Refine(ctx context.Context, sc *Scenario, client LLMClient) error
- func TemplatePath(path string) string
- type AssertType
- type Assertion
- type BreadthFinding
- type BreadthRunner
- type Crash
- type Driver
- type ExploreSeed
- type FuzzPreset
- type FuzzResult
- type LLMClient
- type MatchKey
- type Matcher
- type Recording
- type Report
- type Scenario
- type SeedResult
- type Step
- type StepKind
- type Store
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DOMSignature ¶
DOMSignature returns a stable hash of an HTML fragment with volatile attributes removed and whitespace collapsed, so cosmetic noise does not register as a regression.
func Explore ¶
func Explore(ctx context.Context, sc *Scenario, rep *Report, runner BreadthRunner, agents int, preset string) error
Explore fans out `agents` seeds through the runner and merges findings into the report; newly discovered stable assertions are promoted onto the report.
func GenerateBundle ¶
GenerateBundle returns the full JavaScript (shim + worker) to inject for a replay session. Pure function: same inputs -> same output.
The main-thread shim overrides window.fetch and window.XMLHttpRequest to delegate every request to a Web Worker (created from a Blob) that holds the recordings, the matcher queues, and the fuzz mutator. The worker source is embedded as a JSON-quoted JS string literal so it can be carried inside a Go raw-string template without backtick/escape collisions.
func PresetNames ¶
func PresetNames() []string
func TemplatePath ¶
TemplatePath replaces identifier-looking path segments with ":id" so that recordings match across differing ids at replay time.
Types ¶
type AssertType ¶
type AssertType string
const ( AssertText AssertType = "text" AssertPresent AssertType = "present" )
type Assertion ¶
type Assertion struct {
Selector string `json:"selector"`
Type AssertType `json:"type"`
Expect string `json:"expect"`
Mask bool `json:"mask"`
}
type BreadthFinding ¶
type BreadthFinding struct {
StatesVisited int `json:"states_visited"`
Crashes []Crash `json:"crashes"`
NewAssertions []Assertion `json:"new_assertions"`
}
BreadthFinding holds the output of a single exploration seed.
type BreadthRunner ¶
type BreadthRunner interface {
Run(ctx context.Context, seed ExploreSeed) (BreadthFinding, error)
}
BreadthRunner runs one exploration seed (in production: dispatch a browser-debugger subagent against an isolated worker-mocked context).
type Driver ¶
type Driver struct {
// contains filtered or unexported fields
}
Driver runs the chromedp seed lane: it injects the worker bundle (which mocks the network entirely in-page) before navigation, drives a Scenario's Steps, evaluates Assertions, captures JS errors, and returns a *Report. It is THIN — all request matching and response mutation lives in the worker bundle.
func NewDriver ¶
NewDriver returns a seed-lane driver. proxyID may be "" when the bundle fully mocks the network in-page (the default); when set, the chromedp session is routed through that proxy.
type ExploreSeed ¶
ExploreSeed identifies one exploration run within a breadth fan-out.
type FuzzPreset ¶
type FuzzPreset struct {
Name string
Apply func(status int, body string) FuzzResult
}
func Preset ¶
func Preset(name string) (FuzzPreset, bool)
type FuzzResult ¶
type LLMClient ¶
LLMClient refines auto-captured assertions: masking volatile content and keeping high-signal checks. Injected so CI runs against a stub.
type Matcher ¶
type Matcher struct {
// contains filtered or unexported fields
}
Matcher resolves live requests to recordings, advancing an ordered queue per key so repeated identical calls return successive recordings.
func NewMatcher ¶
type Report ¶
type Report struct {
Scenario string `json:"scenario"`
Seeds []SeedResult `json:"seeds"`
Crashes []Crash `json:"crashes"`
NewAsserts []Assertion `json:"new_assertions,omitempty"`
}
func (*Report) AddSeedResult ¶
func (*Report) CrashCount ¶
type Scenario ¶
type Scenario struct {
Name string `json:"name"`
Version int `json:"version"`
RecordedAt string `json:"recorded_at"`
BaseURL string `json:"base_url"`
Steps []Step `json:"steps"`
Recordings []Recording `json:"recordings"`
Blobs map[string]string `json:"blobs"`
}
func AssembleScenario ¶
AssembleScenario builds a Scenario from a window of proxy log entries. Interaction entries become ordered Steps; HTTP entries become Recordings with response bodies out-of-lined into Blobs (blob:0, blob:1, ...). Paths are templated via TemplatePath, query keys are extracted (dropping the cache-buster "_"), and consecutive identical recordings are coalesced into one with an incremented Hits count.
func UnmarshalScenario ¶
func (*Scenario) MarshalJSON ¶
type SeedResult ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store persists Scenarios and reports under <projectDir>/.agnt/replaytests/.