How steps read
Every step of Axx’s packs follows the same grammar. The pack pages list each step with its parameters, the rows its table takes, its variants and an example.
Optional parts
Section titled “Optional parts”An expression writes optional parts as [[ ... ]]. A step matches with or without each of them. the[[ {ordinal} ordered]] response status code is {int}[[ on {service}]] matches:
the response status code is 200the 2nd ordered response status code is 201the response status code is 200 on parcelsthe 2nd ordered response status code is 201 on parcels
axx steps show prints every variant of a step, given its id, its expression or a line that uses it.
Services
Section titled “Services”A step without a service name uses the default service: the first one of its kind registered in the scenario. The named form (on parcels, on parcels-db, on the events kafka service) picks another.
Ordinals
Section titled “Ordinals”1st, 2nd, 3rd, 4th, … count requests, selections and events within a scenario, starting at 1. A step without an ordinal uses the first.
Arguments
Section titled “Arguments”{string}takes single or double quotes; the quotes are removed, and where the step sets or checks a value, what is inside them is that value: see Values.a(n),time(s),row(s),document(s)anditem(s)are optional text:1 timeand2 timesboth match.- A step that ends with
:takes a data table, or a doc string, on the following lines. Its entry shows the table’s columns and the rows it knows. - What a value means is the same in every step: see Values.
Values
Section titled “Values”A value means what it says, the same in every pack, whether a step sets it or checks it (ADR 0014).
| Written | Is |
|---|---|
42 |
an integer |
42L |
a long: an integer, which a MongoDB query sends as an int64 |
1.5, 2.0 |
a decimal |
true, false |
a boolean |
null |
null |
undefined |
no such property: a check that it is absent, or a property removed |
{"country": "DE"}, ["EXPRESS"] |
JSON |
"42", "true", "null", "undefined", "01067" |
the string inside the double quotes |
any other text, like REGISTERED or PX-4101 |
a string |
- Nothing is inferred, from an example, a schema or a column’s type.
| postcode | 10115 |sets and checks the number 10115, and the string is"10115". - A value of the wrong type is sent as written, so a test can still send one on purpose:
| weightGrams | "1200" |. - Checks are strict: types must match.
42does not match the string “42”, nor2the decimal2.0. - A
where:is held to the column’s real type, before the query, as a database would otherwise convert one of them:| postcode | 10115 |on a text column asks for"10115", and| price | 12 |on a decimal one for12.0. - Sources keep their types. A whole double is a decimal (
6.0), a BigQuery NUMERIC a decimal, a MongoDB Decimal128 the number of its digits, and a protobuf message’s int64 fields are numbers. - A value that could be read two ways fails, and its message gives the forms to write:
- an empty cell:
""for the empty string,nullfor null, andundefinedfor no such property where the step takes it; - a number in a form JSON does not have: a leading zero (
01067), a sign (+5), a suffix (1.5f),NaNorInfinity.
- an empty cell:
- Where a value can only be text, one that reads as anything else fails too: a header, a query parameter or form field, a Redis string, a line of a file or of output, text on a screen.
| Retry-After | 5 |asks for"5". A table’s entry says when its values are text. - In a step’s own text, the quotes are the step’s, and the value inside them follows the rule:
the response payload property priceCents is '690'checks the integer, andis '"690"'the string. REST’s property steps also take an integer without quotes:is 690. Where only text fits,the response header Retry-After is '5'asks for'"5"', which is the text 5, andis 'application/json'is plain text. A${env:…}reference is text, whatever it expands to. - To find JSON as text, put it in double quotes inside the step’s own:
the response body contains '"{"status":"ok"}"'. Without them,'{"status":"ok"}'reads as JSON, and fails asking for them. A pair of double quotes around the whole value is always the rule’s:'"status":"ok"'looks forstatus":"ok, and'""status":"ok""'for"status":"ok". - A name or a pattern is not a value. A name finds something, as written: a button, a field’s label, a page, a file, a tab. A pattern (
… match:,matching '…',the page's requests to '…') and a command line have grammars of their own. Sothe "5" button is clickedis the button named 5, and a pattern matches the value’s text:| postcode | ^[0-9]{5}$ |.
axx validate, the MCP server’s feature_validate and the editors report what a feature shows on its own, as AXX-E0207: empty cells, numbers in other forms, and values that are not text where only text fits, in a table or in a step’s own text. The steps fail with the same messages when they run.
Parameter types
Section titled “Parameter types”| Parameter | Takes | Values | For example | Pack |
|---|---|---|---|---|
{anchor} |
the point of a control that places on it are measured from: its middle, or a corner. Places run right and down from it, so one left of or above it is negative |
middle, top left, top right, bottom left, bottom right |
middle, bottom right |
desktop-core |
{bigdecimal} |
a decimal number of any precision | 0.1000000000000000055 |
cucumber | |
{biginteger} |
a whole number of any size | 123456789012345678901234567890 |
cucumber | |
{byte} |
a whole number, from -128 to 127 | 12 |
cucumber | |
{connection} |
a connection: the name of a proxy in Toxiproxy’s config | parcels-db, cache |
faults | |
{control} |
a kind of control an app shows, found by the name people see: a button by its text, a field by its label, a list item or a row by one of its texts, a menu item in its open menu, an element is anything, by its text or accessibility label; a phone’s notification is tapped, by a text in its title or its text. A kind an app’s platform does not have (a phone has no menu bar) fails the step |
button, field, checkbox, radio button, switch, tab, menu, menu item, list item, row, link, image, text, element, notification |
button, list item |
app-core |
{dataDirection} |
the direction of a connection’s data a fault applies to: coming back to the service, or going out from it |
coming back, going out |
faults | |
{dbService} |
the name of a database registered in the scenario | parcels-db |
sql | |
{direction} |
where a swipe goes, as the finger moves (down from the top pulls a list to refresh); or which way a phone moves or turns in the scene its camera sees, where it also moves forward and back |
up, down, left, right, forward, back |
down, left, forward |
mobile-core |
{double} |
a decimal number | 19.90 |
cucumber | |
{duration} |
a duration in milliseconds (ms), seconds (s) or minutes (m) |
5s, 2m, 500ms |
core | |
{element} |
a kind of element on the page, plural after a number (buttons): a field by its label or placeholder, an option is a radio button, an element is anything, by its text, label, alternative text or title |
button, field, checkbox, option, link, tab, menu item, element |
button, field |
web-core |
{filepath} |
a file of the project: a path relative to the feature file’s directory, the resources directories or axx.yaml’s directory (looked for in that order), or an absolute path, quoted when it has a space |
seeds/parcels.yaml, kafka/scan-delivered.json, "seeds/day one.yaml" |
core | |
{float} |
a decimal number | 2.5, 0.1 |
cucumber | |
{gaugeValue} |
a gauge’s value, of its type: 4 an integer, and 4.0 a decimal |
4, 4.5 |
otel | |
{int} |
a whole number | 200, 3 |
cucumber | |
{integer} |
an integer, in a step’s text without quotes: is 2500 says what is '2500' says |
2500 |
rest | |
{long} |
a whole number, however large | 9007199254740993 |
cucumber | |
{mimeType} |
a content type | application/json, text/json, application/problem+json, application/x-www-form-urlencoded |
application/json |
core |
{mockedService} |
the name of a mocked service the scenario registered | addresses |
mock | |
{mongoService} |
the name of a MongoDB database registered in the scenario | tracking-db |
mongo | |
{ordinal} |
a position, counting from 1; an optional ordinal left out is the first | 1st, 2nd, 3rd |
core | |
{path} |
a path in a folder or a store, like manifests/M-1/report.csv, quoted when it has a space. A * stands for any characters but a slash, for a name a check cannot know (snap-*.json, named by the time): the path then names the one file it matches |
manifests/M-KESTREL-0412/report.csv, "Parcels/Depot desk/arrivals.json", snap-*.json |
core | |
{pattern} |
a regular expression (Java syntax) with no spaces, which matches the whole value | PX-\d{4}, [A-Z]{2}-\d+ |
core | |
{service} |
the name of a REST service the scenario registered | parcels |
rest | |
{short} |
a whole number, from -32768 to 32767 | 1200 |
cucumber | |
{speed} |
how fast a phone travels: 25 mph, 40 km/h or 11 m/s; or, for a GPX file with times, how many times its own pace: 4x |
25 mph, 40 km/h, 4x |
mobile-core | |
{sqlState} |
a five-character SQLSTATE error code, like 40001 (serialization failure) or 23505 (unique violation); on Oracle, an ORA error, like ORA-20001, or its five digits |
40001, 23505, ORA-20001 |
sql | |
{string} |
text in double or single quotes, which the step leaves out | "Get a quote", 'Express' |
cucumber | |
{telemetry} |
the name of telemetry registered in the scenario | parcels-api |
otel | |
{travel} |
whether the step waits for the phone to arrive (travels), or lets the scenario go on while it moves (starts traveling) |
travels, starts traveling |
travels, starts traveling |
mobile-core |
{word} |
one word, with no spaces | parcels, PX-4101 |
cucumber |