mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-26 22:51:03 +03:00
feat(web-test): ловить стартовый блокер 1С вместо ложного диагноза
Когда у 1С нет свободной лицензии, клиент рисует блокирующий стартовый диалог ВМЕСТО приложения. Движок этого не видел: ждал свой маркер инициализации 60с, молча проваливался в waitForTimeout(5000) и ВОЗВРАЩАЛ УСПЕХ. Слот оставался без seanceId, а первое же обращение выдавало заведомую ложь: navigateSection: "Склад" not found. Section panel is in icon-only mode… Поймано на себе: спайки утекли сеансами → упёрлись в лимит → час гонялись за несуществующим «режимом отображения панели». Конфигом это не лечится: число свободных лицензий — не свойство стенда. Замеры дали 3, потом 1, потому что на той же машине работала параллельная сессия со своими сеансами. Предсказать нельзя — надо ловить. - waitForClientOrStartupBlock: один waitForFunction ждёт, что наступит раньше — клиент (#themesCell_theme_0) или видимый стартовый диалог (#messageBoxText). Бросает ТОЛЬКО по положительной улике: отсутствие клиента уликой не является (страница логина легитимна, поведение там не изменилось). Якоря — id, текст платформы лишь цитируется в сообщение, поэтому смена локали детект не сломает. Перед обвинением — переподтверждение через 600мс (защита от мигания при отрисовке оболочки). - openAndSettle убирает третью копию тех же трёх строк и делает обязательное: при блокировке слот НЕ должен пережить ошибку. Он регистрируется до ожидания, а ensureContext в раннере — это `if (hasContext(name)) return`, так что битый слот молча обслуживал бы все следующие тесты диалогом отказа. - test.mjs: дефолтный контекст поднимается во внешнем try, у которого только finally, а run.mjs не оборачивает cmdTest — бросок оттуда дал бы голый стек и НИКАКОГО отчёта. Теперь: строка, отчёт, освобождение сеансов, выход 1. - Кнопки диалога не нажимаем сознательно: его автозапуск по обратному отсчёту может завершить чужой сеанс на общей машине. Причина зафиксирована в тексте ошибки, чтобы это не «починили» кликом. Проверено вживую: - шаг 0 (до кода): на здоровом старте #messageBoxText не существует вовсе — ни в загруженном клиенте, ни в момент загрузки (опрос 100мс); - позитивный контроль на НАСТОЯЩЕМ отказе: бросает за 1.1–13.5с вместо 66, цитирует диалог и список сеансов, слот из реестра убран — 6/6; - негативный контроль: полный регресс 25/25, ноль ложных срабатываний; - путь connect() (exec/run/start) — клиент поднимается штатно. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
57c101ef3c
commit
9bec6171d3
@@ -1,4 +1,4 @@
|
||||
// web-test cli/commands/test v1.6 — regression test runner
|
||||
// web-test cli/commands/test v1.7 — regression test runner
|
||||
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import { existsSync, writeFileSync, mkdirSync, renameSync, copyFileSync, unlinkSync } from 'fs';
|
||||
import { resolve, dirname, basename, relative } from 'path';
|
||||
@@ -394,7 +394,21 @@ export async function cmdTest(rawArgs) {
|
||||
// Connect: create default context up front (hosts beforeAll / hooks). It is NOT permanently
|
||||
// pinned — under a maxContexts cap it becomes an LRU eviction candidate unless it is listed in
|
||||
// pinnedContexts. Register it in the LRU order.
|
||||
await ensureContext(defaultContextName);
|
||||
//
|
||||
// This one call needs its own catch: it sits in a try that has only a `finally`, and run.mjs
|
||||
// does not wrap cmdTest — so a throw here would escape as a raw stack trace and skip the
|
||||
// report entirely. A blocked startup (e.g. no free 1C licence) dooms the whole run anyway,
|
||||
// so say it once, keep the report, and leave.
|
||||
try {
|
||||
await ensureContext(defaultContextName);
|
||||
} catch (e) {
|
||||
W.write(`\n!! не удалось открыть контекст "${defaultContextName}": ${e.message}\n\n`);
|
||||
try { writeFinalReport('aborted'); } catch {}
|
||||
// process.exit skips the `finally` below, and killing the process does NOT release a 1C
|
||||
// seance — so release what we hold explicitly before leaving.
|
||||
await softDeadline(shutdownAll(), 15000, 'shutdown');
|
||||
process.exit(1);
|
||||
}
|
||||
touchLru(lruOrder, defaultContextName);
|
||||
|
||||
const ctx = buildContext({ noRecord: false });
|
||||
|
||||
Reference in New Issue
Block a user