Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JonathanHerSa/xolo-api-hub/llms.txt
Use this file to discover all available pages before exploring further.
Assertions turn a collection run into an automated test suite. Each assertion rule is a declarative condition attached to a saved request; when the collection runner executes that request, AssertionEvaluator checks every rule against the response and records a pass or fail for each. The results flow into the run report and determine whether the runner continues or aborts, making assertions the primary mechanism for catching regressions and validating API contracts directly from your mobile device.
Assertion rules are stored as a JSON array in the assertionsJson column on the SavedRequests table. Each rule is a JSON object with up to four fields, corresponding directly to the fields of AssertionRuleEntity:
| Field | Type | Required | Description |
|---|
type | String | ✅ | One of the assertion type names (see table below) |
target | String | Conditional | JSONPath expression; required for json_path_exists and json_path_equals |
expected | String | ✅ | The expected value or threshold to compare against |
operator | String | ✅ | Comparison operator (default: "equals") |
AssertionRuleEntity.listFromJson(String? jsonStr) is the canonical way to deserialise a stored assertionsJson column value into a typed list, and handles null, empty strings, and malformed JSON gracefully by returning an empty list.
Assertion Types
| Type | target | Example |
|---|
status_code | — | operator: "equals", expected: "200" or operator: "in", expected: "200,201" |
response_time_ms | — | operator: "lessThan", expected: "3000" |
json_path_exists | JSONPath | target: "$.token", operator: "exists", expected: "" |
json_path_equals | JSONPath | target: "$.status", operator: "equals", expected: "\"ok\"" |
body_contains | — | operator: "contains", expected: "success" |
AssertionEvaluator
AssertionEvaluator is a pure domain service — it has no mutable state and no I/O dependencies, making it straightforward to unit-test and to call from any layer.
/// Evaluates a list of assertion rules against a single HTTP response.
///
/// [rules] Assertion rules attached to the request.
/// [statusCode] HTTP status code from the response (nullable if request errored).
/// [durationMs] Round-trip time in milliseconds measured by RequestPipeline.
/// [responseData] Parsed response body (Map, List, String, or null).
/// [errorMessage] Non-null when the HTTP request itself failed (network error, timeout).
///
/// Returns a List<AssertionResultEntity> — one entry per rule.
/// If [rules] is empty, returns a single implicit passing result
/// with message "No assertions defined".
static List<AssertionResultEntity> evaluate({
required List<AssertionRuleEntity> rules,
required int? statusCode,
required int durationMs,
required dynamic responseData,
String? errorMessage,
})
Each AssertionResultEntity in the returned list carries:
| Field | Type | Description |
|---|
ruleType | String | The AssertionType.name of the evaluated rule |
passed | bool | true if the assertion condition was satisfied |
message | String | Human-readable result, e.g., "Status code is 200" or "Expected status 201, got 404" |
When errorMessage is non-null (the HTTP request failed outright), every rule in the list immediately returns passed: false with a message prefixed by "Request error: " — there is no point evaluating status codes or JSONPath against a response that never arrived.
The helper AssertionEvaluator.allPassed(results) returns true only if every entry in the list has passed == true, which is the signal CollectionRunnerService uses to determine the overall step status.
Operators
| Operator | Applicable types | Behaviour |
|---|
equals | status_code, json_path_equals | Exact string or integer equality |
in | status_code | Comma-separated list of acceptable status codes, e.g., "200,201,204" |
lessThan | response_time_ms | Duration strictly less than the expected millisecond threshold |
greaterThan | response_time_ms | Duration strictly greater than the threshold |
exists | json_path_exists | JSONPath must match at least one non-null node |
contains | body_contains | The serialised response body string must contain the expected substring |
For json_path_equals, the expected field may include surrounding quotes (e.g., "\"ok\"") — AssertionEvaluator strips them before comparing, so "ok" and ok both match the string ok.
Adding Assertions in the UI
Open a saved request and tap the Assertions tab. The tab renders a scrollable list of assertion rule cards, each with:
- A Type dropdown — select from
statusCode, responseTimeMs, jsonPathExists, jsonPathEquals, bodyContains.
- A Target field — visible only for
jsonPathExists and jsonPathEquals; enter your JSONPath expression here.
- An Expected field — the value or threshold for the assertion.
Rules are persisted automatically on every field change. Tap Add Assertion (the outlined button at the bottom of the list) to append a new rule pre-filled with statusCode / equals / 200. To delete a rule, remove it from the list — changes are saved immediately.
Add a status_code equals 200 assertion to every request as a baseline — it costs nothing and catches regressions immediately. Xolo pre-fills this rule whenever you open the Assertions tab on a request that has no assertions defined, making it a zero-friction starting point.
Viewing Results
In the Run Report, each step card is expandable. Tapping a card reveals:
- An inline list of assertion results, one row per rule, with a ✅ or ❌ icon followed by the evaluator message.
- The full error message if the HTTP request itself failed.
- A snippet of the response body (up to 500 characters) for quick inspection.
This lets you see at a glance exactly which assertion failed and what the actual value was, without leaving the mobile app.
Example: Login Request Assertions
[
{
"type": "statusCode",
"expected": "200",
"operator": "equals"
},
{
"type": "responseTimeMs",
"expected": "2000",
"operator": "lessThan"
},
{
"type": "jsonPathExists",
"target": "$.access_token",
"expected": "",
"operator": "exists"
},
{
"type": "jsonPathEquals",
"target": "$.token_type",
"expected": "\"Bearer\"",
"operator": "equals"
},
{
"type": "bodyContains",
"expected": "expires_in",
"operator": "contains"
}
]
This set of five assertions verifies that the login endpoint responds with HTTP 200 within two seconds, returns an access token, sets the correct token type, and includes an expiry field — covering both correctness and basic performance in a single run step.