Skip to content

Testing

Flowcraft provides utilities for testing and debugging workflows, including step-by-step execution, event logging, and trace helpers.

createStepper

Creates a stepper for interactive, step-by-step execution of workflows.

Signature

typescript
function createStepper<TContext extends Record<string, any> = Record<string, any>, TDependencies extends RuntimeDependencies = RuntimeDependencies>(
   runtime: FlowRuntime<TContext, TDependencies>,
   blueprint: WorkflowBlueprint,
   functionRegistry: Map<string, NodeFunction | NodeClass>,
   initialState?: Partial<TContext>
): Promise<IWorkflowStepper<TContext>>

Parameters

  • runtime: The FlowRuntime instance to use for execution.
  • blueprint: The workflow blueprint to execute.
  • functionRegistry: A map of node implementations.
  • initialState (optional): Initial context state.

Returns

A Promise resolving to an IWorkflowStepper instance with methods for step-by-step control.

Example

typescript
import { createStepper } from 'flowcraft/testing'

const stepper = await createStepper(runtime, blueprint, registry)
const result = await stepper.next()

IWorkflowStepper Interface

The IWorkflowStepper interface provides methods for step-by-step workflow execution.

typescript
interface IWorkflowStepper<TContext extends Record<string, any>> {
  readonly state: WorkflowState<TContext>
  readonly traverser: GraphTraverser
  next(options?: { signal?: AbortSignal; concurrency?: number }): Promise<WorkflowResult<TContext> | null>
  prev(): Promise<WorkflowResult<TContext> | null>
  reset(): void
  isDone(): boolean
}

Methods

  • state: The current state of the workflow.
  • traverser: The graph traverser instance.
  • next(options?): Executes the next batch of ready nodes. Returns the result or null if done.
  • prev(): Reverts to the previous state. Returns the result or null if no history.
  • reset(): Resets the stepper to initial state.
  • isDone(): Checks if the workflow has more steps.

runWithTrace

Executes a workflow and prints a detailed trace on failure or when DEBUG is set.

Signature

typescript
function runWithTrace<TContext extends Record<string, any> = Record<string, any>, TDependencies extends RuntimeDependencies = RuntimeDependencies>(
  runtime: IRuntime<TContext, TDependencies>,
  blueprint: WorkflowBlueprint,
  options?: {
    functionRegistry?: Map<string, NodeFunction | NodeClass>
    initialState?: Partial<TContext>
    signal?: AbortSignal
  }
): Promise<WorkflowResult<TContext>>

Parameters

  • runtime: The runtime instance.
  • blueprint: The workflow blueprint.
  • options (optional):
    • functionRegistry: Node implementations.
    • initialState: Initial context.
    • signal: AbortSignal.

Returns

Promise resolving to the workflow result.

Example

typescript
import { runWithTrace } from 'flowcraft/testing'

await runWithTrace(runtime, blueprint)

InMemoryEventLogger

An event bus implementation that captures events in memory for testing.

Signature

typescript
class InMemoryEventLogger implements IEventBus {
   readonly events: FlowcraftEvent[]
   constructor()
   emit(event: FlowcraftEvent): Promise<void>
   clear(): void
   find<T extends FlowcraftEvent['type']>(type: T): Extract<FlowcraftEvent, { type: T }> | undefined
   filter<T extends FlowcraftEvent['type']>(type: T): Extract<FlowcraftEvent, { type: T }>[]
   printLog(title?: string): void
}

Methods

  • events: Array of captured events.
  • emit(event): Captures the event in the array.
  • clear(): Clears all captured events.
  • find(type): Finds the first event of the given type.
  • filter(type): Filters events by type.
  • printLog(title?): Prints a formatted log of all events.

Example

typescript
import { InMemoryEventLogger } from 'flowcraft/testing'

const logger = new InMemoryEventLogger()
const runtime = new FlowRuntime({ eventBus: logger })
await runtime.run(blueprint)
const event = logger.find('node:finish')
const retryEvents = logger.filter('node:retry')
logger.printLog('Execution Trace')

Released under the MIT License