Scripting
Load Test specs have two lifecycle script slots — Before All and After All — that run once per test run (not once per VU iteration). They use the exact same scripting engine,tg.* API and snippet library as the Flow Runner.
When They Run
- •Before All — runs once when you press Start, before any VUs are spawned. Use it to log in, mint a token, warm a cache, or seed flow variables that every VU will read via
{{flow.key}} - •After All — runs once after every VU has finished and the results have been aggregated. Use it to notify a channel, POST a report to an HTTP endpoint, or trigger a downstream job
Single execution, not per-VU: these scripts run exactly once regardless of how many VUs the test is configured for. For hot-path logic that should run on every iteration, use a step's preScript or postScript instead — see the Steps section above.
The Script Editor
Clicking Before All or After All in the Steps rail opens a dedicated editor panel with three zones:
- •Header bar with a
▷ Trybutton that runs the script once in isolation against the current environment, so you can verify it works before kicking off a real test - •CodeMirror editor with JavaScript syntax highlighting and autocompletion for the
tg.*API - •Snippets panel on the right that can be collapsed into a thin chevron strip when you need more editor space
- •Script console below the editor showing
console.logoutput and any errors from the most recent Try run
The tg.* API
The same runtime that powers Flow Runner lifecycle scripts is available here. What's accessible depends on whether you're in Before All or After All — the export helpers only make sense after results exist.
| Namespace | Methods | Before All | After All |
|---|---|---|---|
| tg.flow | get(key) / set(key, value) | ✓ | ✓ |
| tg.environment | get(key) / set(key, value) | ✓ | ✓ |
| tg.export.json | () → string | — | ✓ |
| tg.export.html | () → string | — | ✓ |
| tg.export.pdf | () → Promise<Uint8Array> | — | ✓ |
| fetch / console | standard web globals | ✓ | ✓ |
Autocompletion in the editor reflects this — After All gets the full tg.export.* surface, Before All does not.
Before All Snippets
The built-in Before All snippet library matches the Flow Runner list. Click any snippet to insert its code at the end of your script:
| Snippet | What it does |
|---|---|
| GET request | Fire a basic GET with fetch |
| POST request | Send a JSON POST body |
| Register user | Create a new user with a random username template |
| Login & set token | Login and store the token as tg.flow.set("token", …) |
| Set flow variable | Persist a value every VU can read via {{flow.key}} |
| Get environment | Read an env variable with tg.environment.get |
| Set environment | Write an env variable with tg.environment.set |
| Console log | Log to the script console below the editor |
After All Snippets
After All ships a different snippet list tailored to reporting rather than setup:
| Snippet | What it does |
|---|---|
| GET request | Basic GET (same as Before All) |
| POST request | Basic JSON POST |
| Slack notification | POST to a Slack incoming webhook to announce the run finished |
| POST JSON report | Serialize the run with tg.export.json() and POST it |
| POST HTML report | Render the HTML report via tg.export.html() and POST it (useful for email APIs) |
| POST PDF report | Generate the PDF via await tg.export.pdf() and POST the binary |
| Get flow variable | Read a value that Before All or a step stored |
| Console log | Log to the script console |
Fire-and-forget is fine here: After All runs after the test is over and results are captured, so a slow report upload won't affect the run's metrics. The Try button also works here — it runs against the last completed run so you can iterate on your report code without re-running the load test.
Same Engine as Flow Runner
Under the hood, Before All / After All use the exact same executeLifecycleScript service that Flow Runner uses. That means everything you learned in the Flow → Scripting section of this guide applies here: the runtime, the autocomplete, the console output, the environment resolution pipeline. The only thing that's different is the snippet list, which is tuned for load-test scenarios.