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 (acrossClient,Server,AsyncClient,AsyncServer,Subscriber, andDataSource) 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
startandstoptimestamps, so the Allure UI renders a duration badge per step and an accurate timeline.
Changed
AllureReporterrenders JSON payloads via the Allure JSON viewer. WhenincludePayloadsis set, every stamped payload (request, response, message, …) is written as anapplication/jsonattachment; 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". SetincludePayloads: "attachments"to silence the one-time warning emitted at reporter construction.AllureReporterOptions.maxPayloadSizeis 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 trailingreturn true;. The predicate return type now acceptsvoid, so expect-only assertions compile as written.Client.request().retry(...)no longer crashes the runner on retry exhaustion when a downstreamonResponse/waitResponsestep is registered. Previously, theRetryTimeoutError(or rethrown attempt error underretryOnError: false) propagated cleanly as a failed step but left the matching response-hook pending in a rejected-without-observer state, which Node escalated tounhandledRejection— terminating the runner mid-scenario and dropping subsequent test cases. The framework now marks the rejection as observed before triggering it; existingawaitHookconsumers continue to receive the original error unchanged.
[0.7.2] - 2026-06-09
Added
Subscriberis now always per-test-case isolated — Constructor takes theIMQAdapterfactory 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: omitdefaultSubscribeParams.groupIdand the framework auto-generatestesturio-${randomSuffix(8)}per TC so every test case gets its own consumer group. Opt out vianew KafkaAdapter({ ..., defaultSubscribeParams: { groupId: 'shared' } })to share one group across TCs (Kafka partition-assignment semantics).typescriptconst 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?)andunsubscribe(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).paramsisPartial<P>for adapter-specific overrides (e.g.ev.subscribe('orders', { fromBeginning: true })).KafkaSubscribeParamsandKafkaAdapterConfig.defaultSubscribeParams— Per-subscribe params shape (groupId?,fromBeginning?) plus adapter-wide defaults bag. Per-call subscribe-level overrides flow throughev.subscribe('topic', { fromBeginning: true }).SubscriberOptions.autoSubscribe: boolean— Whether the per-TC adapter auto-subscribes to topics referenced byonMessage/waitMessage/waitMessageFromhooks. Defaults totrue. (The v1Array<Topic>form is removed — see Breaking Changes below.)KafkaAdapterConfig.groupJoinTimeoutMs— Configurable per-adapter timeout for the Kafka subscriber to await theconsumer.events.GROUP_JOINevent afterconsumer.run(). Default30000ms (production) and5000ms (testMode: true). On expiry the activation rejects withConsumerJoinTimeoutError.Component.afterHooksRegistered?(testCaseId)— Optional lifecycle hook on theComponentinterface, called between hook registration and step execution for every test case. Receives the originatingtestCaseIdso 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 confirmGROUP_JOINwithin the configured timeout (initial subscribe AND the disconnect-reconnect restart path on new topics). CarriestimeoutMsfor diagnostics.Optional dispatch
key?: stringonCodec.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)andcodec.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 newProtobufCodec) can rely on this invariant when matching bindings.New package
@testurio/codec-protobuf— First-classProtobufCodecwith ordered entries-array bindings: each entry pairs a matcher (stringexact /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 throwCodecErrorlisting every configured entry. Ships a typeddefineBindings<TopicMap, Registry>()helper that catches topic ↔ wire-type mismatches at codec-construction-site type-check, plus anincludePathsoption forprotoc -I include/pathsemantics when loading.protofiles with cross-package imports.ProtobufCodeckeepCase?: booleanoption — Top-level field-naming control forwarded to protobufjs's parser at.protoload time, applied symmetrically to both decode output and encode input. Defaults tofalse(protobufjs's nativecamelCase, e.g.{ orderId }); setkeepCase: trueto preserve the original.protofield names verbatim (conventionallysnake_case, e.g.{ order_id }).
Changed (BREAKING) — Subscriber per-test-case isolation
SubscriberOptions.adapteris now anIMQAdapterfactory (wasIMQSubscriberAdapter). 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.autoSubscribeno longer acceptsArray<Topic>— onlyboolean(defaulttrue). Migration: rely on hooks (onMessage/waitMessagederive their topics automatically). The remaining flag controls whether the per-TC adapter auto-subscribes to hook-derived topics.KafkaAdapterConfig.groupIdandKafkaAdapterConfig.fromBeginningremoved. Replaced by nesteddefaultSubscribeParams: { groupId?, fromBeginning? }.groupIdis now optional — omit it and the framework auto-generatestesturio-${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 intoIMQSubscriberAdapter.subscribe(topic, params?)— the first call activates the adapter's delivery loop.IMQSubscriberAdapter.subscribeandunsubscribeboth widen tostring | string[].Persistent / scenario-level Subscriber hooks removed.
Subscriber.registerHooknow throws whenstep.testCaseId === undefined— that covers hooks registered outside atestCase()body AND hooks registered insidescenario.init/scenario.stophandlers. There is no scenario-level subscription primitive in testurio. Migration: move the hook into atestCase()body.
Changed
CLI:
testurio generatenow 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.encodeandJsonCodec.decodesignatures widen to accept (and ignore) the optional dispatch-key argument. No behaviour change; existing callers compile unchanged.
Fixed
@testurio/codec-protobufno longer crashes withTypeError: protobuf.Root is not a constructorunder native Node ESM. The codec imported protobufjs viaimport * as protobuf, whose namespace places the real CommonJS module on.defaultunder Node's ESM loader (cjs-module-lexer doesn't detect protobufjs's dynamically-assignedRoot). 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 generatenow include the file path andline:column.error: Failed to parse YAML at ./api/openapi.yaml:15:1 Missing closing "quote at line 15, column 1CLI: Orval failures from
testurio generatenow surface Orval's own error message instead of a generic placeholder. Pass--verbosefor the full diagnostic.
[0.6.5] - 2026-06-05
Added
Testurio-native
expect()— Self-contained matcher API with zero dependencies onjest,vitest, orchai. Sync matchers only:toBe,toEqual,toStrictEqual,toBeTruthy,toBeFalsy,toBeNull,toBeUndefined,toBeDefined,toBeGreaterThan(OrEqual),toBeLessThan(OrEqual),toBeCloseTo,toMatch,toContain,toMatchObject,toHaveLength,toHaveProperty, plus.notnegation on every matcher. Failure throwsExpectAssertionErrorwhose.messageis self-formatted with the matcher name, the user's source link (at file:line:col), anExpected:/Received:block, and (for collection matchers) a multi-line ANSI-coloredDiff:.typescriptimport { 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, andexpect.extendare deliberately excluded from this MVP. The diff renderer emits ANSI codes unconditionally — reporters that don't render ANSI can strip viareplace(/\x1b\[\d+m/g, "").
Fixed
Sync
Client: fire-and-forgetrequest()no longer leaks the request promise's rejection as a NodeunhandledRejection. Previously, when noonResponse/waitResponsestep was registered for a request (or every matching hook lacked astep),Client.executeRequest()left the request promise unobserved.AllureReporter.includePayloadsnow actually attaches request/response payloads. Previously the option was effectively a no-op —convertStepread fromstep.metadatabut no component, executor, or projection ever wrote to it.AllureReportersurfaces bothrequestANDresponseon the same step —extractPayloadnow collects every recognized payload key onstep.metadatainstead of returning only the first match. Server hook steps that stamp both keys now produce both parameter rows / both attachments.Kafka
startConsumingnow awaitsGROUP_JOIN—KafkaSubscriberAdapter.startConsuming()previously calledconsumer.run()and resolved immediately, before the consumer had joined its group. WithfromBeginning: false, a.waitMessage(...)step placed after the action that publishes would miss the message — the consumer joined hundreds of ms later, started fetching fromlatest, and the message at the pre-join offset was never delivered. The method now registers a one-shotconsumer.events.GROUP_JOINlistener, callsconsumer.run(), and only resolves after the listener fires (or rejects withConsumerJoinTimeoutErrorif the configured timeout elapses). Idempotent — repeat calls early-return.CLI: OpenAPI generator output is now a single unified
operationsartifact. Previously the generator emitted three near-duplicate artifacts per spec (anoperationsmap for types, a{service}SchemaProtocol 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
responsefield previously emitted only the first 2xx status, silently dropping every 4xx/5xx (and alternative 2xx) defined in the spec. Multi-response operations now emitz.discriminatedUnion('code', [...])with onez.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 plainz.object(...)(no union overhead).CLI: OpenAPI generator body-less slots are now consistent and dual-mode compatible Body-less request slots (e.g.
GEToperations) and body-less response slots (204 No Content, or no2xxdefined) emitbody: 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 inferredbody?: undefinedlets 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
operationIdPreviously the generator logged a warning and dropped every operation without an explicitoperationId, 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 invokingcodec.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 onClient.request(...)(HTTP / gRPC unary) andDataSource.exec(...). Retry-while semantics: predicate returnstrueto keep retrying,falseto stop. Three call forms:.retry(pred),.retry(pred, timeoutMs),.retry(pred, { timeout, interval, retryOnError }). Defaults:timeout = 5000 ms,interval = 1000 ms,retryOnError = true. ThrowsRetryTimeoutErrorcarryingattempts,elapsedMs,lastResult, andlastErrorwhen the overall timeout elapses.typescriptapi.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 onrequest(...)and exec callbacks re-resolve on every attempt;onResponse/waitResponsehooks (sync client) and chained handlers (DataSource) only see the terminal result.ClickHouse DataSource adapter — New
@testurio/adapter-clickhousepackage exposing a thinquery/insert/command/ping/rawwrapper over the official@clickhouse/clientHTTP client. Lifecycle managed byTestScenarioWait Event Correlation — Parallel send + filtered wait pattern for async components. Send multiple messages and correlate responses using matchers, regardless of arrival order:
typescriptapi.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()andAsyncServer.waitMessage().AsyncServer
waitEvent()— Added strictwaitEvent()step toAsyncServerfor proxy mode. This is the strict counterpart toonEvent(): 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()direction —onEvent().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 hooks —
findMatchingHookandfindMatchingHookWithConnectionnow 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
autoConnectoption — New option onAsyncClientOptions(default:false). Set totrueor pass protocol-typed params for automatic connection on start.connect()builder step — New action step onAsyncClientStepBuilderfor explicit connection with optional protocol-typed params. Accepts static params or factory function for dynamic params (e.g., auth tokens from earlier steps).- Reconnection support —
connect()afterdisconnect()creates a fresh connection, enabling reconnection flow testing. - Protocol-typed connect params — Each async protocol declares its own connect params type:
WsConnectParams—headers,query,path,protocolsfor WebSocket handshakeGrpcStreamConnectParams—metadatafor gRPC stream auth- TCP — no protocol-specific params
ProtocolConnectParams<P>type extractor — Extract connect params type from protocol for type-safeconnect()calls
Breaking Changes
AsyncClientno longer auto-connects by default —autoConnectdefaults tofalse. Existing tests usingAsyncClientmust either addautoConnect: trueto the options or add an explicitconnect()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.ValidationErrorclass — Structured error withcomponentName,operationId,direction, andcausefields 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)
- Schema-first protocols — Pass schemas to protocol constructors for automatic TypeScript type inference (
Protocol generic restructuring — All protocols now use
S = neverdefault generic withResolve*Type<S>conditional types to support schema inference, explicit generics, and loose mode in a single generic parameter.
Breaking Changes
schemarenamed toprotoPathon all protocol options that accepted file paths (proto files, OpenAPI specs). Theschemafield 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' })HttpProtocolandWebSocketProtocoldid not previously have aschemafile path field and are unaffected by the rename.Timeout configuration — Removed
timeoutfrom options/parameters inwaitRequest(),onResponse(),waitResponse(),waitMessage(),waitMessageFrom(), andexec(). Use.timeout(ms)chain method instead.- Before:
redis.exec(cb, { timeout: 5000 }) - After:
redis.exec(cb).timeout(5000)
- Before:
ExecOptionsremoved — TheExecOptionsinterface has been removed from exportsSyncServerHookBuilder.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.tsfiles now include a{serviceName}Schemaexport compatible withSyncSchemaInput(HTTP, gRPC Unary) and{serviceName}StreamsSchemacompatible withAsyncSchemaInput(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.tsto.schema.tsto 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 ofz.literal('/pets/{petId}'), which would fail runtime validation when actual resolved paths like/pets/123are checked
[0.4.0] - 2026-02-15
Added
- Custom Codec Support for WebSocket and TCP protocols
- New
Codecinterface 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 failurescodecoption inWsProtocolOptionsandTcpProtocolOptions- Example codecs: MessagePackCodec, ProtobufCodec (
examples/custom-codecs/)
- New
- @testurio/cli package (
packages/cli/) - CLI tool for generating type-safe TypeScript schemas from API specificationstesturio generatecommand to generate Zod schemas and Testurio-compatible service typestesturio initcommand to scaffold a startertesturio.config.ts- Config system using cosmiconfig with Zod validation (
testurio.config.ts/js/json/yaml) defineConfighelper for type-safe configuration- Generates Zod schemas from OpenAPI 3.x specs via Orval programmatic API
- Generates Zod schemas from
.protofiles 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 packageGrpcUnaryProtocol- Synchronous unary request/response callsGrpcStreamProtocol- 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 packageWebSocketProtocolfor 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 packageTcpProtocolfor 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 integrationAllureReporter- Converts Testurio test results to Allure format- Environment info reporting
- Attachment support for payloads
- Label and link management
- Test step conversion with status tracking
FileSystemWriterfor result persistence
@testurio/adapter-kafka- Apache Kafka adapterKafkaPublisherAdapter- Publisher component integrationKafkaSubscriberAdapter- Subscriber component integration- KafkaJS-based implementation
- Topic-based message publishing
- Consumer group support
- Partition and offset management
@testurio/adapter-rabbitmq- RabbitMQ adapterRabbitMQPublisherAdapter- Publisher component integrationRabbitMQSubscriberAdapter- 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 adapterRedisAdapter- DataSource component integration- Direct Redis client access via ioredis
- Redis Pub/Sub support
- Key-value operations
@testurio/adapter-pg- PostgreSQL adapterPostgresAdapter- DataSource component integration- node-postgres (pg) based implementation
- Pool and PoolClient support
- Direct SQL query execution
- Transaction support
@testurio/adapter-mongo- MongoDB adapterMongoAdapter- 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