Template tokens & filters
Reference run context, pipeline context, data fixtures, and credentials in your prompts. Format dates and times with optional timezone.
Template tokens & filters
Test-Lab resolves four kinds of {{...}} placeholders in your prompts, cookies, headers, and data-fixture values.
| Namespace | What it is | Resolved at |
|---|---|---|
{{run.X}} | Per-step run identifiers and timestamps | Executor (re-resolves on every replay) |
{{pipeline.X}} | Per-dispatch identifiers and timestamps, shared across every step in a pipeline | Dispatch (frozen for the run) |
{{data.<name>.<field>}} | A field from a project-scoped data set | Dispatch (rolls dynamic fields per run) |
{{credentials.<key>}} | An account-scoped secret | Just before Playwright launches (never visible to the AI) |
Run context
| Token | Value |
|---|---|
{{run.id}} | Full UUID of the current step's run |
{{run.shortId}} | First 8 characters of the run UUID |
{{run.timestamp}} | Unix seconds at run time (10 digits) |
{{run.timestampMs}} | Unix milliseconds at run time (13 digits) |
Use run.shortId to tag resources the test creates so a per-run cleanup webhook can scope its DELETE:
Create a property named "QA-{{run.shortId}}".Both timestamp variants come from the same source; pick the precision your use case needs.
Pipeline context
For multi-step pipelines, each step runs as its own job. {{run.timestampMs}} resolves to slightly different values in step 1 vs. step 2 (off by milliseconds), and {{run.id}} is the step's own job id, not a shared identifier.
{{pipeline.X}} is allocated once per dispatch and shared across every step. Step 1 and step 2 see identical values, which is what makes flows like "step 1 creates a contact, step 2 finds the same contact" work.
| Token | Value |
|---|---|
{{pipeline.id}} | Full UUID generated at dispatch |
{{pipeline.shortId}} | First 8 characters of the pipeline UUID |
{{pipeline.timestamp}} | Unix seconds at dispatch |
{{pipeline.timestampMs}} | Unix milliseconds at dispatch |
Single-step plans also get a fresh pipeline context per dispatch, so the same prompt vocabulary works in both cases.
Data fixtures
See Test data for the full reference. Quick summary:
Sign up as {{data.contact.first_name}} {{data.contact.last_name}}
with email {{data.contact.email}}.Each field is either Static (same value every run, until you change it) or Dynamic (auto-generates a fresh value on every dispatch).
A static field's stored value can itself embed {{run.X}} or {{pipeline.X}} for per-run uniqueness. The substitution chain resolves the embedded tokens after the fixture lookup.
Credentials
See Credentials.
Filters
Apply a filter chain to format any resolved value, Liquid-style:
{{ run.timestamp | format: 'DD.MM.YYYY' }}
{{ pipeline.timestampMs | format: 'YYYY-MM-DD HH:mm' }}
{{ run.timestamp | format: 'YYYY-MM-DD HH:mm', 'Europe/Bucharest' }}Whitespace inside the braces is tolerated. Filters apply after the namespace lookup resolves the bare value, so they work on any of the four namespaces above.
format
The first argument is the pattern. The second (optional) argument is an IANA timezone name (Europe/Bucharest, America/Los_Angeles, Asia/Tokyo, etc.). When omitted, the value formats in UTC.
Format tokens
| Token | Output | Example |
|---|---|---|
YYYY | 4-digit year | 2026 |
YY | 2-digit year | 26 |
MM | 2-digit month | 01–12 |
M | 1–2 digit month | 1–12 |
DD | 2-digit day | 01–31 |
D | 1–2 digit day | 1–31 |
HH | 2-digit hour, 24h | 00–23 |
H | 1–2 digit hour, 24h | 0–23 |
hh | 2-digit hour, 12h | 01–12 |
h | 1–2 digit hour, 12h | 1–12 |
mm | 2-digit minute | 00–59 |
m | 1–2 digit minute | 0–59 |
ss | 2-digit second | 00–59 |
s | 1–2 digit second | 0–59 |
SSS | 3-digit millisecond | 000–999 |
A | AM/PM | AM, PM |
a | am/pm | am, pm |
Anything else in the pattern emits verbatim. Separators like ., -, :, /, and spaces don't need escaping.
Examples
| Pattern | Timezone | Output (input: 2026-05-09T13:30:45.123Z) |
|---|---|---|
'YYYY-MM-DD' | (UTC default) | 2026-05-09 |
'DD.MM.YYYY' | (UTC default) | 09.05.2026 |
'YYYY-MM-DD HH:mm:ss' | (UTC default) | 2026-05-09 13:30:45 |
'YYYY-MM-DD HH:mm' | Europe/Bucharest | 2026-05-09 16:30 |
'YYYY-MM-DD HH:mm' | Asia/Tokyo | 2026-05-09 22:30 |
'YYYY-MM-DD HH:mm' | Pacific/Auckland | 2026-05-10 01:30 |
'h:mm A' | (UTC default) | 1:30 PM |
'YYYY-MM-DD HH:mm:ss.SSS' | (UTC default) | 2026-05-09 13:30:45.123 |
Input formats
The format filter accepts:
- Unix seconds (10-digit string):
{{run.timestamp}}emits this shape. - Unix milliseconds (13-digit string):
{{run.timestampMs}}and{{pipeline.timestampMs}}emit this shape. - ISO 8601 strings, useful when a data-fixture value stores a date.
Anything else passes through unchanged.
Unknown filters
A typo in a filter name (e.g. | upper when only format is supported) is a no-op: the value passes through unchanged. The substitution stays lossy-but-survivable so a typo doesn't blow up the middle of an AI prompt.
Test data
Project-scoped reusable values you can drop into any test prompt. Mix static and auto-generated fields, embed run-context tokens for per-run uniqueness, and read the resolved snapshot in every run report.
Pipelines
Chain test plans into multi-step pipelines that share browser state - login once, test everything