Runtime Globals

External test cases have access to these globals at runtime.

Variables and Secrets

$vars

Variable group values (read-only):

// Access variables from the selected variable group
const apiUrl = $vars.apiUrl;
const timeout = $vars.defaultTimeout;
const testEmail = $vars.testUserEmail;
 
// Usage
const response = await fetch(`${$vars.apiUrl}/users`);

$secrets

Decrypted secret values (read-only, never logged):

// Access secrets securely
const apiKey = $secrets.apiKey;
const password = $secrets.testUserPassword;
const dbConnection = $secrets.databaseUrl;
 
// Usage
const response = await fetch(url, {
  headers: { "X-API-Key": $secrets.apiKey },
});

Server Configuration

$server

Current server configuration:

interface Server {
  id: string;       // Server ID
  name: string;     // Server name (e.g., "Production", "Staging")
  baseUrl: string;  // Base URL for API requests
}
 
// Usage
const response = await fetch(`${$server.baseUrl}/api/users`);
$log("info", `Testing against ${$server.name}`);

Authentication

$auth

Authentication configuration:

interface Auth {
  type: "bearer" | "apiKey" | "basic" | "none";
  headers: Record<string, string>;  // Pre-built auth headers
  token?: string;      // Bearer token (if type is "bearer")
  apiKey?: string;     // API key value (if type is "apiKey")
  apiKeyHeader?: string; // Header name for API key
}
 
// Usage - just spread the headers
const response = await fetch(url, {
  headers: {
    "Content-Type": "application/json",
    ...$auth.headers,  // Includes Authorization header
  },
});
 
// Or access directly
if ($auth.type === "bearer") {
  console.log(`Using token: ${$auth.token.slice(0, 10)}...`);
}

Test Context

$context

Shared test context (read/write):

// Write to context
$context.userId = response.data.id;
$context.authToken = loginResponse.token;
$context.testData = { items: [...] };
 
// Read from context
const userId = $context.userId;
const token = $context.authToken;
 
// Context persists across tests in the same flow

Functions

$addAssertionResult()

Record an assertion result:

interface AssertionResult {
  passed: boolean;      // Did it pass?
  message: string;      // Human-readable description
  operator: string;     // Assertion type for reports
  leftValue: any;       // Actual value
  rightValue: any;      // Expected value
}
 
$addAssertionResult({
  passed: response.status === 200,
  message: `Status code is ${response.status}`,
  operator: "equals",
  leftValue: response.status,
  rightValue: 200,
});

$log()

Log messages for debugging:

type LogLevel = "info" | "warn" | "error" | "debug";
 
$log(level: LogLevel, message: string, data?: any): void;
 
// Examples
$log("info", "Test started");
$log("debug", "Request payload", { body: requestBody });
$log("warn", "Slow response", { duration: 5000 });
$log("error", "Unexpected error", { error: err.message });

$reportApiRequest()

Report API calls for test tracing:

interface ApiReport {
  method: string;
  url: string;
  status: number;
  duration: number;
  requestHeaders?: Record<string, string>;
  requestBody?: any;
  responseHeaders?: Record<string, string>;
  responseBody?: any;
}
 
$reportApiRequest({
  method: "POST",
  url: `${$server.baseUrl}/api/users`,
  status: 201,
  duration: 150,
  requestBody: { email: "test@example.com" },
  responseBody: { id: 123 },
});

Built-in Libraries

These are always available:

Lodash (_)

const filtered = _.filter(users, { active: true });
const grouped = _.groupBy(orders, "status");
const unique = _.uniq(ids);

Faker (faker)

const email = faker.internet.email();
const name = faker.person.fullName();
const uuid = faker.string.uuid();

Zod (z)

const schema = z.object({
  id: z.number(),
  email: z.string().email(),
});
const result = schema.safeParse(data);

Ky (ky)

const data = await ky.get(url).json();
const response = await ky.post(url, { json: body }).json();

Luxon (luxon)

const now = luxon.DateTime.now();
const formatted = now.toFormat("yyyy-MM-dd");
const tomorrow = now.plus({ days: 1 });

Fetch (fetch)

const response = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(data),
});

Complete Example

import { testCase } from '@reapi/test-sdk'
 
export const completeExample = testCase(
  {
    id: 'complete-example',
    name: 'Complete Example',
    tags: ['example'],
  },
  async () => {
    // Log start
    $log('info', 'Starting test', { server: $server.name })
 
    // Use variables and secrets
    const url = `${$server.baseUrl}/api/auth/login`
    
    // Make request with auth
    const startTime = Date.now()
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...$auth.headers,
      },
      body: JSON.stringify({
        email: $vars.testUserEmail,
        password: $secrets.testUserPassword,
      }),
    })
    const duration = Date.now() - startTime
    const data = await response.json()
 
    // Report the API call
    $reportApiRequest({
      method: 'POST',
      url,
      status: response.status,
      duration,
      responseBody: data,
    })
 
    // Validate with Zod
    const schema = z.object({
      token: z.string(),
      user: z.object({ id: z.number() }),
    })
    const validation = schema.safeParse(data)
 
    // Record assertions
    $addAssertionResult({
      passed: response.status === 200,
      message: `Login status: ${response.status}`,
      operator: 'status',
      leftValue: response.status,
      rightValue: 200,
    })
 
    $addAssertionResult({
      passed: validation.success,
      message: validation.success ? 'Response valid' : validation.error.message,
      operator: 'schema',
      leftValue: data,
      rightValue: 'login response schema',
    })
 
    // Store in context for other tests
    if (data.token) {
      $context.authToken = data.token
      $context.userId = data.user.id
    }
 
    $log('info', 'Test completed', { passed: response.status === 200 })
  }
)