Skip to content

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.7.3] - 2026-06-11

Added

  • Allure report now shows per-step assertions as nested sub-steps. Every .assert() call (across Client, Server, AsyncClient, AsyncServer, Subscriber, and DataSource) records pass and fail results onto the owning step. The Allure HTML report renders each assertion as a nested sub-step under the parent with its own pass/fail status, the assertion description as the name, and the failure message on failure — so chains of multiple .assert() calls on the same hook are visible per-assertion instead of collapsed into a single pass/fail.

  • Allure report now shows per-step duration. Each step in the report carries start and stop timestamps, so the Allure UI renders a duration badge per step and an accurate timeline.

Changed

  • AllureReporter renders JSON payloads via the Allure JSON viewer. When includePayloads is set, every stamped payload (request, response, message, …) is written as an application/json attachment; the Allure 3.x report's built-in JSON viewer prettifies, syntax-highlights, and folds it on click. Replaces the previous flat parameter-row rendering, which the Allure UI collapsed to a single-line string with no syntax highlighting.

Deprecated

  • AllureReporterOptions.includePayloads: "parameters" is deprecated as an alias for "attachments". Set includePayloads: "attachments" to silence the one-time warning emitted at reporter construction. AllureReporterOptions.maxPayloadSize is deprecated and no longer applied to payloads — attachments are written at full size and the Allure JSON viewer handles folding. Both options remain on the type for backward compatibility and are slated for removal in a future major.

Fixed

  • .assert() predicates may now omit a return value without a type error. An expect-only body such as .assert((res) => { expect(res.code).toBe(200); }) already passed at runtime but failed to type-check, forcing a trailing return true;. The predicate return type now accepts void, so expect-only assertions compile as written.

  • Client.request().retry(...) no longer crashes the runner on retry exhaustion when a downstream onResponse / waitResponse step is registered. Previously, the RetryTimeoutError (or rethrown attempt error under retryOnError: false) propagated cleanly as a failed step but left the matching response-hook pending in a rejected-without-observer state, which Node escalated to unhandledRejection — terminating the runner mid-scenario and dropping subsequent test cases. The framework now marks the rejection as observed before triggering it; existing awaitHook consumers continue to receive the original error unchanged.

[0.7.2] - 2026-06-09

