- Updated: March 18, 2026
- 7 min read
Building an Automated Testing Suite for the OpenClaw Rating API over WebSockets
You can build a reliable, secure, and high‑performance automated testing suite for the OpenClaw rating API over WebSockets by setting up a lightweight WebSocket client, designing modular test cases, wiring them together in Node‑RED, applying the latest security hardening guidelines, and finally deploying the whole workflow on the UBOS platform.
1. Introduction
OpenClaw’s rating API is a real‑time WebSocket endpoint that powers autonomous agents with instant feedback loops. While its low‑latency design is perfect for continuous‑agent scenarios, developers often struggle to verify correctness, guard against security regressions, and keep performance in check. This guide walks you through a complete, step‑by‑step process to create an automated testing suite that runs locally, integrates with UBOS, and follows the most recent security and performance best practices.
Whether you are a solo engineer building a proof‑of‑concept or part of a larger team delivering enterprise AI solutions, the patterns described here are MECE‑structured, reusable, and ready for CI/CD pipelines.
2. Prerequisites
- Node.js ≥ 18 and npm ≥ 9
- Docker (optional, for isolated UBOS deployment)
- Access to an OpenClaw gateway (default
ws://localhost:18789) - API token with
rating:readscope - Basic familiarity with Node‑RED flow design
- Understanding of WebSocket security (see the OpenClaw vulnerability report)
3. Overview of the OpenClaw rating API (WebSockets)
The rating API accepts a JSON payload containing a sessionKey, agentId, and the message to be rated. Responses are streamed back as Server‑Sent Events (SSE) over the same WebSocket connection, allowing the client to receive incremental “delta” updates. A typical request looks like:
{
"message": "Rate the relevance of this answer.",
"sessionKey": "session-123",
"agentId": "default",
"options": {
"thinking": "medium",
"model": "anthropic/claude-3-5-sonnet"
}
}The API returns a stream of events such as:
event: delta
data: {"delta":"The","runId":"run-456"}
event: delta
data: {"delta":" rating","runId":"run-456"}
event: done
data: {"runId":"run-456","finishReason":"stop"}For a full reference, see the OpenClaw API Reference.
4. Setting up the WebSocket client
We’ll use the lightweight ws library. Create a new project folder and install dependencies:
mkdir openclaw-test‑suite
cd openclaw-test‑suite
npm init -y
npm install ws dotenv mocha chai
Store your token in a .env file (never commit this file):
OPENCLAW_TOKEN=your‑secure‑token
The client wrapper (client.js) abstracts connection handling, automatic reconnection, and message framing:
require('dotenv').config();
const WebSocket = require('ws');
class OpenClawClient {
constructor(url) {
this.url = url;
this.token = process.env.OPENCLAW_TOKEN;
this.ws = null;
this.pending = [];
}
connect() {
return new Promise((resolve, reject) => {
this.ws = new WebSocket(this.url, {
headers: { Authorization: `Bearer ${this.token}` }
});
this.ws.on('open', () => resolve());
this.ws.on('message', (data) => this._handleMessage(data));
this.ws.on('error', (err) => reject(err));
this.ws.on('close', () => console.warn('WebSocket closed, reconnecting...'));
});
}
_handleMessage(data) {
const msg = JSON.parse(data);
if (msg.runId && this.pending[msg.runId]) {
this.pending[msg.runId].push(msg);
}
}
send(payload) {
return new Promise((resolve) => {
const runId = `run-${Date.now()}`;
this.pending[runId] = [];
const enriched = { ...payload, runId };
this.ws.send(JSON.stringify(enriched));
// Simple timeout‑based collector (replace with event‑driven in prod)
setTimeout(() => resolve(this.pending[runId]), 2000);
});
}
}
module.exports = OpenClawClient;This client will be the backbone of every automated test case.
5. Designing automated test cases
A robust suite should cover:
- Basic connectivity and authentication
- Correct handling of
deltastreams - Rate‑limit enforcement
- Input validation (empty message, oversized payload)
- Security checks (token leakage, unauthorized origins)
- Performance benchmarks (latency, throughput)
Below is an example Mocha test for the “basic connectivity” scenario:
const { expect } = require('chai');
const OpenClawClient = require('./client');
describe('OpenClaw Rating API – Connectivity', function() {
this.timeout(5000);
let client;
before(async () => {
client = new OpenClawClient('ws://localhost:18789');
await client.connect();
});
it('should authenticate and receive a runId', async () => {
const response = await client.send({
message: 'Hello!',
sessionKey: 'test-session',
agentId: 'default',
options: {}
});
expect(response).to.be.an('array').that.is.not.empty;
const runIds = response.map(r => r.runId);
expect(runIds[0]).to.match(/^run-\d+$/);
});
});
Replicate this pattern for each test case, storing them under test/. Use chai‑as‑promised for async assertions and nyc for coverage.
6. Implementing the test suite with Node‑RED
Node‑RED provides a visual flow editor that aligns perfectly with the Workflow automation studio on UBOS. Follow these steps:
-
Install Node‑RED locally:
npm install -g --unsafe-perm node-red -
Create a custom node that wraps
OpenClawClient. In the Node‑RED editor, go to Manage palette → Install → node-red-contrib-openclaw (or create a local module). -
Design the test flow:
- Inject node – triggers a test case (e.g., “Run connectivity test”).
- Function node – builds the JSON payload.
- OpenClaw node – sends the payload over WebSocket.
- Switch node – evaluates the streamed response (pass/fail).
- Dashboard node – visualizes results in real time.
- Parameterize with environment variables so the same flow works across dev, staging, and production.
- Export the flow JSON and store it in your Git repository for CI execution.
The resulting flow can be executed via the node-red-cli in headless mode, making it suitable for automated pipelines.
7. Applying security best practices
The recent OpenClaw vulnerability analysis highlighted three critical attack vectors:
- Localhost WebSocket exposure – any malicious website can open a connection to
ws://127.0.0.1if the gateway is not bound to a loopback‑only interface. - Token leakage via logs – verbose logging of the
Authorizationheader can expose API keys. - Unrestricted tool‑calling – agents may invoke system commands without validation.
Mitigate these risks by:
- Binding the gateway to
127.0.0.1and enabling--require‑authflag. - Rotating tokens every 30 days and storing them in a vault (e.g., HashiCorp Vault or AWS Secrets Manager).
- Implementing a UBOS partner program‑approved middleware that sanitizes tool‑call payloads.
- Enforcing CORS‑like origin checks in the WebSocket handshake (custom header
X-Allowed-Origin).
In the Node‑RED flow, add a function node that strips any Authorization header from outgoing logs and masks the token before persisting test results.
8. Optimizing performance
Performance bottlenecks often stem from excessive round‑trips and large payloads. The OpenClaw API Complete Guide recommends:
- Enabling WebSocket streaming mode (
stream: true) to receive incremental deltas instead of waiting for the full response. - Compressing JSON payloads with
gzipwhen payload size exceeds 2 KB. - Reusing a single persistent WebSocket connection across multiple test cases.
- Parallelizing independent test cases using Node‑RED’s
parallelnode or a customPromise.allwrapper.
To benchmark latency, add a timestamp before sending the request and compute the delta when the done event arrives:
const start = Date.now();
const response = await client.send(payload);
const latency = Date.now() - start;
console.log(`Latency: ${latency} ms`);Record these metrics in a Prometheus‑compatible format and visualize them on Grafana for continuous performance monitoring.
9. Deploying the suite on UBOS
UBOS provides a one‑click OpenClaw hosting solution that bundles the gateway, a reverse‑proxy, and a secure secrets manager. Follow these steps to push your test suite:
-
Containerize the test runner:
FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . CMD ["node", "run-tests.js"] - Push the image to UBOS Container Registry via the Enterprise AI platform by UBOS.
-
Create a UBOS service using the UBOS platform overview UI. Select “WebSocket” as the protocol, bind to
localhost:18789, and attach the secret containing your API token. - Schedule the test container with UBOS’s built‑in cron scheduler (found under Workflow automation studio). Set it to run nightly or on every code push.
-
Integrate results with UBOS dashboards. Use the AI marketing agents module to send a Slack or Telegram alert when a test fails. Example:
if (testFailed) { sendTelegram('⚠️ OpenClaw rating API test failed!'); }The Telegram integration on UBOS makes this notification instant.
After deployment, you can view live logs in the UBOS console, and the automated suite will continuously validate both functional correctness and performance SLAs.
10. Conclusion
Building an automated testing suite for the OpenClaw rating API over WebSockets is a multi‑layered effort that blends low‑level client code, visual workflow orchestration, rigorous security hardening, and performance tuning. By following the steps above—and leveraging UBOS’s integrated services such as the Web app editor on UBOS and the UBOS templates for quick start—you gain a repeatable, CI‑ready pipeline that protects your AI agents from regressions and attacks while keeping latency under control.
Ready to accelerate your AI development? Explore the UBOS solutions for SMBs or dive into the UBOS for startups to spin up more AI‑powered services in minutes.