Модал пошагового выполнения
Когда TCM-кейс открыт в режиме обхода шагов — или Test Plan дошёл до ручного approval-айтема — Mockarty открывает модал пошагового выполнения. На этой странице описано, что делает модал и какой API стоит за ним.
Как выглядит модал
В модале две панели:
- Слева — все шаги прогона со статус-бейджами.
- Справа — действие текущего шага, ожидаемый результат, поля выходных значений и редактор комментария.
Под текущим шагом — четыре кнопки исхода (Пройден, Провален, Пропустить, Заблокировать) и Назад / Вперёд для навигации. Выбор исхода фиксирует вердикт, сохраняет выходные значения и автоматически переходит к следующему незавершённому шагу.
Комментарии поддерживают Markdown. Они отправляются на сервер в одном запросе вместе с выбранным исходом — отдельного автосохранения нет, поэтому быстрый клик по Пройден не может конкурировать с фоновым сохранением.
Исходы
| Статус | Значение |
|---|---|
| В ожидании | Шаг ещё не начат. |
| Выполняется | Шаг сейчас исполняется. |
| Ждёт ручной обработки | Раннер приостановлен — нужен вердикт человека. |
| Пройден | Шаг выполнил ожидаемый результат. |
| Провален | Шаг не выполнил ожидаемый результат. |
| Пропущен | Шаг намеренно обойдён. |
| Заблокирован | Mockarty фиксирует это как Провален с пометкой [blocked] в комментарии — дашборды отличают «попробовали и не получилось» от «не смогли попробовать из-за внешней зависимости». |
Выходные значения
Каждый шаг может опубликовать именованные выходные значения, которые позже потребят следующие шаги. Это простые пары ключ → значение, которые хранятся как JSON в строке шага.
Синтаксис плейсхолдеров для последующих шагов:
${steps.<step-uid>.<имя-выхода>}
Например, шаг “Login” публикует выход token:
${steps.login.token}
Хранилище уже на месте (resolve API принимает мапу extracted). Подстановка этих значений в текст следующего шага не поддерживается: прочитайте их из снапшота прогона и подставьте в своих скриптах.
API
Модал работает поверх существующих TCM-эндпоинтов прогона. Их можно вызывать из своих скриптов.
Базовый путь: /api/v1/namespaces/{namespace}/tcm/case-runs/{run_id}.
| Метод | Путь | Назначение |
|---|---|---|
GET |
/ |
Снапшот прогона со всеми строками шагов. |
GET |
/stream |
SSE-поток для живых обновлений. |
POST |
/steps/{step_uid}/resolve |
Атомарный терминальный переход: resolution + комментарий + выходы. |
POST |
/pause |
Приостановить прогон. |
POST |
/resume |
Возобновить приостановленный прогон. |
POST |
/cancel |
Отменить идущий прогон. |
POST |
/rerun |
Запустить новый прогон, который заменяет этот. |
Снапшот
curl https://mockarty.example.com/api/v1/namespaces/{namespace}/tcm/case-runs/{run_id} \
-H "Authorization: Bearer $MOCKARTY_API_TOKEN"
Ответ — сводка прогона плюс массив steps. Каждая строка несёт stepUid, текущий status, последний resolutionNote (комментарий) и bindingsExtracted (выходные значения).
Зафиксировать исход с комментарием и выходами
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": "Залогинились как admin@example.com.",
"noteFmt": "markdown",
"extracted": {"token": "abc-123"}
}'
resolution принимает pass, fail, skip (длинные passed, failed, skipped тоже работают). noteFmt — markdown (по умолчанию) или plain. extracted — мапа выходных значений шага.
Если прогон или шаг уже в терминальном состоянии, ответ — 409 Conflict с code: step_or_run_terminal, чтобы клиент аккуратно обработал no-op.
Права и изоляция
- Снапшот + stream требуют
test_case:readв namespace. - Resolve, pause, resume, cancel, rerun —
test_case:write. - Все эндпоинты scope’ятся по namespace; пользователь одного NS не может читать или менять прогоны другого NS.
- Каждый изменяющий вызов записывается в audit log:
tcm_case_step_resolve,tcm_case_run_pause,tcm_case_run_resume,tcm_case_run_cancel,tcm_case_run_rerun.
Открыть модал из своего кода
Модал доступен на глобальном window, так что любая страница admin UI может его вызвать:
window.openStepRunModal({
runId: '11111111-2222-3333-4444-555555555555',
namespace: 'acme',
title: 'Приёмочный прогон',
steps: [
{stepUid: 'login', title: 'Войти', description: 'Открыть /login и отправить креды.', expected: 'Открывается дашборд.', outputs: ['token']},
{stepUid: 'fetch', title: 'Получить профиль', description: 'GET /profile с ${steps.login.token}.'},
{stepUid: 'logout', title: 'Выйти'},
],
onComplete: (rows) => console.log('всё готово', rows),
});
window.closeStepRunModal() закрывает модал программно.
Массив steps — это вью на стороне вызывающего: статическая метаинформация (title, description, expected, объявленные выходы). Динамику (status, comment, outputs) модал подтягивает из снапшота сервера при открытии — единственным источником истины остаётся серверный снапшот прогона.