Every operation, from every interface, returns the same ActionResult.
{
"ok": true,
"op": "click",
"action_id": "s1-2",
"session_id": "s1",
"target": {
"element": { "ref": "e1", "role": "button", "name": "Sign in", "tag": "button" },
"strategy": "role",
"candidates": 1
},
"page": { "url": "http://localhost:3000/dashboard", "title": "Dashboard" },
"verification": {
"status": "passed",
"checks": [
{ "condition": { "type": "url_contains", "value": "dashboard" }, "passed": true,
"observed": { "url": "http://localhost:3000/dashboard" } }
]
},
"timing": { "started_at_ms": 1792905230645, "duration_ms": 59, "timeout_ms": 10000 }
}
Fields that would be empty (data, error, evidence, notes) are left out.
| Field | Meaning |
|---|---|
ok |
The operation succeeded and any requested verification passed. |
target |
The element acted on, which locator strategy found it, and how many candidates there were. |
page |
URL and title after the operation. |
verification.status |
passed, failed, or not_checked. A click without expect reports not_checked: the input was delivered, but nothing confirmed the outcome. |
verification.checks |
Each condition with passed and what was observed. |
data |
The operation's output: a snapshot, an evaluate result, a list of tabs, … |
error |
Present when ok is false: kind, message, recoverable, and sometimes details (such as the candidates of an ambiguous locator). |
evidence |
Files written (screenshots, videos, saved states), with paths. |
notes |
What else happened: navigated, url_changed, dom_changed, a dialog that was dismissed, a wait for a client-rendered page, … |
kind |
Recoverable | Meaning |
|---|---|---|
not_found |
yes | No element matched (yet). |
not_actionable |
yes | The element is hidden, disabled, covered or moving. |
stale_element |
yes | The element was removed or replaced. |
timeout |
yes | A wait or an operation ran out of time. |
ambiguous |
no | Several elements matched and no nth was given. details lists them. |
verification_failed |
no | The action happened, but its expect didn't hold. Don't repeat it blindly. |
approval_required |
no | A consequential click needs approved: true (MCP's default policy). |
permission_denied |
no | The policy forbids it (host not allowed, upload outside allowed directories, evaluate off). |
navigation_failed |
no | The page didn't load (DNS, connection, certificate, …). |
invalid_argument |
no | The request is malformed. |
unsupported |
no | This backend can't do it. |
session_not_found, session_limit |
no | Session problems. |
backend |
no | The browser failed unexpectedly. |
"Recoverable" means a later attempt could succeed without changing the request. SwiftBrowse already retries these automatically until the action's timeout, but only when the failure happened before any input reached the page. A click that was delivered is never retried.
A failed interaction also attaches a screenshot to evidence.
get_test_report returns the session's verdict: every assertion with its result, failed actions, console errors, network failures and evidence. The test runner builds its reports from the same data.
# Results and errors
Every operation, from every interface, returns the same `ActionResult`.
```json
{
"ok": true,
"op": "click",
"action_id": "s1-2",
"session_id": "s1",
"target": {
"element": { "ref": "e1", "role": "button", "name": "Sign in", "tag": "button" },
"strategy": "role",
"candidates": 1
},
"page": { "url": "http://localhost:3000/dashboard", "title": "Dashboard" },
"verification": {
"status": "passed",
"checks": [
{ "condition": { "type": "url_contains", "value": "dashboard" }, "passed": true,
"observed": { "url": "http://localhost:3000/dashboard" } }
]
},
"timing": { "started_at_ms": 1792905230645, "duration_ms": 59, "timeout_ms": 10000 }
}
```
Fields that would be empty (`data`, `error`, `evidence`, `notes`) are left out.
| Field | Meaning |
|---|---|
| `ok` | The operation succeeded **and** any requested verification passed. |
| `target` | The element acted on, which locator strategy found it, and how many candidates there were. |
| `page` | URL and title after the operation. |
| `verification.status` | `passed`, `failed`, or `not_checked`. A click without `expect` reports `not_checked`: the input was delivered, but nothing confirmed the outcome. |
| `verification.checks` | Each condition with `passed` and what was `observed`. |
| `data` | The operation's output: a snapshot, an evaluate result, a list of tabs, … |
| `error` | Present when `ok` is false: `kind`, `message`, `recoverable`, and sometimes `details` (such as the candidates of an ambiguous locator). |
| `evidence` | Files written (screenshots, videos, saved states), with paths. |
| `notes` | What else happened: `navigated`, `url_changed`, `dom_changed`, a dialog that was dismissed, a wait for a client-rendered page, … |
## Error kinds
| `kind` | Recoverable | Meaning |
|---|---|---|
| `not_found` | yes | No element matched (yet). |
| `not_actionable` | yes | The element is hidden, disabled, covered or moving. |
| `stale_element` | yes | The element was removed or replaced. |
| `timeout` | yes | A wait or an operation ran out of time. |
| `ambiguous` | no | Several elements matched and no `nth` was given. `details` lists them. |
| `verification_failed` | no | The action happened, but its `expect` didn't hold. Don't repeat it blindly. |
| `approval_required` | no | A consequential click needs `approved: true` (MCP's default policy). |
| `permission_denied` | no | The policy forbids it (host not allowed, upload outside allowed directories, `evaluate` off). |
| `navigation_failed` | no | The page didn't load (DNS, connection, certificate, …). |
| `invalid_argument` | no | The request is malformed. |
| `unsupported` | no | This backend can't do it. |
| `session_not_found`, `session_limit` | no | Session problems. |
| `backend` | no | The browser failed unexpectedly. |
"Recoverable" means a later attempt could succeed without changing the request. SwiftBrowse already retries these automatically until the action's timeout, but only when the failure happened **before** any input reached the page. A click that was delivered is never retried.
A failed interaction also attaches a screenshot to `evidence`.
## The test report
`get_test_report` returns the session's verdict: every assertion with its result, failed actions, console errors, network failures and evidence. The test runner builds its reports from the same data.