JavaScript Step
The JavaScript step lets you run arbitrary JavaScript code as part of a test case using the Google V8 engine. Use it for custom assertions, data transformation, response validation, or to run scripts imported from Postman and Insomnia collections.
When to Use
- Writing custom assertions on the response from a preceding Send Request step
- Transforming or extracting data from responses into variables
- Running existing Postman or Insomnia test scripts without modification
- Implementing complex conditional logic that can't be expressed with built-in assertion steps
- Generating dynamic test data
Quick Start
- Add a Send Request step before the JavaScript step to produce a response.
- Add a JavaScript step from the step palette.
- Write your script using the
aethrixobject:
aethrix.check("Response is valid", () => {
aethrix.assert.statusCode(200);
aethrix.assert.header("Content-Type", "application/json");
aethrix.assert.jsonPath("$.data.token");
});
aethrix.check("Response time is acceptable", () => {
aethrix.assert.bodyContains("success");
});
- Run the test case. The script executes and assertion results appear in the report.
Script Environment
The script runs in a Google V8 engine with the following objects available:
| Object | API | Purpose |
|---|---|---|
aethrix | Native Aethrix | Assertions, variables, diagnostics, progress |
pm | Postman-compatible | Run Postman test scripts verbatim (for imported collections) |
insomnia | Insomnia-compatible | Run Insomnia test scripts verbatim (for imported collections) |
console | Standard | console.log(), console.warn(), console.error() |
testStep | Aethrix | The current JavaScript test step — use testStep.findSendStepByName(...) to locate a Send Request step |
project | Aethrix | The current automation project |
host | ClearScript | .NET interop helper functions |
testParameters | Aethrix | Current test case parameters |
All three sandbox objects (aethrix, pm, insomnia) are always available. A script can use any combination of them.
Pass / Fail Logic
The step result is determined after script execution. Following the Postman/Jest/Mocha convention — "no error = pass" — a script that completes without exceptions and without failed assertions passes by default:
- If any
pm.test()call failed → Failure - If any
aethrix.check()block failed → Failure - If the script returns the JavaScript value
true→ Success - If the script returns the string
"OK"→ Success - If all
pm.test()calls passed (and at least one ran) → Success - If all
aethrix.check()blocks passed (and at least one ran) → Success - If the script returns
false(and no assertions ran) → Failure - Otherwise (no assertions, no explicit return) → Success
A failure in either framework (Postman or Aethrix) fails the step, even if the other framework's assertions all passed. Thrown exceptions also fail the step and are reported with their line/column location.
Aethrix Assertion API
The aethrix.assert object provides assertion methods that map to Aethrix's native assertion types. All methods throw an exception on failure, which is caught by aethrix.check().
Response Assertions
These work on the response from the preceding Send Request step:
| Method | Description |
|---|---|
aethrix.assert.statusCode(code) | Check HTTP status code. Supports exact (200, 404) and range patterns ("2xx", "4xx") |
aethrix.assert.header(name) | Check a response header exists |
aethrix.assert.header(name, value) | Check a response header equals a value |
aethrix.assert.header(name, value, compareMode) | Check with comparison mode |
aethrix.assert.jsonPath(path) | Check a JSON path exists in the response body |
aethrix.assert.jsonPath(path, expected) | Check a JSON path equals a value |
aethrix.assert.jsonPath(path, expected, compareMode) | Check with comparison mode |
aethrix.assert.bodyContains(text) | Check the response body contains text |
aethrix.assert.bodyContains(text, compareMode) | Check with comparison mode |
General Value Assertions
| Method | Description |
|---|---|
aethrix.assert.equal(actual, expected) | Check two values are equal |
aethrix.assert.equal(actual, expected, compareMode) | Check with comparison mode |
aethrix.assert.contains(text, substring) | Check text contains a substring |
aethrix.assert.contains(text, substring, compareMode) | Check with comparison mode |
Negation
Prefix any assertion with .not to invert it:
aethrix.assert.not.statusCode(500);
aethrix.assert.not.header("X-Error");
aethrix.assert.not.jsonPath("$.error");
aethrix.assert.not.bodyContains("error");
aethrix.assert.not.equal(actual, "bad value");
Grouping Assertions
Wrap assertions in aethrix.check() to give them a name and track pass/fail:
aethrix.check("Status and headers", () => {
aethrix.assert.statusCode(200);
aethrix.assert.header("Content-Type", "application/json");
});
aethrix.check("Response payload", () => {
aethrix.assert.jsonPath("$.data.token");
aethrix.assert.not.jsonPath("$.error");
});
Each check() block appears as a named diagnostic entry (✓ name for pass, ✗ name: reason for fail).
Compare Modes
An optional last parameter on equal, contains, header, jsonPath, and bodyContains:
| Mode string | Behavior |
|---|---|
"binary" (default) | Case-sensitive, exact comparison |
"caseInsensitive" | Case-insensitive, accent-insensitive |
"loose" | Case-insensitive, ignores spaces, letters/digits/symbols only |
"regex" | Regular expression match, case-sensitive |
"regexIgnoreCase" | Regular expression match, case-insensitive |
aethrix.assert.equal("Hello", "hello", "caseInsensitive");
aethrix.assert.equal("abc123", "^abc\\d+$", "regex");
aethrix.assert.contains("Hello World", "world", "caseInsensitive");
Variables and Environment
Read and write Aethrix variables from JavaScript:
// Read a variable
var userId = aethrix.variables.get("userId");
// Write a variable (persisted to the step's local variables)
aethrix.variables.set("generatedId", "usr_" + Date.now());
// Check if a variable exists
if (aethrix.variables.has("token")) {
aethrix.info("Token is available");
}
Access the project's current test environment:
var baseUrl = aethrix.environment.get("BaseUrl");
aethrix.environment.set("lastStatus", "ok");
Accessing the Response
The response from the preceding Send Request step is available via aethrix.response:
var code = aethrix.response.code; // HTTP status code (number)
var body = aethrix.response.text(); // raw response body (string)
var json = aethrix.response.json(); // parsed JSON body (object)
var ok = aethrix.response.ok; // true if 2xx
var status = aethrix.response.status; // reason phrase (string)
var headers = aethrix.response.headers(); // dictionary
var url = aethrix.request.url; // request URL
Diagnostics and Progress
aethrix.info("Processing step 1...");
aethrix.warn("Unexpected value: " + someVar);
aethrix.progress = 0.5; // 0.0 to 1.0, clamped automatically
The Script Editor
The JavaScript step ships with a dedicated code editor (JavaScriptPanel.axaml) with IDE-like features:
Syntax Highlighting
JavaScript code is highlighted in real time using a semantic tokenizer (Esprima-based) — keywords, strings, numbers, comments, and template literals are colored as you type.
Code Completion
- Typing an identifier prefix opens a completion list (keywords, built-in JS globals, and the sandbox objects:
aethrix,pm,insomnia,console,project,testParameters,host). - Typing
.after a sandbox object lists its members, e.g.aethrix.assert.→statusCode,header,jsonPath, … - Typing
(after a function name shows a parameter insight popup with the full signature. - Completion also includes variables visible in the current scope and the API model generated from the actual runtime host objects.
Error Marking and Navigation
- Syntax and runtime errors are marked in the editor with squiggly underlines (red) at the exact line/column.
- Hovering a marked error shows a tooltip with the error message (auto-hides after ~2 seconds).
- Errors also appear in the bottom Errors tab of the step panel. Selecting a row in the list jumps the editor to that line and moves the caret there.
- The Build toolbar button pre-validates the script and populates the Errors tab without running it.
Debugging
Press Debug to start an interactive debugging session (CDP-based, same engine used at runtime):
- Toggle Breakpoint from the editor's right-click menu (or click in the left gutter) to set/remove breakpoints.
- Session toolbar: Continue, Step Into, Step Over, Step Out, and Stop.
- A Locals panel on the right shows the current scope's variables; the executing line is highlighted in the editor.
- Console output from
console.log()/aethrix.info()appears during the session.
Editing Commands
- Format Document / Format Selection — re-indent the whole script or the selected code.
- Comment Selection / Uncomment Selection — toggle
//comments. - Standard editing keys (
Ctrl+Zundo,Ctrl+Yredo,Tabauto-indent) and auto-closing brackets/strings are enabled.
Compile (Pre-validation)
The Build button in the UI pre-validates script syntax without executing it. Compilation errors appear in the bottom Errors tab and as squiggly underlines with line and column numbers.
Companion Files
When a project uses companion files (external .js files alongside the .aprj), the script is stored as a {id}_script.js file in the companion directory.
Common Patterns
Validate a REST API Response
aethrix.check("Status is 201 Created", () => {
aethrix.assert.statusCode(201);
});
aethrix.check("Response contains ID", () => {
aethrix.assert.jsonPath("$.id");
var id = aethrix.response.json().id;
aethrix.variables.set("createdId", id.toString());
});
Check Status Code Range
aethrix.check("Client or server error", () => {
aethrix.assert.not.statusCode("2xx");
aethrix.assert.not.statusCode("3xx");
});
Extract and Transform Data
var json = aethrix.response.json();
var price = parseFloat(json.price);
var discounted = price * 0.9;
aethrix.variables.set("discountedPrice", discounted.toFixed(2));
aethrix.info("Discounted price: " + discounted.toFixed(2));
Postman & Insomnia Compatibility
Scripts imported from Postman or Insomnia collections can run verbatim thanks to the pm and insomnia compatibility sandboxes. See Importing Collections → and JavaScript API Reference → for the full API surface.
Limitations
- Scripts must complete within the engine's execution timeout
- File system access is not available from JavaScript
- External npm packages cannot be imported; use the C# Script step for .NET library access
- The
pmandinsomniasandboxes provide a subset of the full Postman/Insomnia API (see API reference for supported methods)