docs: refresh architecture and runtime documentation
- align architecture, development, MCP, and scenario docs with current code - remove obsolete key descriptor document and stale keys/auth references
This commit is contained in:
+60
-58
@@ -1,80 +1,82 @@
|
||||
# Scenario execution
|
||||
|
||||
When a scenario is run, the scheduler creates a `ScenarioRun` with one `ScenarioRunStep` per step. Steps are executed **in order** (by `step.order`), one per scheduler tick.
|
||||
When a scenario run is created, the server creates one `ScenarioRunStep` per scenario step.
|
||||
|
||||
**All steps in the same run share a single Playwright browser instance.** The browser is created on the first `exec` or `sign` step (using session cookies + localStorage), reused for every subsequent step, and closed when the run finishes (pass or fail).
|
||||
- Step runs are ordered by `step.order`.
|
||||
- First step run starts as `pending`; the rest start as `waiting`.
|
||||
- Scheduler tick (`@Interval(1000)`) picks pending runs and processes steps in order.
|
||||
- Steps in the same run share one Playwright browser/context/page.
|
||||
|
||||
## Step types
|
||||
## Execution model
|
||||
|
||||
### `login`
|
||||
Current scheduler behavior is exec-centric:
|
||||
|
||||
Authenticates in a **separate, ephemeral browser** and saves the resulting session to the database. Subsequent exec/sign steps load that session into the shared browser.
|
||||
- `execCode` is required for a step to pass.
|
||||
- `validateCode` is optional and runs after `execCode`.
|
||||
- Legacy step type metadata may still appear in MCP payloads, but run execution is not branched by step type.
|
||||
|
||||
`execCode` must be a JSON object:
|
||||
```json
|
||||
{ "keyId": "3137411915", "environmentName": "liquio-diia-stg" }
|
||||
```
|
||||
## Script runtime
|
||||
|
||||
### `exec`
|
||||
`execCode` and `validateCode` execute as async JavaScript with:
|
||||
|
||||
Runs arbitrary Playwright JS on the **shared page**. The page carries over state from the previous step (URL, form inputs, cookies, etc.).
|
||||
- `page`: Playwright `Page`
|
||||
- `context`: Playwright `BrowserContext`
|
||||
- `helpers`: utility object
|
||||
- `console`: proxied to run logs (`log`, `warn`, `error`, etc.)
|
||||
|
||||
`execCode` is executed as the body of an `async` function with these variables in scope:
|
||||
`validateCode` additionally receives `result`, which is the value returned by `execCode`.
|
||||
|
||||
- `page` — current Playwright `Page`
|
||||
- `context` — current Playwright `BrowserContext`
|
||||
- `helpers.dumpDom(selector?)` — returns a simplified DOM string
|
||||
- `helpers.getStepOutput(order)` — returns the JSON-parsed `output` of a previous step. Positive values are absolute step orders; negative values are relative to the current step (`-1` = previous step).
|
||||
## Available helpers
|
||||
|
||||
Any value returned from `execCode` is JSON-serialised and stored as the `output` field on the `ScenarioRunStep` record. Subsequent steps can read it via `helpers.getStepOutput()`.
|
||||
- `helpers.dumpDom(selector?)`: simplified DOM snapshot
|
||||
- `helpers.log(...args)`, `helpers.warn(...args)`, `helpers.error(...args)`: structured step logs
|
||||
- `helpers.getStepOutput(order)`: prior step output by absolute order (`0`, `1`, ...) or relative (`-1` previous step)
|
||||
- `helpers.getCredential(alias)`: credential payload assigned to the scenario alias
|
||||
- `helpers.env`: shallow copy of environment URL map
|
||||
- `helpers.getEnvUrl(key)`: required environment URL lookup (throws if missing)
|
||||
- `helpers.runSnippet(name, ...args)`: execute stored snippet code in the same page/context/helpers scope
|
||||
|
||||
## Validation contract
|
||||
|
||||
`validateCode` may return:
|
||||
|
||||
```js
|
||||
// example execCode
|
||||
await page.goto('https://cabinet.example.com/tasks/create/987825');
|
||||
await page.locator('input[name="institution"]').fill('caltech');
|
||||
await page.locator('button:has-text("Далі")').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
return page.url(); // stored in ScenarioRunStep.output
|
||||
```
|
||||
|
||||
### `sign`
|
||||
|
||||
Performs EDS signing on the **current shared page** using a key from `KEYS_DIR`. The step clicks the sign widget, selects the file key method, uploads the key file, enters the password, and submits — all without requiring the step author to handle key material in their code.
|
||||
|
||||
`execCode` must be a JSON object:
|
||||
```json
|
||||
{ "keyId": "3137411915" }
|
||||
```
|
||||
|
||||
## Validation code
|
||||
|
||||
Any step type optionally accepts `validateCode` — Playwright JS that runs on the shared page **after** the main action and must return a result evaluated as:
|
||||
|
||||
```js
|
||||
return { success: true, description: 'Application created' };
|
||||
return { success: true, description: 'ok' };
|
||||
// or
|
||||
return { success: false, description: 'Expected success banner not found' };
|
||||
// or simply
|
||||
return someBoolean;
|
||||
return false;
|
||||
```
|
||||
|
||||
If `success` is false the step (and the whole run) fails with the provided `description`.
|
||||
Interpretation:
|
||||
|
||||
## Run statuses
|
||||
- Boolean: `true` = pass, `false` = fail
|
||||
- Object: `success` controls pass/fail; `description` is persisted as step description
|
||||
|
||||
`pending` → `in_progress` → `pass` | `fail`
|
||||
On validation failure, the step fails and the run is marked `fail`.
|
||||
|
||||
Individual step runs also expose `waiting` (not yet reached) and `cancelled` (run failed before this step).
|
||||
## Statuses
|
||||
|
||||
## Adding a new scenario (example workflow)
|
||||
Run status:
|
||||
|
||||
```
|
||||
1. create_environment (if not already present)
|
||||
2. create_scenario → get scenarioId
|
||||
3. create_scenario_step type=login, order=0
|
||||
4. create_scenario_step type=exec, order=1 (navigate + fill form)
|
||||
5. create_scenario_step type=sign, order=2
|
||||
6. create_scenario_step type=exec, order=3 (validateCode checks success banner)
|
||||
7. run_scenario → get runId
|
||||
8. wait_for_scenario_run (blocks until pass/fail, returns full run with outputs)
|
||||
```
|
||||
- `pending`
|
||||
- `in_progress`
|
||||
- `pass`
|
||||
- `fail`
|
||||
|
||||
Run-step status:
|
||||
|
||||
- `waiting`
|
||||
- `pending`
|
||||
- `in_progress`
|
||||
- `pass`
|
||||
- `fail`
|
||||
- `cancelled`
|
||||
|
||||
## Example workflow
|
||||
|
||||
1. Create environment
|
||||
2. Create credentials and snippets (optional but common)
|
||||
3. Create scenario
|
||||
4. Add ordered steps (`execCode`, optional `validateCode`)
|
||||
5. Assign credentials to scenario aliases when needed
|
||||
6. Run scenario
|
||||
7. Wait for run completion and inspect run logs/outputs
|
||||
|
||||
Reference in New Issue
Block a user