Added

  • Subscriber is now always per-test-case isolated — Constructor takes the IMQAdapter factory directly; the framework materializes a fresh subscriber adapter per test case. Eliminates the cross-TC offset leak and the sequential-different-topics breakage that existed in master. Zero-config default: omit defaultSubscribeParams.groupId and the framework auto-generates testurio-${randomSuffix(8)} per TC so every test case gets its own consumer group. Opt out via new KafkaAdapter({ ..., defaultSubscribeParams: { groupId: 'shared' } }) to share one group across TCs (Kafka partition-assignment semantics).

    typescript
    const kafka = new KafkaAdapter({ brokers: ['localhost:9092'] });
    const events = new Subscriber('events', { adapter: kafka });
    // Each TC gets a unique consumer group automatically.
  • SubscriberStepBuilder.subscribe(topic?, params?) and unsubscribe(topic?) — Imperative declarative builder methods. Single topic, array, or empty-array shortcut (subscribes to all hook-derived topics for the TC / unsubscribes from all currently-held). params is Partial<P> for adapter-specific overrides (e.g. ev.subscribe('orders', { fromBeginning: true })).

  • KafkaSubscribeParams and KafkaAdapterConfig.defaultSubscribeParams — Per-subscribe params shape (groupId?, fromBeginning?) plus adapter-wide defaults bag. Per-call subscribe-level overrides flow through ev.subscribe('topic', { fromBeginning: true }).

  • SubscriberOptions.autoSubscribe: boolean — Whether the per-TC adapter auto-subscribes to topics referenced by onMessage / waitMessage / waitMessageFrom hooks. Defaults to true. (The v1 Array<Topic> form is removed — see Breaking Changes below.)

  • KafkaAdapterConfig.groupJoinTimeoutMs — Configurable per-adapter timeout for the Kafka subscriber to await the consumer.events.GROUP_JOIN event after consumer.run(). Default 30000 ms (production) and 5000 ms (testMode: true). On expiry the activation rejects with ConsumerJoinTimeoutError.

  • Component.afterHooksRegistered?(testCaseId) — Optional lifecycle hook on the Component interface, called between hook registration and step execution for every test case. Receives the originating testCaseId so per-TC components can branch on it. Rejections propagate exactly like hook-registration failures and abort the test case.

  • ConsumerJoinTimeoutError — Named export from @testurio/adapter-kafka. Thrown when the Kafka subscriber adapter cannot confirm GROUP_JOIN within the configured timeout (initial subscribe AND the disconnect-reconnect restart path on new topics). Carries timeoutMs for diagnostics.

  • Optional dispatch key?: string on Codec.encode / Codec.decode — Lets a single codec instance pick a payload schema per call without keeping per-topic codec instances. Existing codecs continue to compile because the parameter is optional and unobserved. For MQ adapters the key is the concrete destination topic; HTTP / WS / TCP adapters can leave it undefined or pass an adapter-specific dispatch identifier in a follow-up.

  • MQ adapters pass the concrete topic to the codec on every call. Kafka, RabbitMQ, and Redis Pub/Sub all dispatch through codec.encode(payload, topic) and codec.decode(wire, topic). The key is always the broker-side concrete identity — Kafka topic name, RabbitMQ routing key, Redis channel — never a subscription pattern, glob mask, or AMQP wildcard string. Dispatching codecs (such as the new ProtobufCodec) can rely on this invariant when matching bindings.

  • New package @testurio/codec-protobuf — First-class ProtobufCodec with ordered entries-array bindings: each entry pairs a matcher (string exact / RegExp / predicate (key) => boolean) with a fully-qualified protobuf type name. First match wins. One codec instance handles every topic — exact, RegExp, and predicate matchers can mix freely. Unmapped keys throw CodecError listing every configured entry. Ships a typed defineBindings<TopicMap, Registry>() helper that catches topic ↔ wire-type mismatches at codec-construction-site type-check, plus an includePaths option for protoc -I include/path semantics when loading .proto files with cross-package imports.

  • ProtobufCodec keepCase?: boolean option — Top-level field-naming control forwarded to protobufjs's parser at .proto load time, applied symmetrically to both decode output and encode input. Defaults to false (protobufjs's native camelCase, e.g. { orderId }); set keepCase: true to preserve the original .proto field names verbatim (conventionally snake_case, e.g. { order_id }).

Changed (BREAKING) — Subscriber per-test-case isolation

  • SubscriberOptions.adapter is now an IMQAdapter factory (was IMQSubscriberAdapter). Pass the broker adapter directly — the framework materializes a fresh subscriber adapter per test case. Migration: new Subscriber('x', { adapter: await kafka.createSubscriber() })new Subscriber('x', { adapter: kafka }).

  • SubscriberOptions.autoSubscribe no longer accepts Array<Topic> — only boolean (default true). Migration: rely on hooks (onMessage / waitMessage derive their topics automatically). The remaining flag controls whether the per-TC adapter auto-subscribes to hook-derived topics.

  • KafkaAdapterConfig.groupId and KafkaAdapterConfig.fromBeginning removed. Replaced by nested defaultSubscribeParams: { groupId?, fromBeginning? }. groupId is now optional — omit it and the framework auto-generates testurio-${randomSuffix(8)} per test case. Migration: new KafkaAdapter({ brokers, groupId: 'x', fromBeginning: true })new KafkaAdapter({ brokers, defaultSubscribeParams: { groupId: 'x', fromBeginning: true } }).

  • IMQSubscriberAdapter.startConsuming?() removed from the interface. Folded into IMQSubscriberAdapter.subscribe(topic, params?) — the first call activates the adapter's delivery loop. IMQSubscriberAdapter.subscribe and unsubscribe both widen to string | string[].

  • Persistent / scenario-level Subscriber hooks removed. Subscriber.registerHook now throws when step.testCaseId === undefined — that covers hooks registered outside a testCase() body AND hooks registered inside scenario.init / scenario.stop handlers. There is no scenario-level subscription primitive in testurio. Migration: move the hook into a testCase() body.

