Skip to main content

ADVANCED

WebSocket Testing

Test real-time WebSocket connections with built-in support for text and binary messages, custom handlers, and seamless async event integration.

On this page:

Basic WebSocket Connection

Connect to a WebSocket endpoint and exchange messages using karate.webSocket():

Gherkin
Feature: Simple WebSocket

Scenario: Send and receive text message
* def socket = karate.webSocket('wss://echo.websocket.events')
* socket.send('Hello WebSocket')
* listen 5000
* match listenResult == 'Hello WebSocket'

Without a handler function, listen returns the first message received. The connection auto-closes when the scenario ends.

Method Signatures

Three forms are available:

SignatureDescription
karate.webSocket(url)Connect with defaults, returns first message
karate.webSocket(url, handler)Connect with custom message handler
karate.webSocket(url, handler, options)Connect with handler and configuration

Message Handlers

Filter incoming messages with custom handler functions. The handler receives each message and returns true to capture it (completing the listen wait) or false to ignore and keep waiting:

Gherkin
Feature: Filtered WebSocket messages

Scenario: Wait for specific message type
# Handler captures only messages starting with 'hello'
* def handler = function(msg){ return msg.startsWith('hello') }
* def socket = karate.webSocket(wsUrl, handler)
* socket.send('Billie')
* listen 5000
* match listenResult == 'hello Billie !'
Handler Pattern

Use handlers to filter out heartbeats, system messages, or irrelevant events. The handler is called for each incoming message until it returns true.

WebSocket Options

Configure authentication, sub-protocols, and payload limits with the options parameter:

Gherkin
Feature: Authenticated WebSocket

Scenario: Connect with JWT authentication
* def token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
* def options = { subProtocol: 'chat', headers: { Authorization: 'Bearer ' + token }, maxPayloadSize: 8388608 }
* def socket = karate.webSocket('wss://api.example.com/socket', null, options)
* socket.send('{ "action": "subscribe", "channel": "updates" }')
* listen 5000
* match listenResult contains 'channel'

Available Options

OptionDescriptionDefault
subProtocolProtocol negotiation string expected by servernone
headersAuthentication tokens, API keys, or custom headersnone
maxPayloadSizeMaximum message size in bytes4194304 (4 MB)

Binary Messages

Handle binary WebSocket payloads with karate.webSocketBinary():

Gherkin
Feature: Binary WebSocket

Scenario: Send and receive binary data
* def binarySocket = karate.webSocketBinary('ws://localhost:8080/binary')
* bytes payload = read('classpath:test-data.bin')
* binarySocket.send(payload)
* listen 5000
* bytes received = listenResult
* match received.length > 0

The karate.webSocketBinary() method has the same signatures as karate.webSocket() but handles byte arrays instead of strings. Use it for image uploads, file transfers, or any non-text protocol.

Listen and Signal Pattern

WebSocket integrates with Karate's async listen keyword for event-driven testing. The listen keyword pauses execution until the handler returns true or timeout expires:

Gherkin
Feature: Async WebSocket workflow

Background:
* def wsUrl = 'ws://localhost:8080/events'

Scenario: Trigger action and wait for event
* def handler =
"""
function(msg) {
var data = JSON.parse(msg);
return data.type === 'completed';
}
"""
* def socket = karate.webSocket(wsUrl, handler)
# Trigger async operation via HTTP
Given url baseUrl + '/process'
And request { orderId: 'ORD-123', priority: 'high' }
When method post
Then status 202
# Wait for WebSocket notification (max 10 seconds)
* listen 10000
* def event = JSON.parse(listenResult)
* match event == { type: 'completed', orderId: 'ORD-123', status: 'success' }

If timeout occurs without the handler returning true, listenResult is null.

Connection Cleanup

WebSocket connections auto-close at scenario end. For long-running scenarios, close explicitly with socket.close() to free resources.

Multi-Message Workflows

Test sequences of WebSocket interactions:

Gherkin
Feature: Chat workflow

Scenario: Join room and exchange messages
* def socket = karate.webSocket('ws://localhost:8080/chat')
# Join room
* socket.send('{ "action": "join", "room": "lobby" }')
* listen 3000
* match listenResult contains 'joined'
# Send message
* socket.send('{ "action": "message", "text": "Hello everyone" }')
* listen 3000
* match listenResult contains 'Hello everyone'
# Leave room
* socket.send('{ "action": "leave" }')
* listen 3000
* match listenResult contains 'left'

Event Correlation

Correlate WebSocket events with HTTP operations by collecting events in a handler:

Gherkin
Feature: Order processing pipeline

Scenario: Track order through WebSocket events
* def orderId = java.util.UUID.randomUUID() + ''
* def events = []
* def handler =
"""
function(msg) {
var event = JSON.parse(msg);
if (event.orderId === orderId) {
events.push(event);
return event.status === 'shipped';
}
return false;
}
"""
* def socket = karate.webSocket('ws://localhost:8080/orders', handler)
# Place order via HTTP
Given url baseUrl + '/orders'
And request { id: '#(orderId)', items: ['item1', 'item2'] }
When method post
Then status 201
# Wait for final event
* listen 15000
* match events == '#[3]'
* match events[2].status == 'shipped'

Next Steps