Scripting Overview
ReAPI’s scripting capabilities let you write JavaScript code to handle complex testing scenarios that visual nodes can’t address. Scripts run in a secure sandbox environment compatible with both web and Node.js, giving you flexibility when you need it while keeping the primary interface accessible to QA teams.
This is the 0.1 in ReAPI’s N+0.1 model: visual nodes handle 95% of your testing needs, and scripting handles the remaining edge cases requiring custom logic, complex transformations, or specialized integrations.
Quick Navigation
Jump to the script type you need:
- Request/Response Hooks - Enhance API calls dynamically
- Reusable Functions - Build your testing toolkit
- Script Node - General-purpose JavaScript execution
- Global Functions - Shared utilities across all scripts
- JS Expressions - JSONata alternative for generating values
- External Libraries - Extend capabilities with third-party libraries
Request/Response Hooks
Hooks let you inject custom logic into the API request lifecycle, extending what API nodes can do.
Before Request Scripts
Run code immediately before sending an API request to dynamically modify the request.
Common Scenarios:
- Add authentication headers based on runtime conditions
- Inject timestamps or request IDs for tracking
- Modify request body based on environment or context
Example: Dynamic Authentication
async function beforeRequest() {
// Add JWT token to headers
$request.headers["Authorization"] = `Bearer ${$context.accessToken}`;
// Add request tracking
$request.headers["X-Request-ID"] = `req_${Date.now()}`;
// Inject timestamp for SLA validation
$context.requestStartTime = Date.now();
}Learn more about Before Request scripts →
After Response Scripts
Run code after receiving an API response to process data, perform assertions, or update context.
Common Scenarios:
- Extract tokens or IDs from responses for subsequent requests
- Calculate response time metrics
- Perform custom validations using business logic
- Transform response data before storing in context
Example: Token Extraction & Metrics
async function afterResponse() {
// Extract auth token for next requests
if ($response.data.token) {
$context.accessToken = $response.data.token;
}
// Calculate response time
$context.responseTime = Date.now() - $context.requestStartTime;
// Custom validation
$expect($response.status).to.equal(200);
$assert.isObject($response.data.user, "User object must be present");
}Learn more about After Response scripts →
Reusable Functions
Create libraries of reusable functions that can be called throughout your test suites.
Value Generator Scripts
Create functions that generate or transform data dynamically. These are perfect for creating test data with realistic values.
Unique Capability: Value generators can be called from JS expressions anywhere in your tests using js:$gen.generatorName(params).
Common Scenarios:
- Generate test users with realistic data
- Create dynamic API payloads
- Build mock data for testing edge cases
Example: User Generator
async function createTestUser(options) {
const { role = "user", includeAddress = false } = options || {};
return {
id: faker.string.uuid(),
email: faker.internet.email(),
name: faker.person.fullName(),
role: role,
createdAt: new Date().toISOString(),
...(includeAddress && {
address: {
street: faker.location.streetAddress(),
city: faker.location.city(),
country: faker.location.country(),
},
}),
};
}Usage: Call this generator in any expression field:
js:$gen.createTestUser({ role: 'admin', includeAddress: true })Learn more about Value Generators →
Custom Assertion Scripts
Create complex, reusable validation logic that integrates seamlessly with ReAPI’s assertion nodes.
Unique Capability: Once defined, custom assertions appear in the assertion node UI — QA teams can use them without writing any code.
Common Scenarios:
- Validate complex business rules (e.g., “is valid order”, “meets SLA”)
- Check data structure patterns
- Perform multi-field validations
Example: Valid User Assertion
async function isValidUser(value) {
try {
const isValid =
value &&
typeof value === "object" &&
typeof value.id === "string" &&
typeof value.email === "string" &&
value.email.includes("@") &&
typeof value.name === "string" &&
value.name.length > 0;
$addAssertionResult({
passed: isValid,
message: isValid
? "Value is a valid user object"
: "Value does not match user structure",
operator: "isValidUser",
leftValue: value,
rightValue: "user object",
});
} catch (error) {
$addAssertionResult({
passed: false,
message: `Validation error: ${error.message}`,
operator: "isValidUser",
leftValue: value,
rightValue: "user object",
});
}
}Usage: After defining this, QA teams select “isValidUser” from the assertion dropdown in the UI.
Learn more about Custom Assertions →
Script Node
The Script Node lets you run any JavaScript code as a step in your test flow. Use it for complex operations that don’t fit into other node types.
Common Scenarios:
- Multi-step data transformations
- Complex business logic calculations
- Batch processing of arrays
- Building complex nested data structures
Example: Processing Response Data
async function runScript() {
// Get response data from context
const orders = $context.apiResponse.orders;
// Process and categorize
const processed = {
total: orders.length,
byStatus: {},
highValue: [],
metrics: {
avgValue: 0,
totalValue: 0,
},
};
orders.forEach((order) => {
// Categorize by status
if (!processed.byStatus[order.status]) {
processed.byStatus[order.status] = [];
}
processed.byStatus[order.status].push(order.id);
// Track high-value orders
if (order.total > 1000) {
processed.highValue.push(order);
}
// Calculate metrics
processed.metrics.totalValue += order.total;
});
processed.metrics.avgValue = processed.metrics.totalValue / orders.length;
// Store results in context for next steps
$context.orderAnalysis = processed;
}Learn more about Script Node →
Global Functions
Global functions are utilities defined once and available across all script types in your project. They’re managed directly in the ReAPI web application.
Key Features:
- Centralized utility management
- Available in hooks, generators, assertions, and script nodes
- Loaded after external libraries (can use library functions)
- Built-in libraries available: lodash (
_), CryptoJS
Common Scenarios:
- Date/time formatters used everywhere
- Encryption/hashing utilities
- Common calculations or conversions
- Custom string manipulations
Example: Date Utilities Class
class $$DateUtils {
static formatToISO(date) {
return new Date(date).toISOString();
}
static isRecent(timestamp, hoursAgo = 24) {
const cutoff = Date.now() - hoursAgo * 60 * 60 * 1000;
return new Date(timestamp).getTime() > cutoff;
}
static daysBetween(date1, date2) {
const diff = Math.abs(new Date(date2) - new Date(date1));
return Math.floor(diff / (1000 * 60 * 60 * 24));
}
}Best Practice: Use class-based structure with unique prefixes (like $$) to avoid naming conflicts.
Usage in any script:
const formatted = $$DateUtils.formatToISO(new Date());
const isNew = $$DateUtils.isRecent($response.data.createdAt, 48);JS Expressions
JS expressions provide an alternative to JSONata for cases where you need to generate values rather than query existing data.
JSONata vs JS Expressions
| Goal | Tool | Example |
|---|---|---|
| Query existing data | JSONata (default) | body.user.id |
| Transform existing data | JSONata (default) | body.items[price > 100] |
| Generate new values | JS Expression (js:) | js:faker.internet.email() |
| Call value generators | JS Expression (js:) | js:createTestUser({role: 'admin'}) |
| Dynamic calculations | JS Expression (js:) | js:Date.now() - 3600000 |
When to Use JS Expressions
Use the js: prefix in expression fields when you need to:
- Generate mock data for testing
- Perform calculations for expected values
- Call your custom value generators
- Use lodash or faker functions
Example: Dynamic Timestamp Assertion
Assert that a response timestamp is recent (within the last hour):
# Assertion Node
- field: body.user.lastLogin
operator: greaterThan
expected: "js:Date.now() - 3600000" # One hour agoExample: Using Value Generators
# API Node Request Body
{
"user": "js:createTestUser({ role: 'admin' })",
"testId": "js:faker.string.uuid()",
}Example: Lodash Utility
# Context Node
contextVar: "js:_.random(1000, 9999)"Learn more about Template Engine & Expressions →
External Libraries
ReAPI provides comprehensive JavaScript library support for all your scripting needs.
Built-in Libraries (Always Available)
These libraries are pre-loaded and always available without any setup:
- Lodash (
_) - Data manipulation utilities (docs) - Faker - Mock data generation (docs)
- Zod (
z) - Schema validation, v4.x (docs) - Ky - Modern HTTP client (docs)
- Luxon - Date/time manipulation (docs)
Additional Library Support
- Predefined Libraries - Curated collection (CryptoJS, DayJS, Axios, Moment, Validator, Turf.js, Numeral)
- Custom Libraries - Load any IIFE/UMD library from a public URL
- ESM Bundler Service - Convert modern ESM modules to IIFE format
📚 View complete library documentation →
Learn about all available libraries, examples, the ESM Bundler Service, and how to add custom libraries.
Sandbox Environment
All scripts run in a secure, isolated sandbox environment with the following characteristics:
Security Features
- Isolated execution - Scripts can’t access other scripts’ state
- No file system access - Can’t read or write local files
- Limited network access - Only via fetch API
- No Node.js built-ins - Can’t access
fs,path,process, etc.
Performance Limits
- Memory limits - Prevents memory leaks from affecting system
- Execution timeout - Automatic termination of long-running scripts
- CPU throttling - Prevents resource exhaustion
Available Globals
$context- Test context (read/write)$request- Request object (in hooks)$response- Response object (in after-response hooks)_- Lodash libraryfetch- HTTP clientconsole- Logging functionssetTimeout,setInterval- Timer functionsJSON- JSON utilitiesstructuredClone- Deep cloning
Best Practices
Choosing the Right Script Type
Use Request/Response Hooks when:
- You need to modify API calls dynamically
- You need to extract data from responses
- You want to perform custom validations
Use Value Generators when:
- You need reusable data generation functions
- You want to call functions from JS expressions
- You need to create mock data patterns
Use Custom Assertions when:
- You have complex validation logic
- QA teams need to use your validation in the UI
- You want to encapsulate business rules
Use Script Node when:
- You need general-purpose JavaScript execution
- You’re doing complex multi-step transformations
- None of the specific script types fit
Use Global Functions when:
- You have utilities needed across multiple script types
- You want centralized, maintainable helper functions
- You need to share logic between hooks, generators, and assertions
Code Quality
- Keep it simple - Visual nodes should handle most logic
- Single responsibility - Each script does one thing well
- Meaningful names - Use descriptive function and variable names
- Error handling - Always wrap in try/catch for robustness
- Comments - Explain business logic, not obvious code
Performance
- Avoid loops - Use array methods like
map,filter,reduce - Cache values - Don’t recalculate the same thing repeatedly
- Clean up - Delete temporary context variables you don’t need
- Monitor execution - Track script performance in production
Integration with Visual Nodes
- Set clear context - Use descriptive variable names for subsequent nodes
- Simplify conditions - Create boolean flags for IF nodes to use
- Prepare iteration data - Format arrays properly for ITERATION nodes
- Document outputs - Make it clear what context variables you’re setting
Next Steps
Dive deeper into specific script types:
- Global Scripts - Reusable utilities, hooks, and functions
- Script Node Guide - General-purpose JavaScript execution
- Value Generators - Reusable data generators
- Before Request Hooks - Pre-request hooks
- After Response Hooks - Post-response hooks
- Custom Assertions - Reusable validation logic
Learn about context and expressions:
- Context & Variables - The data bus for your test flows
- Template Engine & Expressions - JSONata vs JS expressions