Node.js SDK
Run AI-powered UX tests from Node.js or TypeScript with the official SimuTest SDK.
Installation
Install the SDK using your preferred package manager:
npm install @simutest/sdkThe package ships with full TypeScript types — no @types package needed. Requires Node.js 18 or later.
Quick Start
Import SimuTest, instantiate with your API key, and call test(). Results are returned once all sessions finish.
import { SimuTest } from '@simutest/sdk';
const simutest = new SimuTest({
apiKey: process.env.SIMUTEST_API_KEY,
});
const results = await simutest.test({
url: 'http://localhost:3000',
task: 'Sign up for a free trial',
sessions: 100,
model: 'claude-sonnet',
personas: 'auto-diverse',
criteria: ['cta_findability', 'task_completion', 'trust_credibility'],
viewport: 'mobile',
});
console.log(results.summary);
// { overall_score: 7.2, sessions_completed: 98, top_issue: "..." }
for (const session of results.sessions) {
console.log(session.persona.name, session.scores.task_completion);
console.log(session.thinking_trace);
}
// Assert in tests
assert(results.summary.overall_score >= 7.0, 'UX score regression');Configuration
Pass options to the SimuTest constructor to configure the client:
const simutest = new SimuTest({
apiKey: process.env.SIMUTEST_API_KEY, // required
baseUrl: 'https://api.simutest.dev', // optional, default shown
timeout: 300_000, // optional, ms (default: 5 min)
});| Option | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Yes | Your SimuTest API key |
| baseUrl | string | No | API base URL (default: https://api.simutest.dev) |
| timeout | number | No | Request timeout in milliseconds (default: 300000) |
Running Tests
The simutest.test() method accepts a configuration object with the following options:
const results = await simutest.test({
// Required
url: 'http://localhost:3000',
task: 'Complete the onboarding flow',
// Session configuration
sessions: 100, // number of simulated sessions
model: 'claude-sonnet', // AI model to use
personas: 'auto-diverse', // 'auto-diverse' or custom persona array
// Evaluation criteria
criteria: [
'cta_findability',
'task_completion',
'trust_credibility',
'navigation_clarity',
'error_handling',
],
// Viewport
viewport: 'mobile', // 'mobile' | 'desktop' | 'tablet'
// Authentication (optional)
auth: {
method: 'credentials',
loginUrl: 'http://localhost:3000/login',
usernameEnv: 'TEST_USERNAME',
passwordEnv: 'TEST_PASSWORD',
successUrl: 'http://localhost:3000/dashboard',
},
});| Option | Type | Description |
|---|---|---|
| url | string | URL of the page to test |
| task | string | Natural language task for agents to complete |
| sessions | number | Number of simulated user sessions (default: 100) |
| model | string | AI model: claude-sonnet | claude-opus |
| personas | string | object[] | 'auto-diverse' or an array of custom persona definitions |
| criteria | string[] | Evaluation metrics to score (e.g. task_completion) |
| viewport | string | 'mobile' | 'desktop' | 'tablet' |
| auth | object | Authentication configuration (optional) |
Results Object
The test() method returns a TestResult object with the following TypeScript types:
interface TestResult {
testId: string;
status: 'completed' | 'failed';
summary: {
overall_score: number; // 0–10
sessions_completed: number;
sessions_failed: number;
top_issue: string;
scores: Record<string, number>;
};
sessions: SessionResult[];
}
interface SessionResult {
sessionId: string;
persona: {
name: string;
age: number;
tech_savviness: 'low' | 'medium' | 'high';
description: string;
};
scores: Record<string, number>;
completed: boolean;
thinking_trace: ThinkingTrace[];
duration_ms: number;
}
interface ThinkingTrace {
step: number;
thought: string;
action: string;
url: string;
timestamp: string;
}Assertions
Use SimuTest results directly in your test suite. The SDK works with any test framework that supports async tests, including Jest and Vitest:
// Jest / Vitest
import { SimuTest } from '@simutest/sdk';
import { describe, it, expect, beforeAll } from 'vitest';
describe('Homepage UX', () => {
let results: Awaited<ReturnType<typeof simutest.test>>;
beforeAll(async () => {
const simutest = new SimuTest({ apiKey: process.env.SIMUTEST_API_KEY });
results = await simutest.test({
url: process.env.PREVIEW_URL!,
task: 'Find and click the Get Started button',
sessions: 50,
criteria: ['cta_findability', 'task_completion'],
});
});
it('overall UX score meets threshold', () => {
expect(results.summary.overall_score).toBeGreaterThanOrEqual(7.0);
});
it('CTA findability score is acceptable', () => {
expect(results.summary.scores.cta_findability).toBeGreaterThanOrEqual(6.5);
});
it('majority of sessions complete the task', () => {
const completionRate =
results.summary.sessions_completed / 50;
expect(completionRate).toBeGreaterThan(0.8);
});
});Error Handling
The SDK throws a SimuTestError on API errors. Check err.code to handle specific failure modes:
import { SimuTest, SimuTestError } from '@simutest/sdk';
const simutest = new SimuTest({ apiKey: process.env.SIMUTEST_API_KEY });
try {
const results = await simutest.test({ url: '...', task: '...' });
} catch (err) {
if (err instanceof SimuTestError) {
console.error('SimuTest error:', err.code, err.message);
switch (err.code) {
case 'INVALID_API_KEY':
// Check your SIMUTEST_API_KEY env var
break;
case 'QUOTA_EXCEEDED':
// Upgrade your plan or reduce session count
break;
case 'URL_UNREACHABLE':
// Ensure the target URL is accessible from SimuTest servers
break;
case 'TIMEOUT':
// Increase timeout in SimuTest constructor options
break;
}
}
throw err;
}| Error Code | Description |
|---|---|
| INVALID_API_KEY | The provided API key is missing or invalid |
| QUOTA_EXCEEDED | Session quota for your plan has been reached |
| URL_UNREACHABLE | Target URL could not be reached from SimuTest servers |
| TIMEOUT | Test exceeded the configured timeout duration |
| INVALID_CRITERIA | One or more criteria names are unrecognized |
On this page