Files
liqa/docs/scenario.md
T
ars9 71bcc8faec feat(scenario): step output, getStepOutput helper, export/import MCP tools, doc restructure
- 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)
2026-04-08 19:02:36 +03:00

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 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).

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

pendingin_progresspass | 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)