Step Execution Modal
When a TCM test case is opened in step-by-step mode — or a Test Plan reaches a manual approval item that needs a human verdict — Mockarty opens a step execution modal. This page documents what the modal does and the API behind it.
What the modal looks like
The modal has two panes:
- Left — every step in the run, with a coloured status badge.
- Right — the active step’s action, expected result, output fields, and a comment editor.
Below the active step there are four outcome buttons (Pass, Fail, Skip, Block) plus Previous / Next for navigation. Choosing an outcome records the verdict, captures any outputs, and auto-advances to the next non-terminal step.
Comments support Markdown. They are sent to the server together with the chosen outcome — there is no separate auto-save round-trip, so a fast click on Pass can never race a pending comment save.
Outcomes
| Status | Meaning |
|---|---|
| Pending | Not started yet. |
| Running | The step is currently executing. |
| Awaiting manual | The runner has paused — a human verdict is needed. |
| Passed | The step met its expected result. |
| Failed | The step did not meet its expected result. |
| Skipped | The step was deliberately bypassed. |
| Blocked | Mockarty records this as Failed with a [blocked] marker on the comment, so dashboards differentiate “we tried and it didn’t work” from “we couldn’t try because something else got in the way”. |
Outputs
Each step can publish named output values that later steps may reference. Outputs are simple key → value pairs, stored as JSON on the step row.
The intended placeholder syntax for downstream steps is:
${steps.<step-uid>.<output-name>}
For example, a “Login” step that publishes a token output:
${steps.login.token}
The storage is in place today (the resolve API accepts an extracted map). Substituting those values into the next step’s text is not supported; read them from the step snapshot and feed them into your own scripts.
API
The modal is driven by the existing TCM case-run endpoints. You can integrate from your own scripts.
Base path: /api/v1/namespaces/{namespace}/tcm/case-runs/{run_id}.
| Method | Path | Purpose |
|---|---|---|
GET |
/ |
Snapshot the run and all step rows. |
GET |
/stream |
Server-sent events stream for live updates. |
POST |
/steps/{step_uid}/resolve |
Atomic terminal transition: resolution + comment + outputs. |
POST |
/pause |
Pause the case run. |
POST |
/resume |
Resume a paused run. |
POST |
/cancel |
Cancel an in-flight run. |
POST |
/rerun |
Start a fresh run that supersedes this one. |
Snapshot
curl https://mockarty.example.com/api/v1/namespaces/{namespace}/tcm/case-runs/{run_id} \
-H "Authorization: Bearer $MOCKARTY_API_TOKEN"
The response is the run summary plus a steps array. Each step row carries its stepUid, current status, the latest resolutionNote (your comment), and bindingsExtracted (your outputs).
Record an outcome with a comment and outputs
curl -X POST https://mockarty.example.com/api/v1/namespaces/{namespace}/tcm/case-runs/{run_id}/steps/{step_uid}/resolve \
-H "Authorization: Bearer $MOCKARTY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resolution": "pass",
"note": "Logged in as admin@example.com.",
"noteFmt": "markdown",
"extracted": {"token": "abc-123"}
}'
resolution accepts pass, fail, skip (long-form passed, failed, skipped also accepted). noteFmt is markdown (default) or plain. extracted is the per-step output map.
If the run or step is already in a terminal state the call returns 409 Conflict with code: step_or_run_terminal so your client can handle the no-op cleanly.
Permissions and isolation
- Snapshot + stream require
test_case:readon the namespace. - Resolve, pause, resume, cancel, rerun require
test_case:write. - All endpoints are namespace-scoped; a user from one namespace cannot read or mutate another namespace’s case runs.
- Every state-changing call is recorded in the audit log under one of
tcm_case_step_resolve,tcm_case_run_pause,tcm_case_run_resume,tcm_case_run_cancel,tcm_case_run_rerun.
Opening the modal from custom code
The modal is exposed on the global window object so any page in the admin UI can open it:
window.openStepRunModal({
runId: '11111111-2222-3333-4444-555555555555',
namespace: 'acme',
title: 'Acceptance run',
steps: [
{stepUid: 'login', title: 'Sign in', description: 'Open /login and submit credentials.', expected: 'Dashboard loads.', outputs: ['token']},
{stepUid: 'fetch', title: 'Fetch profile', description: 'GET /profile with ${steps.login.token}.'},
{stepUid: 'logout', title: 'Sign out'},
],
onComplete: (rows) => console.log('all done', rows),
});
Call window.closeStepRunModal() to close it programmatically.
The steps array is the caller’s view of the case definition; the modal hydrates the per-step status, comment, and outputs from the server snapshot when it opens. Your steps provide the static metadata (title, description, expected, declared outputs) — the runtime state always comes from the server-side run snapshot.