- add output column to ScenarioRunStepEntity; exec step return value is JSON-serialised and stored - expose helpers.getStepOutput(order) in exec code; negative order is relative to current step - add get_scenario_run, wait_for_scenario_run, export_scenario, import_scenario MCP tools - move Architecture, Key descriptors, MCP tools, Scenario, Development docs to docs/ - delete CONTRIBUTING.md (replaced by docs/development.md)
3.3 KiB
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.
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 types
login
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 must be a JSON object:
{ "keyId": "3137411915", "environmentName": "liquio-diia-stg" }
exec
Runs arbitrary Playwright JS on the shared page. The page carries over state from the previous step (URL, form inputs, cookies, etc.).
execCode is executed as the body of an async function with these variables in scope:
page— current PlaywrightPagecontext— current PlaywrightBrowserContexthelpers.dumpDom(selector?)— returns a simplified DOM stringhelpers.getStepOutput(order)— returns the JSON-parsedoutputof a previous step. Positive values are absolute step orders; negative values are relative to the current step (-1= previous step).
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().
// 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:
{ "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:
return { success: true, description: 'Application created' };
// or
return { success: false, description: 'Expected success banner not found' };
// or simply
return someBoolean;
If success is false the step (and the whole run) fails with the provided description.
Run statuses
pending → in_progress → pass | fail
Individual step runs also expose waiting (not yet reached) and cancelled (run failed before this step).
Adding a new scenario (example workflow)
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)