Every automation hook receives a RunContext. It is the automation's whole world: the identity of the run, the
browser, a logger, a step recorder and one facade per declared capability. An automation that wants a capability it
did not declare is refused by name at run time, rather than handed a quiet empty surface.
#The context object
| Member | What it is |
|---|---|
ctx.automationId |
The automation's stable id. |
ctx.runId |
The id of this run, chosen by the caller or generated. |
ctx.baseURL |
The target application's base URL, from the automation definition (a --url override wins). |
ctx.settings |
The executing robot's robotId, machine and environment. |
ctx.screenshotsDir |
Where failure screenshots are written. |
ctx.screenshot(name) |
Capture the current page state and return the path. |
ctx.note(msg, data?) |
Record an ad-hoc note for the current transaction, visible in the logs. |
ctx.requestStop() |
Ask the run to stop after the current operation. |
ctx.checkAborted() |
Throws if a stop was requested. Call it between operations. |
#Recording steps
ctx.steps is how a failure says where it happened. ctx.steps.record(name, work) runs work as a named step and
records its outcome and its measured duration, rethrowing the same error unchanged on failure. ctx.steps.records()
returns a copy of what this attempt recorded. ctx.steps.reset() forgets them and the runner calls it at the start
of every attempt.
Steps are named and flat. An unnamed step is refused with STEP_NAME_REQUIRED and a step inside another step is
refused with STEP_NESTED, because an inner step would double-count its outer one and "step 3 of 5" would stop
meaning what it says. ctx.steps.record throws a SystemException for both, with retryable: false.
#The log
ctx.log writes structured entries to JSONL and a human-readable mirror. The levels are debug, info, warn and
error, each taking (msg, data?, meta?). data is JSON-serialisable. meta may carry step, tx and
attempt.
#The browser surfaces
ctx.page is the single page an automation drives and it is a Playwright Page. ctx.context is the browser
context and ctx.browser is the browser itself. Elements are addressed through the Target Repository by name, not
by a selector written inline.
#Credentials
ctx.credentials.get(name) resolves a credential by name and returns its fields. Automations never read a
credential value from source, never read an environment variable directly and never embed a secret. The name is
the only thing a call site carries.
#The capability facades
A facade is present only when the automation declares its capability (web, excel, files, api, database,
email, pdf or desktop). Each method is the surface below.
| Facade | Members |
|---|---|
ctx.excel |
resolvePath, readWorkbook, readTable, readRange, writeTable, append, updateCells, createSheet, deleteSheet, toCSV, deleteFile, fileExists |
ctx.files |
exists, readFile, readBinary, writeFile, writeBinary, appendFile, list, deleteFile, writeJson, readCsv, writeCsv |
ctx.email |
send(credentialName, message); send only, with the host and security policy from the vault record |
ctx.api |
request, get, post, put, patch, delete; each returns a result rather than throwing on 2xx or 3xx |
ctx.db |
bind, open, close, query, execute, scalar, begin, commit, rollback |
ctx.pdf |
read(name, options); the text layer only, a page with no text layer refused by name |
ctx.desktop |
engine, read, press, text, setValue, activate, closeWindow, select, toggle, selectItem |
ctx.files works inside the robot's data-directory jail and ctx.excel resolves relative paths there. ctx.api
maps a timeout or a network failure to a retryable SystemException, a 5xx to a retryable SystemException and a
4xx to a BusinessException that is not retried. ctx.db takes named connections only, declared by name and
provider, never a connection string in an automation. ctx.desktop addresses a control by its accessible name or
automationId and its control type, never by a coordinate and refuses every verb by name when no bridge is
present.
#Run control and identity
The run loop is init, then get transaction, process transaction, then success or a lane. A BusinessException is an
expected domain failure: the transaction fails and the run continues, never retried. A SystemException is an
infrastructure failure: it is retried under the bounded policy and only after the attempts are exhausted is the
transaction marked failed. An unknown error is treated as a retryable system failure, also bounded.