Changed

  • CLI: testurio generate now reports every OpenAPI spec issue in one aggregated, location-tagged error. Each broken field is listed with its JSON pointer in a single pass — no more fix-rerun-repeat against opaque messages.

  • JsonCodec.encode and JsonCodec.decode signatures widen to accept (and ignore) the optional dispatch-key argument. No behaviour change; existing callers compile unchanged.

Fixed

  • @testurio/codec-protobuf no longer crashes with TypeError: protobuf.Root is not a constructor under native Node ESM. The codec imported protobufjs via import * as protobuf, whose namespace places the real CommonJS module on .default under Node's ESM loader (cjs-module-lexer doesn't detect protobufjs's dynamically-assigned Root). Switched to a default import (import protobuf from "protobufjs"), which resolves correctly across native ESM, the CJS build, and the bundled test runner.

  • Redis Pub/Sub subscriber no longer leaks a Redis connection per test case. RedisPubsubSubscriberAdapter.close() now releases the connection it owns; previously each test case left one Redis client open until process exit.

  • Subscriber adapter errors and disconnects now fail only the originating test case. Previously a single subscriber-side error failed the whole scenario and a single disconnect rejected every pending wait across every test case; now each test case runs on its own adapter and observes only its own failure.

  • CLI: YAML / JSON parse errors from testurio generate now include the file path and line:column.

    error: Failed to parse YAML at ./api/openapi.yaml:15:1
      Missing closing "quote at line 15, column 1
  • CLI: Orval failures from testurio generate now surface Orval's own error message instead of a generic placeholder. Pass --verbose for the full diagnostic.

[0.6.5] - 2026-06-05

Added

  • Testurio-native expect() — Self-contained matcher API with zero dependencies on jest, vitest, or chai. Sync matchers only: toBe, toEqual, toStrictEqual, toBeTruthy, toBeFalsy, toBeNull, toBeUndefined, toBeDefined, toBeGreaterThan(OrEqual), toBeLessThan(OrEqual), toBeCloseTo, toMatch, toContain, toMatchObject, toHaveLength, toHaveProperty, plus .not negation on every matcher. Failure throws ExpectAssertionError whose .message is self-formatted with the matcher name, the user's source link (at file:line:col), an Expected:/Received: block, and (for collection matchers) a multi-line ANSI-colored Diff:.

    typescript
    import { expect } from "testurio";
    
    api.onResponse("getUser").assert((res) => {
      expect(res.code).toBe(200);              // no `return true;` needed
      expect(res.body).toMatchObject({ id: 1 });
    });

    Asymmetric matchers (expect.any), async chaining (.resolves/.rejects), snapshot, mock, and expect.extend are deliberately excluded from this MVP. The diff renderer emits ANSI codes unconditionally — reporters that don't render ANSI can strip via replace(/\x1b\[\d+m/g, "").

