Skip to main content

Data Extraction APIs

LiveDoc automatically extracts structured data from step and rule titles — quoted values, named parameters, data tables, and doc strings — making your tests both self-documenting and data-driven.

given("the user has '100' items and active is 'true'", (ctx) => {
const [count, isActive] = ctx.step.values;
// count = 100 (number), isActive = true (boolean)
});

Step Data: ctx.step

All step data properties are available on ctx.step inside given, when, then, and, but, and rule callbacks.

ctx.step.values

Type-coerced array of values extracted from single-quoted '...' strings in the step title.

function get values(): any[]

Type Coercion Rules

Input StringCoerced ValueType
'42'42number
'3.14'3.14number
'true'trueboolean
'false'falseboolean
'hello'"hello"string
'[1,2,3]'[1, 2, 3]array
'2024-01-15'Date objectDate

Examples

// Single value
given("the cart has '5' items", (ctx) => {
const count = ctx.step.values[0]; // 5 (number)
expect(count).toBe(5);
});

// Multiple values
then("the result of '10' + '20' should be '30'", (ctx) => {
const [a, b, expected] = ctx.step.values;
// a = 10, b = 20, expected = 30
expect(a + b).toBe(expected);
});

// Mixed types
given("user 'Alice' has '3' items and premium is 'true'", (ctx) => {
const [name, count, isPremium] = ctx.step.values;
// name = "Alice" (string), count = 3 (number), isPremium = true (boolean)
});

ctx.step.valuesRaw

Raw string array of quoted values before type coercion.

function get valuesRaw(): string[]
given("the price is '42.99'", (ctx) => {
ctx.step.values[0]; // 42.99 (number)
ctx.step.valuesRaw[0]; // "42.99" (string)
});

ctx.step.params

Type-coerced object of named parameters extracted from <name:value> patterns in the step title.

function get params(): Record<string, any>

Spaces in parameter names are stripped (e.g., <user name:John>ctx.step.params.username).

Examples

// Named parameters
given("a user with <name:Alice> and <age:30>", (ctx) => {
ctx.step.params.name; // "Alice" (string)
ctx.step.params.age; // 30 (number)
});

// Numeric parameters
when("transferring <amount:250> dollars", (ctx) => {
ctx.step.params.amount; // 250 (number)
});

// Boolean parameters
given("debug mode is <debug:true>", (ctx) => {
ctx.step.params.debug; // true (boolean)
});

ctx.step.paramsRaw

Raw string object of named parameters before type coercion.

function get paramsRaw(): Record<string, string>
given("a user with <age:30>", (ctx) => {
ctx.step.params.age; // 30 (number)
ctx.step.paramsRaw.age; // "30" (string)
});

ctx.step.table

Multi-column data table parsed as an array of objects, using the first row as header keys.

function get table(): Record<string, any>[]

Example

given(`the following users exist:
| name | email | role |
| Alice | alice@example.com | admin |
| Bob | bob@example.com | user |
`, (ctx) => {
const users = ctx.step.table;
// [
// { name: "Alice", email: "alice@example.com", role: "admin" },
// { name: "Bob", email: "bob@example.com", role: "user" }
// ]

expect(users).toHaveLength(2);
expect(users[0].name).toBe("Alice");
expect(users[0].role).toBe("admin");
expect(users[1].email).toBe("bob@example.com");
});

Values in tables are type-coerced using the same rules as quoted values.


ctx.step.tableAsEntity

Two-column table parsed as a single key-value object. The first column provides keys, the second provides values.

function get tableAsEntity(): Record<string, any> | undefined

Example

given(`a product with details:
| name | Widget Pro |
| price | 29.99 |
| stock | 150 |
| active | true |
`, (ctx) => {
const product = ctx.step.tableAsEntity;
// { name: "Widget Pro", price: 29.99, stock: 150, active: true }

expect(product.name).toBe("Widget Pro");
expect(product.price).toBe(29.99);
expect(product.stock).toBe(150);
expect(product.active).toBe(true);
});

ctx.step.tableAsSingleList

Single-column table parsed as a flat array.

function get tableAsSingleList(): any[]

Example

given(`the following status codes:
| 200 |
| 301 |
| 404 |
| 500 |
`, (ctx) => {
const codes = ctx.step.tableAsSingleList;
// [200, 301, 404, 500]

expect(codes).toContain(200);
expect(codes).toContain(404);
});

