Using Scripts
Resonance runs JavaScript before a request is sent (pre-request scripts) and after the response arrives (test scripts). Scripts run in a sandboxed engine embedded in the app — no data leaves your machine unless a script calls sendRequest.
Overview
- Write scripts in the Scripts tab of the request panel, in the Pre-request or Test sub-tab — they save automatically
- Console output, test results and errors appear in the Scripts tab of the response panel
- The collection runner runs the same scripts for every request in a run
- Scripts run synchronously, top to bottom — no
setTimeout,fetchor Promises that need scheduling - A script is stopped after 30 seconds (for example an endless loop) and reports an error
What Happens After a Script
- Pre-request: changes to
requestare applied to the outgoing request - Pre-request failure: if the script throws, the request is not sent and the error is shown in its place; in the runner the request is marked failed
- Both:
environment.set/unsetchanges are saved to the active environment, andpm.collectionVariables.set/unsetchanges to the request's collection
request
The outgoing request, mutable in pre-request scripts. Variables such as {{name}} are already resolved when the script runs.
request.urlFully resolved URL.request.methodHTTP method.request.headersHeader name → value map. Also has add({key, value}), upsert(...), remove(name), get(name), has(name).request.bodyRequest body (a parsed object for JSON bodies).request.queryParamsQuery parameter map — set a key to null to remove it.request.pathParamsPath parameter map.request.headers["Authorization"] = `Bearer ${environment.get("token")}`;
request.queryParams["page"] = "2";
delete request.queryParams["debug"];
response (test scripts)
response.statusHTTP status code (number).response.statusTextStatus reason phrase.response.headersResponse header map. Repeated headers are joined with ", ".response.bodyParsed object when the response was JSON, otherwise a string.response.timingsTiming breakdown in ms, e.g. timings.total.response.cookiesEvery Set-Cookie entry of this response.expect(response.status).toBe(200);
expect(response.body.user.email).toMatch(/@example\.com$/);
environment.set("userId", String(response.body.user.id));
environment
Read and write variables of the active environment. Values are strings; a value set earlier in the same script is returned by get.
const host = environment.get("host");
environment.set("requestId", "abc-123");
environment.unset("tempToken");
cookies
Read and write the cookie jar of the active environment (also pm.cookies). See Cookie Jar.
cookies.get(name[, domain])Value of the first matching cookie, or null.cookies.has(name[, domain])Whether a matching cookie exists.cookies.getAll() / toObject()Every cookie, or a { name: value } map.cookies.set(name, value[, opts])Store a cookie; opts accepts domain, path, expires, secure, httpOnly, sameSite.cookies.unset(name[, domain, path])Remove matching cookies.cookies.clear()Remove every cookie of the active environment.Testing
describe("user endpoint", () => {
test("returns 200", () => {
expect(response.status).toBe(200);
});
it("returns a user id", () => {
expect(response.body.user).toHaveProperty("id");
});
});
A failing expectation inside test / it fails that test and moves on. expect at the top level records each assertion as its own result and stops the script on failure.
toBe(e) / toEqual(e)Strict or deep equality.toBeTruthy() / toBeFalsy()Truthiness.toBeNull() / toBeDefined() / toBeUndefined()Null and defined checks.toContain(item)String or array containment.toBeGreaterThan(n) / toBeLessThan(n)Numeric comparison (also …OrEqual).toHaveLength(n)actual.length === n.toMatch(regex)Regular expression match.toHaveProperty(key[, value])Property existence and optional value..notNegates any matcher: expect(x).not.toBe(500).sendRequest(urlOrOptions[, callback])
Makes an HTTP request from a script. It is synchronous and returns the response directly; the Postman-style callback form also works.
const res = sendRequest({
url: environment.get("authUrl"),
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "grant_type=client_credentials&client_id=" + environment.get("clientId")
});
if (res.status === 200) {
environment.set("token", res.json().access_token);
}
- Options:
url(required),method,headers,body(objects are sent as JSON),timeoutin ms (default 10 000, max 60 000) - Response:
status,statusText,headers,body,json(),text() - Network errors and timeouts throw — wrap calls in
try/catch - Redirects are followed; the app's proxy settings apply, client certificates do not
Crypto & Encoding
btoa(text) / atob(base64)Latin1 ⇄ base64, as in browsers.crypto.randomUUID()Random v4 UUID.crypto.hash(alg, data[, enc])md5, sha1, sha256, sha384, sha512; encoding hex (default), base64 or base64url.crypto.hmac(alg, key, data[, enc])HMAC with the same algorithms and encodings.CryptoJSSubset of CryptoJS (also via require("crypto-js")): MD5, SHA1, SHA256, SHA384, SHA512, their Hmac… variants, and CryptoJS.enc.Hex / Base64 / Base64url / Utf8 / Latin1.const signature = CryptoJS.HmacSHA256(request.body, environment.get("secret"))
.toString(CryptoJS.enc.Base64);
request.headers["X-Signature"] = signature;
Postman Compatibility (pm)
Scripts written for Postman run largely unchanged — including scripts that come in with a Postman import.
pm.test(name, fn) / pm.expect(v)Chai-style assertions: to.equal, eql, be.a, include, have.property, lengthOf, keys, above / below, match, oneOf, be.ok / true / null / empty, with not and deep.pm.responsecode, status (numeric, as in response), reason(), responseTime, headers.get(name), json(), text().pm.response.to.have.*status(code), header(name[, value]), body([text]), jsonBody([path[, value]]); also pm.response.to.be.ok / success / clientError / serverError / notFound / json, each negatable with to.not.pm.environmentget, set, unset, has, toObject, replaceIn, clear.pm.collectionVariablesSame methods, saved to the request's collection.pm.variablesScript-local values first, then the runner data row, the environment and the collection; set lasts for this script run only.pm.globalsMapped to the active environment — Resonance has no global scope.pm.request / pm.sendRequest / pm.cookiesThe same objects as request, sendRequest and cookies.pm.info / pm.iterationDataPosition and data row of a runner iteration.Not supported yet: pm.execution.setNextRequest / skipRequest, pm.vault, and require for modules other than crypto-js.
Limitations
- No file system or system access;
sendRequestis the only network call - No
fetch,XMLHttpRequest,import,setTimeoutor browser storage - Scripts are stopped after 30 seconds; each
sendRequesthas its own timeout - Environment values are stored as strings — convert with
String(…)/Number(…)
Troubleshooting
The request was not sent
- A failing pre-request script stops the send — the error is shown in the response area and the Scripts tab
Variable missing in the next request
- Make sure an environment is active before using
environment.set - Log the value with
console.log(environment.get("name")) - Check the spelling between
environment.setand the{{name}}placeholder
Assertion fails unexpectedly
- Log
response.statusandresponse.bodybefore asserting response.bodyis already an object for JSON responses — noJSON.parseneeded
Next Steps
- Getting Started — request basics and environment setup
- Collection Runner — run sequences using script-captured variables
- Mock Server — test script flows against local mock endpoints