JavaScript Scripting (spec: script-js)
Napper runs JavaScript scripts (.js, .mjs, .cjs) via Node.js, found as node on your PATH. Scripts run on the real Node runtime with full access to npm — no sandbox, no limits.
A script can be a step in a .naplist, or a pre/post hook on a .nap request. It passes when it exits 0 and fails on any non-zero exit; everything it prints to stdout is captured into the run output.
The injected ctx object (spec: script-context)
Napper injects a global named ctx into every JavaScript script and hook. There is no import and nothing to install — ctx is already in scope.
| Member | Available | Description |
|---|---|---|
ctx.env |
step + hook | Current environment name (--env), or "" |
ctx.vars |
step + hook | Object of all resolved variables (read) |
ctx.request |
hook | The request: method, url, headers, body |
ctx.response |
post hook | The response: status, headers, body, json, durationMs |
ctx.set(key, value) |
step + hook | Set a variable visible to every later step |
ctx.fail(message) |
step + hook | Fail the step — even if the process exits 0 |
ctx.log(message) |
step + hook | Write a line to the run output |
Pre/post request hooks (spec: script-pre, script-post)
Reference hooks from a .nap file's [script] block:
[script]
pre = ./scripts/setup-auth.js
post = ./scripts/validate-response.js
A pre hook runs before the request is sent — set up variables or log:
// setup-auth.js
const token = "demo-" + ctx.vars.userId;
ctx.set("token", token); // {{token}} is now available to this request and later steps
ctx.log("token ready for env " + ctx.env);
A post hook runs after the response — validate, extract, or chain. If it calls ctx.fail (or exits non-zero), the request step fails even when the HTTP assertions passed:
// validate-response.js
if (ctx.response.status !== 200) ctx.fail("expected 200, got " + ctx.response.status);
const body = ctx.response.json; // parsed JSON, or null if the body isn't JSON
if (body.id <= 0) ctx.fail("id must be positive");
ctx.set("postId", String(body.id)); // hand the id to the next step
ctx.log("created post " + body.id + " in " + ctx.response.durationMs + "ms");
Scripts as playlist steps (spec: naplist-script-step)
A .js step shares the playlist's variable scope through ctx, so it can seed data for the steps that follow:
// seed.js
ctx.set("postId", "7");
ctx.log("seeded postId=7");
[steps]
./seed.js
./get-post.nap # this request can use {{postId}}
Runnable end-to-end: examples/scripting-ctx/ctx-demo.naplist.
Mixing with other languages (spec: script-dispatch)
Dispatch is by extension, so a .naplist can interleave JavaScript with Python, F#, and C# steps — see examples/jsonplaceholder/mixed-scripts.naplist and the Scripting Overview.
Requirements (spec: script-runtime)
JavaScript scripts require Node.js available as node on your PATH. The Napper CLI binary itself is self-contained; plain .nap and .naplist files need no runtime at all.
Prefer Python? See Python Scripting — it has the same ctx surface. F# and C# scripts also run (as exit-code steps and hooks); see F# and C#.