feat(web-test): настраиваемый таймаут команды exec

--timeout=<ms> / --timeout-min=<n> и WEB_TEST_EXEC_TIMEOUT_MS вместо
захардкоженных 30 мин; сообщение об ошибке строится из фактического
значения. Закрывает кейс длинных записей видео с addNarration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-25 17:24:20 +03:00
parent cd3e50c408
commit 60cdbf0aec
2 changed files with 25 additions and 4 deletions
+6
View File
@@ -69,6 +69,12 @@ SCRIPT
# 2b. Execute without video recording (for debugging/testing)
cat script.js | node $RUN exec - --no-record
# 2c. Override exec HTTP timeout (default 30 min). Use for long scripts
# such as multi-block recordings + addNarration.
cat script.js | node $RUN exec - --timeout-min=120
cat script.js | node $RUN exec - --timeout=7200000
WEB_TEST_EXEC_TIMEOUT_MS=7200000 node $RUN exec script.js
# 3. Screenshot
node $RUN shot result.png
+19 -4
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env node
// web-test run v1.13 — CLI runner for 1C web client automation
// web-test run v1.14 — CLI runner for 1C web client automation
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
/**
* CLI runner for 1C web client automation.
@@ -33,9 +33,23 @@ const SEVERITY_RANK = { blocker: 5, critical: 4, normal: 3, minor: 2, trivial: 1
const SEVERITY_LEVELS = Object.keys(SEVERITY_RANK);
const [,, cmd, ...rawArgs] = process.argv;
const flags = { noRecord: rawArgs.includes('--no-record') };
const flags = {
noRecord: rawArgs.includes('--no-record'),
execTimeoutMs: parseExecTimeoutMs(rawArgs),
};
const args = rawArgs.filter(a => !a.startsWith('--'));
function parseExecTimeoutMs(argv) {
const DEFAULT_MS = 30 * 60 * 1000;
const flagMs = argv.find(a => a.startsWith('--timeout='));
if (flagMs) return Math.max(1, Number(flagMs.slice('--timeout='.length))) || DEFAULT_MS;
const flagMin = argv.find(a => a.startsWith('--timeout-min='));
if (flagMin) return Math.max(1, Number(flagMin.slice('--timeout-min='.length))) * 60 * 1000 || DEFAULT_MS;
const env = process.env.WEB_TEST_EXEC_TIMEOUT_MS;
if (env) return Math.max(1, Number(env)) || DEFAULT_MS;
return DEFAULT_MS;
}
switch (cmd) {
case 'start': await cmdStart(args[0]); break;
case 'run': await cmdRun(args[0], args[1]); break;
@@ -288,17 +302,18 @@ async function cmdExec(fileOrDash, flags = {}) {
const sess = loadSession();
const headers = {};
if (flags.noRecord) headers['x-no-record'] = '1';
const timeoutMs = flags.execTimeoutMs ?? 30 * 60 * 1000;
const result = await new Promise((resolve, reject) => {
const req = http.request({
hostname: '127.0.0.1', port: sess.port, path: '/exec',
method: 'POST', timeout: 30 * 60 * 1000, headers,
method: 'POST', timeout: timeoutMs, headers,
}, res => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => { try { resolve(JSON.parse(data)); } catch { reject(new Error(data)); } });
});
req.on('error', reject);
req.on('timeout', () => { req.destroy(new Error('Exec timeout (10 min)')); });
req.on('timeout', () => { req.destroy(new Error(`Exec timeout (${Math.round(timeoutMs / 60000)} min)`)); });
req.write(code);
req.end();
});