Fixed

  • Sync Client: fire-and-forget request() no longer leaks the request promise's rejection as a Node unhandledRejection. Previously, when no onResponse/waitResponse step was registered for a request (or every matching hook lacked a step), Client.executeRequest() left the request promise unobserved.

  • AllureReporter.includePayloads now actually attaches request/response payloads. Previously the option was effectively a no-op — convertStep read from step.metadata but no component, executor, or projection ever wrote to it.

  • AllureReporter surfaces both request AND response on the same stepextractPayload now collects every recognized payload key on step.metadata instead of returning only the first match. Server hook steps that stamp both keys now produce both parameter rows / both attachments.

  • Kafka startConsuming now awaits GROUP_JOINKafkaSubscriberAdapter.startConsuming() previously called consumer.run() and resolved immediately, before the consumer had joined its group. With fromBeginning: false, a .waitMessage(...) step placed after the action that publishes would miss the message — the consumer joined hundreds of ms later, started fetching from latest, and the message at the pre-join offset was never delivered. The method now registers a one-shot consumer.events.GROUP_JOIN listener, calls consumer.run(), and only resolves after the listener fires (or rejects with ConsumerJoinTimeoutError if the configured timeout elapses). Idempotent — repeat calls early-return.

  • CLI: OpenAPI generator output is now a single unified operations artifact. Previously the generator emitted three near-duplicate artifacts per spec (an operations map for types, a {service}Schema Protocol Schema bridge for runtime validation, and a hand-built {Service} interface). The duplication was the source of multiple drift bugs (case mismatch between emitters, body-less slots using different fallbacks, etc.).

  • CLI: OpenAPI generator now includes all response status codes The operations map's response field previously emitted only the first 2xx status, silently dropping every 4xx/5xx (and alternative 2xx) defined in the spec. Multi-response operations now emit z.discriminatedUnion('code', [...]) with one z.object({ code: z.literal(N), body: ... }) per status code, producing the inferred type { code: 200; body: ... } | { code: 400; body: never } | .... Single-response operations still use a plain z.object(...) (no union overhead).

  • CLI: OpenAPI generator body-less slots are now consistent and dual-mode compatible Body-less request slots (e.g. GET operations) and body-less response slots (204 No Content, or no 2xx defined) emit body: z.never().optional() uniformly across the generated output. The .optional() modifier is required for the schema to be usable at both runtime and design-time: at runtime, parse({ method, path }) (the typical no-body shape) succeeds; at design-time, the inferred body?: undefined lets consumers omit the field. A stray body with content is still rejected (expected never, received ...). Without .optional() every body-less payload would fail auto-validation at runtime and refuse to compile at the consumer call site.

  • CLI: OpenAPI generator no longer skips operations missing operationId Previously the generator logged a warning and dropped every operation without an explicit operationId, producing an empty schema for any spec that omits the optional field. The CLI now synthesizes a deterministic id from {path + method} (e.g. GET /v1/accounts/{account-id}v1getAccountsAccountId) and applies it to the spec before both Orval and the parser run, so the two pipelines agree on naming. Explicit operationIds are preserved unchanged. Collisions hard-fail with both endpoints named in the error message.

[0.6.4] - 2026-06-02

Fixed

  • MQ adapters: binary codec payloads no longer corrupted All three MQ subscribers (Kafka, RabbitMQ, Redis Pub/Sub) previously called .toString() on the raw payload before invoking codec.decode(...), which UTF-8-stringified non-text bytes and silently broke any binary codec (protobuf, msgpack, Avro). The Redis Pub/Sub publisher had the symmetric bug on the encode side. Adapters now pass raw transport bytes directly to the codec; text/binary normalization is the codec's responsibility.

[0.6.3] - 2026-06-01