ctx.step.dataTable

Raw 2D array of the table data, without header interpretation.

function get dataTable(): any[][]

Example

given(`raw data:
| name | age |
| Alice | 30 |
| Bob | 25 |
`, (ctx) => {
const raw = ctx.step.dataTable;
// [
// ["name", "age"],
// ["Alice", 30],
// ["Bob", 25]
// ]
});

ctx.step.docString

Raw multi-line string content enclosed in triple double-quotes (""").

function get docString(): string

Example

when(`the user submits the following markdown:
"""
# Hello World

This is a **test** document.
"""
`, (ctx) => {
const markdown = ctx.step.docString;
expect(markdown).toContain("# Hello World");
expect(markdown).toContain("**test**");
});

ctx.step.docStringAsEntity

Doc string parsed as JSON. Returns undefined if the content is not valid JSON.

function get docStringAsEntity(): any | undefined

Example

given(`the API request body:
"""
{
"name": "Widget",
"price": 29.99,
"tags": ["featured", "new"]
}
"""
`, (ctx) => {
const body = ctx.step.docStringAsEntity;
// { name: "Widget", price: 29.99, tags: ["featured", "new"] }

expect(body.name).toBe("Widget");
expect(body.price).toBe(29.99);
expect(body.tags).toContain("featured");
});

Rule Data: ctx.rule

Rules have their own value extraction via ctx.rule, in addition to ctx.step.

ctx.rule.values

Type-coerced array of quoted values from the rule title. Identical coercion rules as ctx.step.values.

function get values(): any[]
rule("Adding '5' and '3' returns '8'", (ctx) => {
const [a, b, expected] = ctx.rule.values;
expect(a + b).toBe(expected);
});

ctx.rule.valuesRaw

Raw string array of quoted values from the rule title.

function get valuesRaw(): string[]
rule("The price is '42.99' dollars", (ctx) => {
ctx.rule.values[0]; // 42.99 (number)
ctx.rule.valuesRaw[0]; // "42.99" (string)
});

ctx.rule.params

Type-coerced named parameters from the rule title.

function get params(): Record<string, any>
rule("Processing <action:login> for <user:alice>", (ctx) => {
ctx.rule.params.action; // "login"
ctx.rule.params.user; // "alice"
});

ctx.rule.paramsRaw

Raw string named parameters from the rule title.

function get paramsRaw(): Record<string, string>
rule("Set timeout to <ms:5000>", (ctx) => {
ctx.rule.params.ms; // 5000 (number)
ctx.rule.paramsRaw.ms; // "5000" (string)
});
Rule vs Step Data

Inside a rule() callback, both ctx.rule and ctx.step provide extracted values and params. Use ctx.rule for clearer intent when working with rule-level data.


Combining Extraction Methods

You can combine quoted values with data tables or doc strings in the same step:

given(`a user named 'Alice' with permissions:
| read |
| write |
| admin |
`, (ctx) => {
const name = ctx.step.values[0]; // "Alice"
const perms = ctx.step.tableAsSingleList; // ["read", "write", "admin"]
});

Summary Table

PropertyExtraction SourceReturnsAvailable In
ctx.step.values'quoted' valuesany[] (coerced)Steps, Rules
ctx.step.valuesRaw'quoted' valuesstring[] (raw)Steps, Rules
ctx.step.params<name:value>Record<string, any>Steps, Rules
ctx.step.paramsRaw<name:value>Record<string, string>Steps, Rules
ctx.step.tablePipe-delimited rowsobject[]Steps, Rules
ctx.step.tableAsEntity2-column tableobjectSteps, Rules
ctx.step.tableAsSingleList1-column tableany[]Steps, Rules
ctx.step.dataTablePipe-delimited rowsany[][] (raw 2D)Steps, Rules
ctx.step.docString"""...""" blockstringSteps, Rules
ctx.step.docStringAsEntity"""...""" JSONany | undefinedSteps, Rules
ctx.rule.values'quoted' valuesany[] (coerced)Rules only
ctx.rule.valuesRaw'quoted' valuesstring[] (raw)Rules only
ctx.rule.params<name:value>Record<string, any>Rules only
ctx.rule.paramsRaw<name:value>Record<string, string>Rules only

See Also