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.

.norn
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.

.norn
wait 1s
wait 500ms

URL-Encoded Form Data

For application/x-www-form-urlencoded requests, separate headers from the body with a blank line and write each form field on its own line.

.norn
POST https://httpbin.org/post
Content-Type: application/x-www-form-urlencoded

username=testuser
password=secret123
grant_type=password

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.

.norn
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.

.norn
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.

.norn
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.

.norn
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.

.norn
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.

.norn
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 if closes an if block. endif also works, but the docs use end if consistently.
  • Retry options are written inline as retry N and optional backoff N ms or backoff N s.
  • run readJson loads data relative to the current file.
  • Imported .norn files expose named requests and sequences; .nornapi imports expose header groups and endpoints.