Core

Testing utilities

ManualClock and AnnouncementRecorder APIs for testing runtime behavior without a browser or real-time delays.

createAnnouncementRecorder

createAnnouncementRecorder bundles a runtime, ManualClock, announcement transcript, and diagnostic transcript into one test harness.

typescript
const recorder = createAnnouncementRecorder({
  preset: "balanced",
  startAt: 10_000,
});

recorder.runtime.dispatch({
  type: "response.started",
  responseId: "r1",
});
recorder.runtime.dispatch({
  type: "response.text.delta",
  responseId: "r1",
  delta: "A complete sentence.",
});
recorder.clock.advanceBy(2_000);

expect(recorder.transcript()).toHaveLength(1);

How this code works

  1. 01
    Create the test runtime

    Your recorder provides a runtime, ManualClock, and captured output.

  2. 02
    Send app events

    Use the same events your app sends in production.

  3. 03
    Advance the clock

    Tests control time instead of waiting for real timers.

Options and return values

optionsRecorder optionsOptional

Accepts runtime preset, policy, error handling, and an optional startAt timestamp. Clock and listeners are owned by the recorder.

Default
{}
returnAnnouncementRecorderReturn

Provides runtime, clock, transcript(), diagnosticTranscript(), and clear().

Default
n/a

ManualClock

ManualClock implements Clock and runs timers in a repeatable order.

Options and return values

new ManualClock(startAt)ManualClockConstructor

Creates a clock at the supplied timestamp.

Default
0
now()numberMethod

Returns the current manual timestamp.

Default
n/a
setTimeout(callback, delayMs)ClockTimerMethod

Schedules a callback on the manual clock.

Default
n/a
clearTimeout(timer)voidMethod

Cancels a registered timer.

Default
n/a
advanceBy(ms)voidMethod

Advances time and runs due callbacks in a repeatable order.

Default
n/a
runUntilIdle(maxTasks = 10_000)voidMethod

Runs pending callbacks until none remain and throws if the task limit is reached.

Default
n/a