Mock HTTP server for testing HTTP clients and stubbing webservices
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
WebSocket connection interception and mocking with support for message echoing, forwarding, and custom handling for testing real-time applications.
Create rules for matching and handling WebSocket upgrade requests.
interface Mockttp {
/**
* Create a rule builder for matching WebSocket connections.
* Matches the initial HTTP upgrade request that establishes the WebSocket.
*/
forAnyWebSocket(): WebSocketRuleBuilder;
}
interface WebSocketRuleBuilder {
/**
* Match WebSocket upgrades for specific paths.
* Supports string paths, full URLs, and regular expressions.
*/
withPath(path: string | RegExp): this;
/**
* Match WebSocket upgrades with specific headers.
* Useful for matching custom protocols or authentication.
*/
withHeaders(headers: Headers): this;
/**
* Match WebSocket upgrades with specific query parameters.
*/
withQuery(query: {[key: string]: string | string[] | undefined}): this;
/**
* Match WebSocket requests to specific hostname.
*/
withHostname(hostname: string | RegExp): this;
/**
* Match WebSocket requests to specific host (hostname:port).
*/
withHost(host: string | RegExp): this;
/**
* Match WebSocket requests to specific host (hostname:port).
* Alternative method name for withHost.
*/
forHost(host: string): this;
/**
* Match WebSocket requests to specific hostname only.
* Alternative method name for withHostname.
*/
forHostname(hostname: string): this;
/**
* Match WebSocket requests on specific port number.
*/
withPort(port: number): this;
/**
* Match WebSocket requests on specific port number.
* Alternative method name for withPort.
*/
forPort(port: number): this;
/**
* Match WebSocket requests with specific protocol (ws/wss).
*/
withProtocol(protocol: "ws" | "wss"): this;
/**
* Match WebSocket requests where URL matches regular expression.
*/
withUrlMatching(pattern: RegExp): this;
/**
* Match WebSocket requests with specific body content.
* Less common for WebSockets but available from inherited base.
*/
withBody(content: string | RegExp): this;
/**
* Match WebSocket requests with exact JSON body content.
* Less common for WebSockets but available from inherited base.
*/
withJsonBody(json: object): this;
/**
* Match WebSocket requests with partial JSON body content.
* Less common for WebSockets but available from inherited base.
*/
withJsonBodyIncluding(json: object): this;
/**
* Match WebSocket requests with specific cookie values.
*/
withCookie(cookie: {[key: string]: string}): this;
/**
* Match WebSocket upgrades using custom matching logic.
*/
matching(callback: (request: CompletedRequest) => boolean | Promise<boolean>): this;
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Match any WebSocket connection
await mockServer.forAnyWebSocket()
.thenEcho();
// Match specific path
await mockServer.forAnyWebSocket()
.withPath("/chat")
.thenEcho();
// Match with custom headers
await mockServer.forAnyWebSocket()
.withPath("/secure-chat")
.withHeaders({
"Sec-WebSocket-Protocol": "chat-v1",
"Authorization": /^Bearer .+/
})
.thenPassivelyListen();
// Match with query parameters
await mockServer.forAnyWebSocket()
.withPath("/notifications")
.withQuery({ userId: "123", token: "abc" })
.thenEcho();
// Custom matching logic
await mockServer.forAnyWebSocket()
.matching((request) => {
const protocols = request.headers['sec-websocket-protocol'];
return protocols && protocols.includes('myapp-v2');
})
.thenPassThrough();Actions for handling WebSocket connections after they're matched.
interface WebSocketRuleBuilder {
/**
* Accept the WebSocket and echo all received messages back to the client.
* Useful for testing WebSocket client implementations.
*/
thenEcho(): Promise<MockedEndpoint>;
/**
* Accept the WebSocket and listen passively without sending messages.
* Useful for testing message sending without interference.
*/
thenPassivelyListen(): Promise<MockedEndpoint>;
/**
* Forward the WebSocket to the original target server.
* Enables selective WebSocket mocking while preserving real connections.
*/
thenPassThrough(options?: PassThroughWebSocketStepOptions): Promise<MockedEndpoint>;
/**
* Forward the WebSocket to a specific target URL.
* Enables WebSocket proxying and redirection.
*/
thenForwardTo(
target: string,
options?: PassThroughWebSocketStepOptions
): Promise<MockedEndpoint>;
/**
* Reject the WebSocket upgrade request with an HTTP error response.
* Useful for testing connection failure scenarios.
*/
thenRejectConnection(
statusCode?: number,
statusMessage?: string,
headers?: Headers,
body?: Buffer | string
): Promise<MockedEndpoint>;
/**
* Close the connection immediately without accepting the WebSocket.
* Simulates server crashes or network failures.
*/
thenCloseConnection(): Promise<MockedEndpoint>;
/**
* Reset the connection with a TCP RST packet.
* Simulates aggressive connection termination.
*/
thenResetConnection(): Promise<MockedEndpoint>;
/**
* Hold the connection open indefinitely without responding.
* Simulates server timeouts during WebSocket upgrade.
*/
thenTimeout(): Promise<MockedEndpoint>;
/**
* Add a delay before processing the WebSocket connection.
* Can be chained with other WebSocket actions.
*/
delay(ms: number): this;
}
interface PassThroughWebSocketStepOptions {
/**
* Custom DNS lookup options for the target server.
*/
lookupOptions?: PassThroughLookupOptions;
/**
* Connection options for the upstream WebSocket.
*/
connectionOptions?: PassThroughStepConnectionOptions;
/**
* Forwarding configuration for the WebSocket.
*/
forwardingOptions?: ForwardingOptions;
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal();
await mockServer.start();
// Echo server for testing
await mockServer.forAnyWebSocket()
.withPath("/echo")
.thenEcho();
// Silent listener for one-way testing
await mockServer.forAnyWebSocket()
.withPath("/send-only")
.thenPassivelyListen();
// Forward to real WebSocket server
await mockServer.forAnyWebSocket()
.withPath("/chat")
.thenForwardTo("wss://chat.example.com/socket");
// Reject unauthorized connections
await mockServer.forAnyWebSocket()
.withPath("/admin")
.matching((req) => !req.headers.authorization)
.thenRejectConnection(401, "Unauthorized", {
"WWW-Authenticate": "Bearer"
});
// Accept authorized connections
await mockServer.forAnyWebSocket()
.withPath("/admin")
.matching((req) => req.headers.authorization === "Bearer valid-token")
.thenPassThrough();
// Simulate connection failure
await mockServer.forAnyWebSocket()
.withPath("/unreliable")
.thenCloseConnection();
// Delayed WebSocket handling
await mockServer.forAnyWebSocket()
.withPath("/slow")
.delay(2000)
.thenEcho();Monitor WebSocket connections and messages through the event system.
interface Mockttp {
/**
* Subscribe to WebSocket upgrade requests (before acceptance/rejection).
*/
on(event: 'websocket-request', callback: (req: CompletedRequest) => void): Promise<void>;
/**
* Subscribe to WebSocket upgrade acceptances (after successful upgrade).
*/
on(event: 'websocket-accepted', callback: (res: CompletedResponse) => void): Promise<void>;
/**
* Subscribe to messages received from WebSocket clients.
*/
on(event: 'websocket-message-received', callback: (msg: WebSocketMessage) => void): Promise<void>;
/**
* Subscribe to messages sent to WebSocket clients.
*/
on(event: 'websocket-message-sent', callback: (msg: WebSocketMessage) => void): Promise<void>;
/**
* Subscribe to WebSocket connection closures.
*/
on(event: 'websocket-close', callback: (close: WebSocketClose) => void): Promise<void>;
}
interface WebSocketMessage {
/**
* ID of the WebSocket stream (matches request/response IDs).
*/
streamId: string;
/**
* Direction of the message from Mockttp's perspective.
*/
direction: 'sent' | 'received';
/**
* Message content as raw bytes (already decompressed).
*/
content: Uint8Array;
/**
* Whether this is a binary message or text message.
*/
isBinary: boolean;
/**
* High-precision timestamp of when the message was processed.
*/
eventTimestamp: number;
/**
* Timing information for the WebSocket connection.
*/
timingEvents: TimingEvents;
/**
* Tags associated with this WebSocket connection.
*/
tags: string[];
}
interface WebSocketClose {
/**
* ID of the WebSocket stream (matches request/response IDs).
*/
streamId: string;
/**
* WebSocket close code (1000 = normal closure, etc.).
*/
closeCode: number | undefined;
/**
* Human-readable close reason.
*/
closeReason: string;
/**
* Timing information for the WebSocket connection.
*/
timingEvents: TimingEvents;
/**
* Tags associated with this WebSocket connection.
*/
tags: string[];
}Usage Examples:
import { getLocal } from "mockttp";
const mockServer = getLocal({ debug: true });
await mockServer.start();
// Monitor all WebSocket activity
await mockServer.on('websocket-request', (req) => {
console.log(`WebSocket requested: ${req.url}`);
});
await mockServer.on('websocket-accepted', (res) => {
console.log(`WebSocket accepted: ${res.id}`);
});
await mockServer.on('websocket-message-received', (msg) => {
const text = msg.isBinary ?
`<${msg.content.length} bytes>` :
new TextDecoder().decode(msg.content);
console.log(`Received: ${text}`);
});
await mockServer.on('websocket-message-sent', (msg) => {
const text = msg.isBinary ?
`<${msg.content.length} bytes>` :
new TextDecoder().decode(msg.content);
console.log(`Sent: ${text}`);
});
await mockServer.on('websocket-close', (close) => {
console.log(`WebSocket closed: ${close.closeCode} - ${close.closeReason}`);
});
// Set up WebSocket mock
await mockServer.forAnyWebSocket()
.withPath("/chat")
.thenEcho();Advanced methods for programmatic WebSocket rule management.
interface Mockttp {
/**
* Add multiple WebSocket rules to the server.
*/
addWebSocketRules(...ruleData: WebSocketRuleData[]): Promise<MockedEndpoint[]>;
/**
* Add a single WebSocket rule to the server.
*/
addWebSocketRule(ruleData: WebSocketRuleData): Promise<MockedEndpoint>;
/**
* Replace all existing WebSocket rules with the given rules.
* HTTP request rules are left untouched.
*/
setWebSocketRules(...ruleData: WebSocketRuleData[]): Promise<MockedEndpoint[]>;
}
interface WebSocketRuleData {
// Complex internal rule data structure
// Use fluent builder API when possible
}WebSocket connections can be matched on various aspects of the initial HTTP upgrade request:
Path Matching: Same patterns as HTTP requests - relative paths, full URLs, wildcards, regex
Header Matching: Match WebSocket-specific headers like Sec-WebSocket-Protocol, Sec-WebSocket-Extensions
Query Parameters: Match connection parameters passed in the upgrade URL
Custom Logic: Use callback functions for complex matching requirements
Common patterns for testing WebSocket applications:
Echo Testing: Use thenEcho() to test client message sending and receiving
Send-Only Testing: Use thenPassivelyListen() to test client sending without server responses
Protocol Testing: Match specific protocols and subprotocols using header matching
Authentication Testing: Reject connections without proper authentication headers
Error Handling: Test client error handling with thenRejectConnection() and connection control methods
Performance Testing: Use delay() to simulate slow WebSocket upgrades
WebSocket mocking differs from HTTP request mocking in several ways: