feat(web-test): status реально пингует сервер, а не верит файлу сессии

cmdStatus проверял только наличие .browser-session.json, поэтому после
падения/перезагрузки оставшийся файл читался как живая сессия (ложное
ok:true). Сервер уже отдаёт реальную живость через GET /status
(browser.isConnected()) — CLI теперь им пользуется:

- ok:true/ready:true только если сервер ответил connected:true (exit 0);
- server-unreachable (сервер мёртв, файл остался) → exit 1 + самоочистка
  stale-файла; browser-disconnected → exit 1;
- контракт кода возврата сохранён: exit 0 = живая готовая сессия.
- SKILL.md: ждать готовности поллингом status (exit 0), а не ловлей
  stdout долгоживущего start.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-16 15:06:37 +03:00
parent b81a7504ce
commit 115a966f0f
3 changed files with 29 additions and 9 deletions
+4 -2
View File
@@ -57,8 +57,10 @@ node $RUN run <url> script.js # exits when done, no session
### Interactive mode (step-by-step development)
```bash
# 1. Start session (run_in_background=true, prints JSON when ready)
node $RUN start <url>
# 1. Start session in the background — `start` stays running as the server, so don't wait on
# its stdout. Poll `status` instead: it exits 0 only once the session is loaded and live.
node $RUN start <url> # run_in_background=true
until node $RUN status >/dev/null 2>&1; do sleep 2; done # exit 0 = ready
# 2. Execute scripts against running session
cat <<'SCRIPT' | node $RUN exec -
@@ -1,14 +1,32 @@
// web-test cli/commands/status v1.0 — check session
// web-test cli/commands/status v1.1 — check session (active liveness probe)
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import { existsSync, readFileSync } from 'fs';
import { out } from '../util.mjs';
import { SESSION_FILE } from '../session.mjs';
import { SESSION_FILE, cleanup } from '../session.mjs';
export function cmdStatus() {
export async function cmdStatus() {
if (!existsSync(SESSION_FILE)) {
out({ ok: false, message: 'No active session' });
out({ ok: false, ready: false, message: 'No active session' });
process.exit(1);
}
const sess = JSON.parse(readFileSync(SESSION_FILE, 'utf-8'));
out({ ok: true, ...sess });
// The session file is written only after connect() finished, but the server process may have
// died since (crash/reboot) and left the file behind. Don't trust the file — probe the
// in-process /status endpoint for real liveness.
try {
const resp = await fetch(`http://127.0.0.1:${sess.port}/status`, { signal: AbortSignal.timeout(2000) });
const body = await resp.json();
if (body.connected) {
out({ ok: true, ready: true, ...sess });
} else {
out({ ok: false, ready: false, reason: 'browser-disconnected', ...sess });
process.exit(1);
}
} catch {
// Server unreachable → the file is stale (process gone). Self-heal by removing it so the
// next status/start reads clean.
cleanup();
out({ ok: false, ready: false, reason: 'server-unreachable', ...sess });
process.exit(1);
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env node
// web-test run v1.18 — CLI entry-point (распилено по cli/)
// web-test run v1.19 — CLI entry-point (распилено по cli/)
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
/**
* CLI runner for 1C web client automation.
@@ -59,7 +59,7 @@ switch (cmd) {
case 'exec': await cmdExec(args[0], flags); break;
case 'shot': await cmdShot(args[0]); break;
case 'stop': await cmdStop(); break;
case 'status': cmdStatus(); break;
case 'status': await cmdStatus(); break;
case 'test': await cmdTest(rawArgs); break;
default: usage();
}