Added

  • Step Polling / Retry — Step-level .retry(predicate, timeoutMs | options) modifier on Client.request(...) (HTTP / gRPC unary) and DataSource.exec(...). Retry-while semantics: predicate returns true to keep retrying, false to stop. Three call forms: .retry(pred), .retry(pred, timeoutMs), .retry(pred, { timeout, interval, retryOnError }). Defaults: timeout = 5000 ms, interval = 1000 ms, retryOnError = true. Throws RetryTimeoutError carrying attempts, elapsedMs, lastResult, and lastError when the overall timeout elapses.

    typescript
    api.request('getStatus', { method: 'GET', path: '/status' })
       .retry((res) => res.body.ready === false, 3000);
    
    ds.exec('wait for row', (c) => c.query<Row>({ query: 'SELECT * FROM t' }))
      .retry((rows) => rows.length === 0)
      .assert('row exists', (rows) => rows.length > 0);

    New exported types: RetryPredicate<T>, RetryOptions, RetryPolicy<T>, RetryTimeoutError, TimeoutError. Data factories on request(...) and exec callbacks re-resolve on every attempt; onResponse/waitResponse hooks (sync client) and chained handlers (DataSource) only see the terminal result.

  • ClickHouse DataSource adapter — New @testurio/adapter-clickhouse package exposing a thin query/insert/command/ping/raw wrapper over the official @clickhouse/client HTTP client. Lifecycle managed by TestScenario

  • Wait Event Correlation — Parallel send + filtered wait pattern for async components. Send multiple messages and correlate responses using matchers, regardless of arrival order:

    typescript
    api.sendMessage('new_order', { price: 1.9, amount: 4000 });
    api.sendMessage('new_order', { price: 0.99, amount: 7000 });
    api.waitEvent('order_confirm', { matcher: (r) => r.price === 1.9 }).assert(...);
    api.waitEvent('order_confirm', { matcher: (r) => r.price === 0.99 }).assert(...);

    Works for both AsyncClient.waitEvent() and AsyncServer.waitMessage().

  • AsyncServer waitEvent() — Added strict waitEvent() step to AsyncServer for proxy mode. This is the strict counterpart to onEvent(): it blocks until a matching backend event arrives and throws a strict ordering violation if the event arrives before the step starts. Supports the full handler chain (assert, transform, proxy, drop, timeout, matcher).

  • Factory Step Parameters — Action step methods now accept T | (() => T) factory functions in addition to static values. This allows step parameters to be resolved at execution time, enabling multi-step flows where data from one step (e.g., a token or session ID) is used by a later step.

    • client.request('getProfile', () => ({ method: 'GET', path: '/profile', headers: { Authorization: Bearer ${token} } }))
    • ws.sendMessage('join', () => ({ room: 'general', sessionId }))
    • server.sendEvent('conn', 'authResult', () => ({ success: true, sessionId: extractedId }))
    • publisher.publish('orders', () => ({ orderId, status: 'confirmed' }))
    • New exported types: ValueOrFactory<T>, resolveValue<T>()

Fixed

  • AsyncServer validate() directiononEvent().validate() now correctly uses "serverMessage" direction for schema lookup instead of hardcoded "clientMessage". Previously, event validation would fail with "No schema registered" or validate against the wrong schema.

  • Hook matching skips resolved hooksfindMatchingHook and findMatchingHookWithConnection now skip already-resolved hooks. Previously, when two hooks matched the same message type, the second event would re-match the first (already-resolved) hook instead of routing to the second. This fix enables correct FIFO ordering for same-type waits.

[0.6.0] - 2026-03-18

Added

  • AsyncClient Connection Control — Explicit connection lifecycle management for async protocols
    • autoConnect option — New option on AsyncClientOptions (default: false). Set to true or pass protocol-typed params for automatic connection on start.
    • connect() builder step — New action step on AsyncClientStepBuilder for explicit connection with optional protocol-typed params. Accepts static params or factory function for dynamic params (e.g., auth tokens from earlier steps).
    • Reconnection supportconnect() after disconnect() creates a fresh connection, enabling reconnection flow testing.
    • Protocol-typed connect params — Each async protocol declares its own connect params type:
      • WsConnectParamsheaders, query, path, protocols for WebSocket handshake
      • GrpcStreamConnectParamsmetadata for gRPC stream auth
      • TCP — no protocol-specific params
    • ProtocolConnectParams<P> type extractor — Extract connect params type from protocol for type-safe connect() calls

Breaking Changes

  • AsyncClient no longer auto-connects by defaultautoConnect defaults to false. Existing tests using AsyncClient must either add autoConnect: true to the options or add an explicit connect() step. This enables testing deferred connections, auth-gated connections, and reconnection flows.

[0.5.0] - 2026-03-16

Added

  • Documentation Portal — Comprehensive VitePress documentation site with getting started guides, API reference for all packages, examples/cookbook, and development guides for custom protocols, adapters, reporters, and codecs. Deployed to GitHub Pages via GitHub Actions.

  • Runtime Schema Validation — Validate request/response/message payloads at runtime using Zod-compatible schemas (any object with a .parse() method)

    • Schema-first protocols — Pass schemas to protocol constructors for automatic TypeScript type inference (new HttpProtocol({ schema: zodSchemas })). No manual generic parameters needed.
    • Auto-validation — Outgoing requests/messages and incoming responses/events are validated automatically at I/O boundaries when schemas are registered. Controlled via validation: { validateRequests, validateResponses } options.
    • .validate() builder method — Explicit per-step validation on hook builders. Supports no-arg (protocol schema lookup) and explicit schema overloads.
    • ValidationError class — Structured error with componentName, operationId, direction, and cause fields for clear diagnostics.
    • SchemaLike<T> interface — Framework-agnostic schema contract requiring only .parse(data): T. Compatible with Zod, Yup, or any validation library.
    • Supported across all component types: Client, Server, AsyncClient, AsyncServer, Publisher, Subscriber
    • Three typing modes: schema-first (runtime + compile-time), explicit generic (compile-time only), loose (any string)
  • Protocol generic restructuring — All protocols now use S = never default generic with Resolve*Type<S> conditional types to support schema inference, explicit generics, and loose mode in a single generic parameter.

