Documentation

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/sdk

The 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)
});
OptionTypeRequiredDescription
apiKeystringYesYour SimuTest API key
baseUrlstringNoAPI base URL (default: https://api.simutest.dev)
timeoutnumberNoRequest 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',
  },
});
OptionTypeDescription
urlstringURL of the page to test
taskstringNatural language task for agents to complete
sessionsnumberNumber of simulated user sessions (default: 100)
modelstringAI model: claude-sonnet | claude-opus
personasstring | object[]'auto-diverse' or an array of custom persona definitions
criteriastring[]Evaluation metrics to score (e.g. task_completion)
viewportstring'mobile' | 'desktop' | 'tablet'
authobjectAuthentication 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 CodeDescription
INVALID_API_KEYThe provided API key is missing or invalid
QUOTA_EXCEEDEDSession quota for your plan has been reached
URL_UNREACHABLETarget URL could not be reached from SimuTest servers
TIMEOUTTest exceeded the configured timeout duration
INVALID_CRITERIAOne or more criteria names are unrecognized