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​