Breaking Changes

  • schema renamed to protoPath on all protocol options that accepted file paths (proto files, OpenAPI specs). The schema field now accepts typed Zod-compatible schema maps for runtime validation.

    Migration:

    typescript
    // Before
    new GrpcUnaryProtocol({ schema: 'user.proto', serviceName: 'UserService' })
    new GrpcStreamProtocol({ schema: 'chat.proto' })
    new TcpProtocol({ schema: 'protocol.proto' })
    
    // After
    new GrpcUnaryProtocol({ protoPath: 'user.proto', serviceName: 'UserService' })
    new GrpcStreamProtocol({ protoPath: 'chat.proto' })
    new TcpProtocol({ protoPath: 'protocol.proto' })

    HttpProtocol and WebSocketProtocol did not previously have a schema file path field and are unaffected by the rename.

  • Timeout configuration — Removed timeout from options/parameters in waitRequest(), onResponse(), waitResponse(), waitMessage(), waitMessageFrom(), and exec(). Use .timeout(ms) chain method instead.

    • Before: redis.exec(cb, { timeout: 5000 })
    • After: redis.exec(cb).timeout(5000)
  • ExecOptions removed — The ExecOptions interface has been removed from exports

  • SyncServerHookBuilder.timeout() — Added missing .timeout(ms) method to sync server hook builder for consistency

[0.4.1] - 2026-02-26

Added

  • CLI: Protocol schema bridge exports — Generated .schema.ts files now include a {serviceName}Schema export compatible with SyncSchemaInput (HTTP, gRPC Unary) and {serviceName}StreamsSchema compatible with AsyncSchemaInput (gRPC Streaming). These bridge objects compose individual Zod schemas into the structure expected by protocol constructors, enabling schema-first usage with automatic type inference.

