Scripts
Customise requests, automate repetitive tasks and create custom workflows using Testfully's scripting feature.
Testfully supports Javascript (ES2020) for scripting. You can write scripts for your requests, folders, and the entire collection. You have the option to run your scripts before or after a request is sent. Also, Testfully offers a range of built-in functions that you can use in your scripts to interact with the request, response, and other parts of the application.
Attention! Postman Users
A widge range of Postman's scripting API is supported in Testfully. In theory, you should not have to change your scripts when moving from Postman to Testfully. If you encounter any issues, please report them to us via support@testfully.io. We are here to help you with your transition.
Features
The table below shows the list of features that are available/coming in Testfully's scripting environment and their status.
| Feature | Status |
|---|---|
| Supports ES2020, write code in modern Javascript | Available |
All native APIs including JSON.parse() etc are available | Available |
| Access & Modify Request | Available |
| Access Response Data | Available |
| Work with global variables | Available |
| Work with environment variables | Available |
| Work with collection and folder variables | Available |
| Send HTTP requests | Available |
API Testing using using test and expect APIs | Available |
Import & use npm packages | Available |
| Chain requests via code | Available |
Supported APIs
Testfully offers a range of built-in APIs to use for scripting. You can use these APIs to interact with the request, response, and other parts of the application.
You should know!
All of the APIs are available via the $ global variable. To use Testfully API, simply type $.
Send a request
Use the $.sendRequest() API to send a request. This API accepts a request object, or a URL, as its first parameter and returns the response.
Basic Get Request
The example below sends a request to the https://httpbin.org/anything endpoint and stores the response in the response variable. The response variable is then used to log the response body.
const response = $.sendRequest("https://httpbin.org/anything");console.log(response);Request Object
The example below sends a request to the https://httpbin.org/anything endpoint and stores the response in the response variable. The response variable is then used to log the response body.
const request = { method: "POST", url: "https://httpbin.org/anything", headers: { "Content-Type": "application/json", }, body: { mode: "raw", raw: { name: "Testfully", }, },};
const response = $.sendRequest(request);console.log(response);Setting up a request timeout
Testfully waits for the response to be received for 30 seconds by default. You can change this timeout value by setting the timeout property of the request object. The example below sets the timeout value to 1 second.
const request = { method: "POST", url: "https://httpbin.org/anything", timeout: 1,};Working with requests
Use the $.request API to work with the current request. Testfully offers the following APIs to work with the request.
| API | Description |
|---|---|
$.request.method | Get the HTTP method of the request. |
$.request.url | Get the URL of the request. |
$.request.type | Get the type of the request. |
$.request.headers | Get the headers of the request. |
$.request.headers.add({ key, value }) | Add a new header |
$.request.headers.upsert({ key, value }) | Upsert a header |
$.request.headers.remove(key) | Remove a header |
$.request.params | Get the params of the request. |
$.request.body | Get the body of the request. |
$.request.body.json | Get the JSON payload for the request. |
$.request.body.query | GraphQL query for the request. |
$.request.body.variables | GraphQL variables for the variables. |
$.request.body.form | Form fields for both formdata and urlencoded requests. |
$.request.skip() | Skip the execution of current request. |
$.setNextRequest() | Set the next request to be executed. |
Working with response
Use the $.response API to work with the response of the current request. Testfully offers the following APIs to work with the response.
| API | Description |
|---|---|
$.response.code | Get the HTTP status code of the response. |
$.response.status | Get the HTTP status of the response. |
$.response.headers | Get the headers of the response. |
$.response.body | Get the response body in plain text (string). |
$.response.cookies | Get the cookies of the response. |
$.response.text() | Returns the response body in plain text (string). |
$.response.json() | Returns the response body as a Javascript object. Throws an error when the response body is not a valid JSON. |
$.response.responseTime | Get the response time of the response. |
$.response.responseSize | Get the response size of the response. |
Working with Response Cookies
Testfully offers a few APIs to access and work with the cookies in the response of a request. The table below shows the list of APIs that are available in Testfully to work with the cookies.
| API | Description |
|---|---|
$.response.cookies | Get a list of cookies in the response in the form of an array of objects, each object representing a cookie, with the following properties: name, value |
$.cookies.get(name) | Get the value of a cookie by providing name of the cookie. This function returns undefined when the cookie is not available. |
$.cookies.has(name) | Check if a cookie with the given name exists. This function returns true if the cookie exists, otherwise false. |
$.cookies.toObject() | Get all cookies as an object. This function returns an object with the cookie name as the key and the cookie value as the value. |
Examples
Say you API endpoint returns a cookie named x-csrf-token and you want to access the value of this cookie. You can use the following code to access the value of the cookie.
const csrfToken = $.cookies.get("x-csrf-token");console.log(csrfToken);Please note that name of the cookie is case-sensitive, and must match the name of the cookie your API endpoint returns.
If you want to check if a cookie with the name x-csrf-token exists, you can use the following code.
const hasCsrfToken = $.cookies.has("x-csrf-token");console.log(hasCsrfToken);If you want to get all cookies as an object, you can use the following code.
const cookies = $.cookies.toObject();const csrfToken = cookies["x-csrf-token"];console.log(cookies, csrfToken);If you want to get all cookies as an array of objects, you can use the following code.
const cookies = $.response.cookies;const csrfToken = cookies.find((cookie) => cookie.name === "x-csrf-token");console.log(cookies, csrfToken);Try it out with HTTPBin API
If you want to try out the cookie APIs but don't have your API endpoint handy, you can use HTTP Bin API to set and get cookies. Please check the HTTP Bin documentation for more information.
Migrating from Postman and working with cookies?
For users who are migrating from Postman to Testfully, we have added the following APIs to make it easier to work with cookies in Testfully without changing your existing scripts.
| API | Description |
|---|---|
pm.cookies.get(name) | Get the value of a cookie by name. This function returns undefined when the cookie is not available. |
pm.cookies.has(name) | Check if a cookie with the given name exists. This function returns true if the cookie exists, otherwise false. |
pm.cookies.toObject() | Get all cookies as an object. This function returns an object with the cookie name as the key and the cookie value as the value. |
Logging
Use the global console object to log messages to the console. The logs are available in the "Logs" tab of the request. Testfully supports the following logging APIs:
| API | Description |
|---|---|
console.log(message) | Logs a message to the console. |
console.info(message) | Logs an informational message to the console. |
console.warn(message) | Logs a warning message to the console. |
console.error(message) | Logs an error message to the console. |
Example
console.log("Hello World!");console.warn("request failed error was ->", $.response.code);Working with globals
Use the $.globals API to work with global variables in your workspace. For compatibility reasons, Testfully supports the pm.globals object. However, we recommend using the $.globals object instead.
| API | Description |
|---|---|
$.globals.get(name) | Get the value of a global variable. |
$.globals.has(name) | Check if a global variable exists. |
$.globals.set(name, value) | Sets value of a global variable |
$.globals.unset(name) | Unsets value of a global variable |
$.globals.clear() | Removes all of the global variables in one go |
$.globals.toObject() | Returns all of the global variables as an object |
Working with environment variables
Use the $.environment API to work with the active environment (currently selected). For compatibility reasons, Testfully supports the pm.environment object. However, we recommend using the $.environment object instead.
| API | Description |
|---|---|
$.environment.get(name) | Get the value of an environment variable. |
$.environment.has(name) | Check if an environment variable exists. |
$.environment.set(name, value) | Sets value of an environment variable |
$.environment.unset(name) | Unsets value of an environment variable |
$.environment.clear() | Removes all of the environment variables in one go |
$.environment.toObject() | Returns all of the environment variables as an object |
Working with parent folder variables
Requests within a folder can access the variables defined in the parent folder, update them, delete them, or add new ones. Use the $.parentFolder.variables family of APIs to work with the parent folder variables.
| API | Description |
|---|---|
$.parentFolder.variables.get(name) | Returns the value of a variable defined in the parent folder. |
$.parentFolder.variables.has(name) | Returns true if the provided variable exists in the parent folder. |
$.parentFolder.variables.set(name, value) | Sets value of a variable defined in the parent folder. |
$.parentFolder.variables.unset(name) | Unsets value of a variable defined in the parent folder. |
$.parentFolder.variables.clear() | Removes all of the variables defined in the parent folder. |
$.parentFolder.variables.toObject() | Returns all of the variables defined in the parent folder as an object |
Working with user-scoped variables
Workspaces on Lite, Plus and Premium plans can use user-scoped variables. To work with user-scoped variables programmatically, pass true as the last parameter to all of the APIs mentioned above. The example below shows how to work with user-scoped variables.
// Returns the value of a variable called `access_token` defined in the parent folder,// as a user-scoped variable for the current user.$.parentFolder.variables.get("access_token", true);
// Returns true if the parent folder has a user-scoped variable called `access_token`,// for the current user.$.parentFolder.variables.has("access_token", true);
// Sets value of a variable called `access_token` defined in the parent folder,// as a user-scoped variable for the current user.$.parentFolder.variables.set("access_token", "value", true);
// Unsets value of a variable called `access_token` defined in the parent folder,// as a user-scoped variable for the current user.$.parentFolder.variables.unset("access_token", true);
// Removes all of the variables defined in the parent folder,// as a user-scoped variable for the current user.$.parentFolder.variables.clear(true);
// Returns all of the variables defined in the parent folder,// as a user-scoped variable for the current user.$.parentFolder.variables.toObject(true);Working with root folder variables
Requests within a folder can access the variables defined in the root folder (the folder that hosts all other folders), update them, delete them, or add new ones. Use the $.rootFolder.variables family of APIs to work with the parent folder variables.
| API | Description |
|---|---|
$.rootFolder.variables.get(name) | Returns the value of a variable defined in the root folder. |
$.rootFolder.variables.has(name) | Returns true if the provided variable exists in the root folder. |
$.rootFolder.variables.set(name, value) | Sets value of a variable defined in the root folder. |
$.rootFolder.variables.unset(name) | Unsets value of a variable defined in the root folder. |
$.rootFolder.variables.clear() | Removes all of the variables defined in the root folder. |
$.rootFolder.variables.toObject() | Returns all of the variables defined in the root folder as an object |
Testfully's support of pm.collectionVariables
For compatibility reasons, Testfully supports the pm.collectionVariables object. However, we recommend using the $.rootFolderVariables object instead.
| API | Description |
|---|---|
pm.collectionVariables.get(name) | Returns the value of a variable defined in the root folder. |
pm.collectionVariables.has(name) | Returns true if the provided variable exists in the root folder. |
pm.collectionVariables.set(name, value) | Sets value of a variable defined in the root folder. |
pm.collectionVariables.unset(name) | Unsets value of a variable defined in the root folder. |
pm.collectionVariables.clear() | Removes all of the variables defined in the root folder. |
pm.collectionVariables.toObject() | Returns all of the variables defined in the root folder as an object |
The example below shows how to use the pm.collectionVariables object.
// Returns the value of a variable called `access_token` defined in the root folder.pm.collectionVariables.get("access_token");
// Returns true if the root folder has a variable called `access_token`.pm.collectionVariables.has("access_token");
// Sets value of a variable called `access_token` defined in the root folder.pm.collectionVariables.set("access_token", "value");
// Unsets value of a variable called `access_token` defined in the root folder.pm.collectionVariables.unset("access_token");
// Removes all of the variables defined in the root folder.pm.collectionVariables.clear();
// Returns all of the variables defined in the root folder.pm.collectionVariables.toObject();Working with user-scoped variables
Root folders, like other folders, can have user-scoped variables. To work with user-scoped variables programmatically, pass true as the last parameter to all of the APIs mentioned above. The example below shows how to work with user-scoped variables.
// Returns the value of a variable called `access_token` defined in the root folder,// as a user-scoped variable for the current user.$.rootFolder.variables.get("access_token", true);
// Returns true if the root folder has a user-scoped variable called `access_token`,// for the current user.$.rootFolder.variables.has("access_token", true);
// Sets value of a variable called `access_token` defined in the root folder,// as a user-scoped variable for the current user.$.rootFolder.variables.set("access_token", "value", true);
// Unsets value of a variable called `access_token` defined in the root folder,// as a user-scoped variable for the current user.$.rootFolder.variables.unset("access_token", true);
// Removes all of the variables defined in the root folder,// as a user-scoped variable for the current user.$.rootFolder.variables.clear(true);
// Returns all of the variables defined in the root folder,// as a user-scoped variable for the current user.$.rootFolder.variables.toObject(true);Using npm packages
The ability to import npm packages is available via a Plus (or higher) subscription or a Testfully Offline license.
Publicly available NPM packages can be imported and used using the standard import syntax. The example below demonstrates how lodash module can be imported and used in Testfully.
import _ from "lodash";const result = _.merge({ name: "Teddy" }, { location: "AUS" });console.log(result);Creating delays in scripts
Use the $.sleep() API to create delays in your scripts. This API accepts a number as its parameter, which represents the number of milliseconds to wait.
$.sleep(1000); // Wait for 1 secondalternatively, you can use the setTimeout function to create delays in your scripts. We recommend using the $.sleep() API for better readability and compatibility.
timeouts and intervals
Testfully supports setTimeout, clearTimeout, setInterval, and clearInterval functions for timeouts and intervals. The example below demonstrates how to use these functions.
const timeout = setTimeout(() => { console.log("Hello World!");}, 1000);
clearTimeout(timeout);
const interval = setInterval(() => { console.log("Hello World!");}, 1000);
clearInterval(interval);The pm.info object
For compatibility reasons, Testfully supports the pm.info object.
| API | Description |
|---|---|
pm.info.eventName | pre for scripts that are executed before a request or test for scripts that are executed after sending a request |
pm.info.requestName | Get the name of the request. |
pm.info.requestId | Get the ID of the request. |
pm.info.iteration | Get the current iteration number. |
pm.info.iterationCount | Get the total number of iterations. |
Postman Legacy APIs
In addition to the currently supported Postman APIs, Testfully also supports Postman's legacy API. The table below shows the list of legacy APIs that are available in Testfully.
| API | Description | Status |
|---|---|---|
postman.setEnvironmentVariable(name, value) | Sets the value of an environment variable. | Available |
postman.getEnvironmentVariable(name) | Returns the value of an environment variable. | Available |
postman.clearEnvironmentVariables(name) | Removes an environment variable. | Available |
postman.setGlobalVariable(name, value) | Sets the value of a global variable. | Available |
postman.getGlobalVariable(name) | Returns the value of a global variable. | Available |
postman.clearGlobalVariables(name) | Removes a global variable. | Available |
postman.getResponseHeader(name) | Get value for a response header. | Available |
responseBody | Get the response body in plain text (string). | Available |
responseHeaders | Get the headers of the response in form of an object. | Available |
responseCode | Get the HTTP status code of the response. | Available |
responseTime | Get the response time of the response. | Available |
tests object | Writing tests using the tests object. | Available |
globals objectfeat/scripting_apis | Global variables and their values are available via the globals object. | Available |
Working with async code
If you have experience with Javascript and async code, you may have noticed that the Testfully examples above for any kind of async code, including sendRequest and $.globals.set(), are written synchronously. This is because Testfully automatically handles async code for you. You can write your code in a synchronous way and Testfully will take care of the rest.
API Testing
You can use the "After" script of a request to write automated tests. Once the response is received, Testfully will run your tests and show the results in the "Validations" tab of the request.
Attention! Postman Users
Similar to Postman, Testfully uses Chai Assertion Library for assertions. Testfully also supports the pm object for assertions so both pm.test() and pm.expect() works. However, we recommend using the $ object for assertions.
The $.test() API
Use the $.test() API to write tests. This API accepts a name and a function as its parameters. The function is where you write your tests. The example below shows how to use the $.test() API.
$.test("Status code is 200", function () { // Write your tests here});The $.expect() API
Use the $.expect() API to write assertions. This API accepts a value and returns an object with a set of assertion methods. The example below shows how to use the $.expect() API. Check out the Chai Assertion Library for a full list of assertion methods.
$.test("Status code is 200", function () { $.expect($.response.code).to.equal(200);});Postman's legacy tests object
For compatibility reasons, Testfully supports the tests object. The example below shows how to use the tests object. Please note that we recommend using the $ object for assertions instead of the tests object.
tests["Status code is 200"] = responseCode.code === 200;Working with multi-step requests
Use the $.steps() API to access request and response information from previous steps in multi-step requests. This API allows you to read data from any executed step, making it useful for debugging, logging, and cross-step data validation. The $.steps() API is available for both Before Request and After Response scripts.
| API | Description |
|---|---|
$.steps(stepIndex) | Returns request and response information for the step at the specified index (0-based indexing). |
Step Data Structure
The $.steps() API returns an object containing both request and response information for the specified step.
Request Fields
| Field | Type | Description |
|---|---|---|
step.request.method | string | HTTP method (GET, POST, PUT, DELETE, etc.) |
step.request.url | string | Complete request URL including query parameters |
step.request.dispatchedAt | string | ISO timestamp when the request was sent |
step.request.headers | Array<{name, value}> | Array of header objects. Each object contains name (string) and value (string) properties |
step.request.params | Array<{name, value}> | Array of query parameter objects. Each object contains name (string) and value (string) properties |
step.request.body | string | Array<{name, value}> | Request body content. String for raw data, array of objects for form data with name and value properties |
Response Fields
| Field | Type | Description |
|---|---|---|
step.response.receivedAt | string | ISO timestamp when the response was received |
step.response.code | number | HTTP response status code (200, 404, 500, etc.) |
step.response.body | string | Response body content as a string |
step.response.headers | Array<{name, value}> | Array of response header objects. Each object contains name (string) and value (string) properties |
step.response.cookies | Array<{name, value}> | Array of cookie objects. Each object contains name (string) and value (string) properties |
step.response.error | string | Error message if the request failed, empty string if successful |
Examples
Basic Step Data Access
Access basic information from a previous step:
// Get the first step's response codeconst firstStep = $.steps(0);console.log("First step status:", firstStep.response.code);
// Get the second step's request URLconst secondStep = $.steps(1);console.log("Second step URL:", secondStep.request.url);Extract Data from Previous Step Response
Use data from a previous step's response in the current step:
// Get user ID from the first step's responseconst loginStep = $.steps(0);const loginResponse = JSON.parse(loginStep.response.body);const userId = loginResponse.user.id;
// Use the user ID in current request$.request.headers.add({ key: "X-User-ID", value: userId.toString(),});Validate Cross-Step Data
Verify that data is consistent across multiple steps:
$.test("User ID consistent across steps", function () { const step1 = $.steps(0); const step2 = $.steps(1);
const user1 = JSON.parse(step1.response.body).user.id; const user2 = JSON.parse(step2.response.body).user.id;
$.expect(user1).to.equal(user2);});Debug Step Execution
Log request and response details for debugging:
// Debug all executed stepsfor (let i = 0; i < 3; i++) { try { const step = $.steps(i); console.log(`Step ${i}:`); console.log(` Method: ${step.request.method}`); console.log(` URL: ${step.request.url}`); console.log(` Status: ${step.response.code}`); console.log(` Response Time: ${new Date(step.response.receivedAt) - new Date(step.request.dispatchedAt)}ms`); } catch (error) { console.log(`Step ${i} not available`); break; }}Extract Authentication Token
Get an authentication token from a login step and use it in subsequent requests:
// Get JWT token from login stepconst loginStep = $.steps(0);const loginData = JSON.parse(loginStep.response.body);const authToken = loginData.token;
// Set authorization header for current request$.request.headers.upsert({ key: "Authorization", value: `Bearer ${authToken}`,});Important Notes
- Step indexing is zero-based (first step is index 0, second step is index 1, etc.)
- Only completed steps can be accessed via
$.steps() - If you try to access a step that doesn't exist or hasn't been executed, an error will be thrown
Miscellaneous
This section covers various miscellaneous concepts and APIs related to scripting in Testfully.
Globally scoped variables
In this context, a global variable is a variable that is accessible from any script within the same tree of folders. This should not be mistaken with the concept of "Global Variables" in Testfully, which are workspace-scoped variables defined via the Globals feature.
Although not recommended, in Testfully, you can define a Javascript variable globally and access it from any script within the same tree of folders. This is primarily to aid users migrating from Postman, where defining global variables is a common practice.
How to define a globally scoped variable?
To define a globally scoped variable, simply set it as a property of the globalThis object.
The example below defines a variable called SHOULD_LOG globally.
globalThis.SHOULD_LOG = true;Once defined, you can access this variable from any script within the same tree of folders.
if (SHOULD_LOG) { console.log("Logging is enabled");}Important Notes
If you define a global variable in "Before Request" script, it will be ONLY available during the "Before Request" script execution. It will NOT be available in "After Response" script. If you want to define a global variable that is available in both "Before Request" and "After Response" scripts, you must define it in both scripts.
Defining global variables follows Testfully's folder and collection structure. Only requests and sub-folders within a folder can access the global variables defined in that folder. Sibling folders or requests cannot access each other's global variables.
Using the postman-util-lib in Testfully
postman-util-lib is a crypto utility library for Postman. If you're migrating from Postman to Testfully and you depend on the postman-util-lib package, you can use the following technique to import and use it in Testfully.
Step 1: Download the postman-util-lib package
Using the below script, download the postman-util-lib package from the CDN. Ideally, you should do this in the "Before Request" script of the root folder, so that all requests and folders can access it.
const downloadUrl = "https://joolfe.github.io/postman-util-lib/dist/bundle.js";const script = $.sendRequest(downloadUrl);eval.bind(this)(script.text); // this makes the `pmlib` object available globally.Step 2: Use the postman-util-lib package
Once the package is downloaded, you can use it in any script within the same tree of folders. The example below shows how to use the postman-util-lib package to generate a SHA256 hash of a string.
const challenge = pmlib.pkceChallenge();console.log(challenge);Miscellaneous APIs
Testfully offers a range of miscellaneous APIs for scripting. The table below shows the list of miscellaneous APIs that are available in Testfully.
| API | Description |
|---|---|
$.uuid() | Generate a UUID V4. |
$.sleep(ms) | Create a delay in the script. |