From 60cdbf0aec2a3d6a8a23e1871bda4521a5fb34c2 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 25 May 2026 17:24:20 +0300 Subject: [PATCH] =?UTF-8?q?feat(web-test):=20=D0=BD=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=B8=D0=B2=D0=B0=D0=B5=D0=BC=D1=8B=D0=B9=20=D1=82?= =?UTF-8?q?=D0=B0=D0=B9=D0=BC=D0=B0=D1=83=D1=82=20=D0=BA=D0=BE=D0=BC=D0=B0?= =?UTF-8?q?=D0=BD=D0=B4=D1=8B=20exec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --timeout= / --timeout-min= и WEB_TEST_EXEC_TIMEOUT_MS вместо захардкоженных 30 мин; сообщение об ошибке строится из фактического значения. Закрывает кейс длинных записей видео с addNarration. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/skills/web-test/SKILL.md | 6 ++++++ .claude/skills/web-test/scripts/run.mjs | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.claude/skills/web-test/SKILL.md b/.claude/skills/web-test/SKILL.md index 6a1c52b2..5107a699 100644 --- a/.claude/skills/web-test/SKILL.md +++ b/.claude/skills/web-test/SKILL.md @@ -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 diff --git a/.claude/skills/web-test/scripts/run.mjs b/.claude/skills/web-test/scripts/run.mjs index d6ed3f9f..fea34cd7 100644 --- a/.claude/skills/web-test/scripts/run.mjs +++ b/.claude/skills/web-test/scripts/run.mjs @@ -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(); });