Advanced Features
These language features are part of everyday Norn usage once your tests move beyond single-request flows.
Conditionals
Use if blocks to run steps only when a condition passes. Conditions support the same operators as assertions.
GET {{baseUrl}}/todos/1
if $1.status == 200
var userId = $1.body.userId
print "Todo Found" | "Fetching related user"
GET {{baseUrl}}/users/{{userId}}
assert $2.status == 200
end if Wait Commands
Pause execution between steps with seconds or milliseconds.
wait 1s
wait 500ms URL-Encoded Form Data
For application/x-www-form-urlencoded requests, separate headers from the body with a blank line. Norn accepts one field per line using either key=value or key: value, and it also accepts a single ampersand-delimited line such as name=John+Doe&email=john%40example.com.
POST https://httpbin.org/post
Content-Type: application/x-www-form-urlencoded
username=testuser
password=secret123
grant_type=password If a form body line is not valid, Norn reports it as a syntax error before the request is sent. This also works with header groups and captured requests such as var result = POST PostFormData FormData.
Retry and Backoff
Retry works on direct requests, named endpoints, and named requests. The HTTP client retries network failures, 5xx responses, and 429 responses.
var direct = GET "https://api.example.com/health" retry 2 backoff 200 ms
var endpoint = GET GetTodo(1) retry 2 backoff 100 ms
var named = run GetStatus retry 3 backoff 150 ms Script Execution
Run shell, JavaScript, or PowerShell scripts from a sequence. Captured output becomes a variable. PowerShell accepts both powershell and pwsh.
run bash ./scripts/seed-db.sh
var signature = run js ./scripts/sign.js {{payload}}
var data = run powershell ./scripts/query.ps1 When a script prints JSON, Norn parses it automatically so you can access properties and array elements directly.
assert data[0].id == 1
print "First Row" | "value={{data[0].value}}" JSON File Loading
Load structured test data from disk with run readJson, then read or update properties in memory. Structured values stay as objects, so debugger views and type checks see real object types instead of JSON strings.
var config = run readJson ./test-data.json
print "Config" | "timeout={{config.settings.timeout}}"
config.settings.timeout = 10000
config.users[0].name = "Updated Alice" Print Statements
Use print for lightweight debugging and execution breadcrumbs. print "Title" | "Body" creates a structured message.
print "Starting Test"
print "Auth" | "token={{token}}" Imports
Import .norn files to reuse named requests and sequences. File-level variables inside the imported file are resolved into those imported definitions.
import "./shared-utils.norn"
import "./api.nornapi"
test sequence SmokeFlow
run AuthRequest
var token = run SharedSetup
GET GetTodo(1) Json
assert $2.status == 200
end sequence Rules to Remember
end ifcloses anifblock.endifalso works, but the docs useend ifconsistently.- Retry options are written inline as
retry Nand optionalbackoff N msorbackoff N s. run readJsonloads data relative to the current file.- Imported
.nornfiles expose named requests and sequences;.nornapiimports expose header groups and endpoints.