Overview
Expressions let you inject dynamic values into step fields without writing full code. They are evaluated at runtime and can reference:env.*: environment variables from your selected Environmentvars.*: test variables produced by earlier steps (e.g., Extract Text)random.*: built‑in random data generators (email, name, uuid, etc.)- Utility functions: one‑line helpers for dates, encoding, hashing, and random operations
{{ ... }}. You can mix text with expressions, chain methods, and apply simple JavaScript.

When to use
- Build URLs from environment values and previous step outputs
- Fill forms with dynamic or random data
- Verify text or URLs that contain variable parts
- Drive conditional logic using values computed on the fly
Autocomplete and sources
In supported fields, typing{{ opens an autocomplete with tabs for Env, Vars, Random, and Utils. Select an item to insert it automatically.

- Env (
env.*): Read‑only key‑values defined in the selected Environment - Vars (
vars.*): Values saved by earlier steps in the same test case - Random (
random.*): Utilities likeemail(),firstName(),uuid(),number(min,max) - Utils: One‑line utility functions for dates, encoding, hashing, and random operations
Syntax
- Wrap in braces:
{{ ... }} - Mix with static text:
Hello {{ vars.firstName }}! - Chain methods:
{{ vars.email.trim().toLowerCase() }} - Build paths:
{{ env.API_BASE }}/users/{{ vars.userId }} - Generate data:
{{ random.email() }}
Common examples
-
URL from env and vars:
{{ env.APP_URL }}/account/{{ vars.accountId }} -
Normalizing a value:
{{ vars.username.strip().lower() }} -
Array operations:
{{ [t.strip() for t in env.TAGS.split(',')] }} -
Fallbacks:
{{ vars.displayName or env.DEFAULT_NAME }} -
Compose multiple parts:
Hello {{ vars.firstName }} {{ vars.lastName }}!
Utility functions
Utility functions provide one‑line helpers for common operations. Access them via autocomplete by typing{{ utils. or find them in the Utils tab. These functions are available globally in expressions, so you can call them directly without a prefix.
Date and time
Use date and time utilities to work with timestamps, dates, and time calculations:-
now(): Current date and time{{ format_date(now(), '%Y-%m-%d') }} -
today(): Current date{{ today() }} -
timestamp(): Unix timestamp{{ timestamp() }} -
timedelta(days=...): Time difference for date arithmetic{{ format_date(today() + timedelta(days=7), '%Y-%m-%d') }} -
format_date(date_obj, fmt='%d/%m/%Y'): Format a date object{{ format_date(now(), '%Y-%m-%d %H:%M:%S') }}
String encoding and crypto
Encode, decode, hash, and transform strings:-
uuid(): Generate a random UUID{{ uuid() }} -
md5(text): Generate MD5 hash{{ md5(vars.password) }} -
sha256(text): Generate SHA256 hash{{ sha256(vars.apiKey + env.SECRET) }} -
hmac_sha256(key, msg): Generate HMAC signature{{ hmac_sha256(env.API_SECRET, vars.message) }} -
b64encode(text): Base64 encode{{ b64encode(vars.credentials) }} -
b64decode(text): Base64 decode{{ b64decode(env.ENCODED_TOKEN) }} -
urlencode(text): URL encode{{ urlencode(vars.searchQuery) }} -
urldecode(text): URL decode{{ urldecode(vars.encodedParam) }} -
slugify(text): Convert text to URL‑friendly slug{{ slugify(vars.pageTitle) }}
Math and random
Generate random numbers and select random items:-
randint(min, max): Random integer in range{{ randint(1, 100) }} -
choice(list): Pick random item from list{{ choice(['option1', 'option2', 'option3']) }} -
sample(list, k): Pick k random items from list{{ sample(['a', 'b', 'c', 'd'], 2) }}
Where it works
- Navigate (URL)
- Fill Text (value)
- Verify Text / Verify URL (expected value)
- Select Option (value)
- Start Condition (expression)
- Other fields that support text input in the editor
Expressions in locators
You can use expressions in element locators.-
String locators (e.g., CSS, text engine): If a locator includes
{{ ... }}, it’s evaluated at runtime and passed topage.locator(...).- Example:
This becomes a dynamic string at runtime, supporting mixes like: -
Functional locators (Playwright API style): When your step stores a functional locator (e.g.,
getByRole,getByTestId,locator(...)chains), expressions are supported only inside quoted string literals. The rest of the call remains code-safe.- Example:
At runtime, only the quoted string literal is evaluated, keeping the function call intact.
Notes and safeguards
- Expressions are evaluated at runtime using the same sources (
env,vars,random). - For functional locators, only quoted string literals are transformed. Non‑string parts (objects, function names) are preserved to avoid code injection and keep type safety.
- Prefer concise expressions; move complex logic to a prior step (e.g., Capture Value or Run Python) and reference via
vars.*.
Best practices
- Ensure the variable exists before use (the step that creates it must run earlier)
- Keep expressions concise; move complex logic to a “Run Python” step when needed
- Do not attempt to assign to
env.*(read‑only) - Prefer
strip()/lower()for robust comparisons in verifications
How to use in Run Python
In the Run Python step you do not use{{ }}. The following are directly available:
env.*(read‑only)vars.*random.*- Utility functions (same as in expressions:
now(),uuid(),md5(), etc.)

Troubleshooting
- Variable not found: confirm the producing step ran earlier and saved a variable
- Quote handling: prefer
{{ ... }}without additional quotes; the editor handles string composition - Curly braces: make sure both
{{and}}are present and balanced