Fixed

  • CLI: File extension rename — Default generated output changed from .types.ts to .schema.ts to better reflect the file's runtime content (Zod schemas + protocol schema bridge)
  • CLI: Naming standardization — Internal properties and section comments renamed from plural "schemas" to singular "schema" (e.g., // ===== Zod Schema =====)
  • CLI: Doc comments updated — Generated doc comments now show both "Schema-first (recommended)" and "Current usage (explicit generic)" patterns with accurate constructor signatures for the current API
  • CLI: Header schema naming — Renamed generated header schema variables from {operationId}HeadersSchema (plural) to {operationId}HeaderSchema (singular) for consistency with the naming convention
  • CLI: Path parameter validation — Protocol schema bridge now uses z.string() for OpenAPI operations with path parameters (e.g., /pets/{petId}) instead of z.literal('/pets/{petId}'), which would fail runtime validation when actual resolved paths like /pets/123 are checked

[0.4.0] - 2026-02-15

Added

  • Custom Codec Support for WebSocket and TCP protocols
    • New Codec interface for message encoding/decoding (packages/core/src/protocols/base/codec.types.ts)
    • JsonCodec - Default JSON codec with reviver/replacer support (packages/core/src/protocols/base/json.codec.ts)
    • CodecError - Dedicated error class for codec failures
    • codec option in WsProtocolOptions and TcpProtocolOptions
    • Example codecs: MessagePackCodec, ProtobufCodec (examples/custom-codecs/)
  • @testurio/cli package (packages/cli/) - CLI tool for generating type-safe TypeScript schemas from API specifications
    • testurio generate command to generate Zod schemas and Testurio-compatible service types
    • testurio init command to scaffold a starter testurio.config.ts
    • Config system using cosmiconfig with Zod validation (testurio.config.ts/js/json/yaml)
    • defineConfig helper for type-safe configuration
    • Generates Zod schemas from OpenAPI 3.x specs via Orval programmatic API
    • Generates Zod schemas from .proto files via protobufjs

Changed

  • WebSocket adapters now use configurable codec instead of hardcoded JSON
  • TCP adapters now use configurable codec instead of hardcoded JSON

Documentation

  • Added Custom Codecs section to README.md
  • Added Codec Layer section to ARCHITECTURE.md
  • Created examples/custom-codecs/ with MessagePack and Protobuf examples

[0.3.1] - 2026-01-19

Added

  • @testurio/protocol-grpc - gRPC protocol package

    • GrpcUnaryProtocol - Synchronous unary request/response calls
    • GrpcStreamProtocol - Asynchronous bidirectional streaming
    • Proto schema loading with @grpc/proto-loader
    • gRPC credentials support
    • Metadata handling for gRPC calls
    • Type-safe gRPC service definitions
  • @testurio/protocol-ws - WebSocket protocol package

    • WebSocketProtocol for async bidirectional messaging
    • Type-safe WebSocket service definitions
    • Custom codec support (JSON default, configurable)
    • Client and server message type definitions
  • @testurio/protocol-tcp - TCP protocol package

    • TcpProtocol for custom binary/text protocols
    • Length-prefixed framing for binary protocols
    • Custom codec support
    • TCP client/server socket management
    • Type-safe TCP service definitions
  • @testurio/reporter-allure - Allure TestOps integration

    • AllureReporter - Converts Testurio test results to Allure format
    • Environment info reporting
    • Attachment support for payloads
    • Label and link management
    • Test step conversion with status tracking
    • FileSystemWriter for result persistence
  • @testurio/adapter-kafka - Apache Kafka adapter

    • KafkaPublisherAdapter - Publisher component integration
    • KafkaSubscriberAdapter - Subscriber component integration
    • KafkaJS-based implementation
    • Topic-based message publishing
    • Consumer group support
    • Partition and offset management
  • @testurio/adapter-rabbitmq - RabbitMQ adapter

    • RabbitMQPublisherAdapter - Publisher component integration
    • RabbitMQSubscriberAdapter - Subscriber component integration
    • Exchange and routing key support
    • Topic pattern matching (e.g., orders.#, *.created)
    • AMQP delivery tag tracking
    • Redelivery detection
  • @testurio/adapter-redis - Redis adapter

    • RedisAdapter - DataSource component integration
    • Direct Redis client access via ioredis
    • Redis Pub/Sub support
    • Key-value operations
  • @testurio/adapter-pg - PostgreSQL adapter

    • PostgresAdapter - DataSource component integration
    • node-postgres (pg) based implementation
    • Pool and PoolClient support
    • Direct SQL query execution
    • Transaction support
  • @testurio/adapter-mongo - MongoDB adapter

    • MongoAdapter - DataSource component integration
    • Official MongoDB Node.js driver based implementation
    • Collection and database operations
    • Direct database access

[0.3.0] - 2026-01-09

Added

  • Flexible Protocol Types feature
    • Loose mode: Accept any string as message type
    • Strict mode: Constrain to defined operation IDs
  • DataSource component for database/cache integration
  • Redis, PostgreSQL, MongoDB adapters

Changed

  • Protocol type system refactored for better type inference

[0.2.0] - 2026-01-08

Added

  • gRPC streaming support (GrpcStreamProtocol)
  • TCP protocol (TcpProtocol)
  • WebSocket protocol (WebSocketProtocol)
  • Proxy mode for Server and AsyncServer components

[0.1.0] - 2026-01-07

Added

  • Initial release
  • HTTP protocol support
  • gRPC unary protocol support
  • Client/Server components
  • AsyncClient/AsyncServer components
  • TestScenario and testCase APIs
  • Hook system for message interception

Released under the MIT License.