Test file format (DSL)
Every AutoTestX test is stored as a JSON document in one fixed format, the DSL. The editor, the server, the CLI and the runner all read and write this format, and nothing else defines what a test is. You can see any test’s DSL in the editor’s DSL tab.
Current version: 1.8.0.
A complete example
Section titled “A complete example”{ "dslVersion": "1.8.0", "id": "tc_create_po", "name": "Create Purchase Order", "description": "Creates a PO with two lines and checks it is approved.", "engine": "web", "module": "Purchasing", "status": "draft", "tags": ["smoke", "purchase-orders"], "defaults": { "timeoutMs": 8000, "retry": 1, "onError": "abort" }, "variables": { "lines": [ { "item": "1234", "qty": "2" }, { "item": "5678", "qty": "1" } ] }, "steps": [ { "id": "open", "type": "browser.open", "label": "Open the application", "params": { "url": "{{baseUrl}}" } }, { "id": "username", "type": "input", "label": "Enter username", "target": { "strategies": [ { "kind": "label", "value": "Username" } ] }, "params": { "value": "{{secret.APP_USER}}", "sensitive": true } }, { "id": "add-lines", "type": "control.forEach", "label": "Add each order line", "params": { "items": "lines", "as": "line" }, "children": [ { "id": "line-item", "type": "input", "target": { "strategies": [ { "kind": "label", "value": "Item" } ] }, "params": { "value": "{{line.item}}" } } ] }, { "id": "verify-status", "type": "assert.text", "soft": true, "target": { "strategies": [ { "kind": "testId", "value": "po-status" } ] }, "params": { "expected": "Approved" } } ], "cleanup": []}The full worked example is examples/create-purchase-order.json.
Test fields
Section titled “Test fields”| Field | Required | Type | Meaning |
|---|---|---|---|
dslVersion |
yes | "MAJOR.MINOR.PATCH" |
Format version the document was written for |
id |
yes | text | Unique test id. Replaced with a new one on import. |
name |
yes | text | Test name |
description |
text | Free text | |
engine |
yes | web | android | ios |
Execution engine |
module |
text | Suite name. Absent = Unsorted. | |
status |
draft | ready | deprecated |
Lifecycle. Absent = draft. |
|
tags |
list of text | Free tags, searchable in the test list | |
defaults |
yes | object | timeoutMs (default 30000), retry (0), onError (abort) |
variables |
object | Test variables, available as {{name}} |
|
steps |
yes | list of steps | The test body |
cleanup |
list of steps | Always runs after the body, pass or fail | |
data |
object | Data-driven binding (since 1.7.0). See below. |
Step fields
Section titled “Step fields”| Field | Required | Meaning |
|---|---|---|
id |
yes | Unique within the test |
type |
yes | A step type from the step reference |
label |
Name shown in the editor and reports | |
target |
per type | { scope?, strategies: [...], fingerprint? }. See Element targets. |
params |
per type | The step’s parameters |
timeoutMs, retry, onError |
Override the test defaults | |
soft |
Soft assertion | |
disabled |
Skip this step | |
children |
blocks | Body of If / For each / Repeat / While / Lookup |
orElse |
If only | The otherwise branch |
Strategy objects
Section titled “Strategy objects”{ "kind": "testId", "value": "save-po" }{ "kind": "role", "role": "button", "name": "Save", "exact": true }{ "kind": "label", "value": "Username" }{ "kind": "placeholder", "value": "Search…" }{ "kind": "altText", "value": "Logo" }{ "kind": "title", "value": "Close" }{ "kind": "text", "value": "Approved", "exact": true, "nth": 0 }{ "kind": "css", "value": "#btn_save_123" }{ "kind": "xpath", "value": "//*[@id='po-form']//button" }Any strategy may carry "confidence": 0.0–1.0 (informational).
"scope": { "frame": ["iframe#content"], "within": { "role": "row", "key": "{{poNumber}}" }}within also accepts selector (CSS) or testId.
Data binding (data)
Section titled “Data binding (data)”"data": { "source": { "kind": "dataSet", "id": "tds_…" }, "independent": true, "maxConcurrency": 3, "sensitiveColumns": ["password"]}source.kind |
Fields |
|---|---|
inline |
columns: [..], rows: [ { column: value } ] |
dataSet |
id of a project data set |
http |
url, method?, headers?, body?, rowsPath? (expression over response) |
pool |
poolId, count, onFinish?: "consume" | "release" |
Versioning and migration
Section titled “Versioning and migration”dslVersion follows semantic versioning:
- Minor versions add optional features (lookup in 1.4, components in 1.5, HTTP steps in 1.6, data binding and custom code in 1.7, upload in 1.8). An older document is still valid under a newer version.
- A breaking change always comes with a migration. The only one so far,
0.9.0 → 1.0.0, replaced the singleselectorstring with an ordered strategy list. - Migration is forward-only and automatic on import and in the CLI.
atx migrateshows or writes the result. - A document from a newer version than the server is rejected rather than guessed at.
A step type the test’s engine does not implement fails validation when you save, not at run time. A deprecated step type produces a warning.
Validation
Section titled “Validation”atx validate file.json, the editor and the server all apply the same checks:
- JSON schema (fields, types, unknown fields rejected),
- every step type exists and is supported by the test’s engine,
- every step’s parameters match its schema,
- every template and expression parses,
- step-specific rules (e.g. a lookup with
completion: "ok"needs an OK control).
Problems are reported with a path, e.g. step username.params.value, and a severity:
error (blocks saving and running) or warning.