TypeScript SDK for Test Server
The `test-server-sdk` is a TypeScript SDK designed to provide client-side interaction with a companion `test-server` for robust HTTP and WebSocket request recording and replaying. This package facilitates deterministic and isolated testing by allowing developers to capture network traffic and simulate server responses. It's currently on version 0.2.9 and exhibits a rapid release cadence with frequent minor updates, focusing on new features and bug fixes. Key functionalities include recording and replaying HTTP and WebSocket requests, supporting dynamic subdirectory recording paths, streaming capabilities, and redacting sensitive information from response bodies. A notable differentiator is its ability to manage recording formats, which was updated to a JSON serializable format in v0.2.6, enhancing interoperability and storage. This SDK is a core component for integrating `test-server` capabilities into TypeScript-based test environments.
Common errors
-
Error: listen EADDRINUSE :::9000
cause The specified port for the `TestServer` is already in use by another process on your system.fixChoose a different port for the `TestServer` or ensure no other application is listening on that port before running your tests. You can use a utility like `lsof -i :9000` (macOS/Linux) or `netstat -ano | findstr :9000` (Windows) to identify the conflicting process. -
TypeError: TestServer is not a constructor
cause This error typically indicates an incorrect import statement, often when attempting to use CommonJS `require` syntax with an ESM-first TypeScript library, or attempting a default import when only named exports are available.fixEnsure you are using named imports with modern TypeScript/ESM syntax: `import { TestServer } from 'test-server-sdk';`. If using CommonJS, it might require `const { TestServer } = require('test-server-sdk');` but ESM is preferred. -
Error: ENOENT: no such file or directory, stat './recordings/some-test.json'
cause The `recordingPath` specified in `TestServerOptions` either does not exist or the process lacks the necessary write permissions to create or access files within it.fixEnsure the directory specified by `recordingPath` exists before starting the `TestServer`. You can add `fs.mkdirSync(recordingsDir, { recursive: true });` in your setup code. Also, check that your application has read/write permissions for that directory.
Warnings
- breaking The internal recording format changed to a JSON serializable structure. Existing recordings made with versions prior to v0.2.6 may not be compatible with newer SDK versions for replay, requiring regeneration of test data.
- gotcha The SDK is designed to work with a separate `test-server` binary. This package provides the TypeScript client, but the actual proxying and recording functionality depends on the `test-server` process being run externally or managed by this SDK. Ensure the `test-server` is accessible and correctly configured (e.g., firewall rules, port availability).
- gotcha Dynamic subdirectory recording paths were introduced, which might change default recording locations or require explicit configuration for managing test data. If you relied on a flat recording structure, this could lead to recordings not being found.
Install
-
npm install test-server-sdk -
yarn add test-server-sdk -
pnpm add test-server-sdk
Imports
- TestServer
const TestServer = require('test-server-sdk').TestServer;import { TestServer } from 'test-server-sdk'; - TestServerOptions
import { Options } from 'test-server-sdk';import { TestServerOptions } from 'test-server-sdk'; - RecordingMode
import { RecordingMode } from 'test-server-sdk';
Quickstart
import { TestServer, RecordingMode, TestServerOptions } from 'test-server-sdk';
import fetch from 'node-fetch'; // For example HTTP client
import * as path from 'path';
import * as fs from 'fs';
async function runTestScenario() {
const recordingsDir = path.join(__dirname, 'recordings');
if (!fs.existsSync(recordingsDir)) {
fs.mkdirSync(recordingsDir);
}
const serverOptions: TestServerOptions = {
port: 9000,
recordingPath: recordingsDir,
mode: RecordingMode.Record, // Start in recording mode
// Assume health check path for the test server itself
healthPath: '/health'
};
const testServer = new TestServer(serverOptions);
try {
console.log('Starting Test Server in Record mode...');
await testServer.start();
console.log(`Test Server listening on http://localhost:${serverOptions.port}`);
// Make a request to be recorded
console.log('Making a request to the test server...');
const response = await fetch(`http://localhost:${serverOptions.port}/api/data?id=123`);
const data = await response.json();
console.log('Received data:', data);
// In a real test, you'd assert on `data` or switch to replay mode for subsequent runs.
} catch (error) {
console.error('Test scenario failed:', error);
} finally {
console.log('Stopping Test Server...');
await testServer.stop();
console.log('Test Server stopped.');
}
}
runTestScenario().catch(err => console.error('Unhandled scenario error:', err));