resetState молча сдавался: крутил 10 попыток closeForm, игнорировал их
результат и ничего не возвращал. Контекст с чужой открытой формой уходил в
пул как «чистый», следующий тест кликал в него (заявка пилота: Сц.3 роняет
форму → Сц.5 падает на чужой).
- resetState возвращает вердикт {clean, attempts, form, title, modal}. «Чисто»
определяется не как «форм нет» (form == null — верно только для пустого
стола), а как «закрывать нечего»: closeForm.nothingToClose. Замерено на
стенде пилота — рабочий стол там это form=5, formCount=3, openForms=[5,6,7],
и старое правило объявляло бы чистый контекст грязным ПОСЛЕ КАЖДОГО теста
(clean:false за 8.7с). Теперь clean:true за 0.9с, одна итерация вместо десяти.
- resetOrAbort читает вердикт: не clean → !-строка с именем оставшейся формы +
abortContext. Ровно логика, уже работавшая для пробоя дедлайна.
- Диагностика буферизуется и печатается ПОД строкой своего теста: cleanup идёт
до записи результата, поэтому раньше !-строки вставали над тестом и
приписывались предыдущему (на этом купилась и сама сессия).
- Ранний выход по closed:false НЕ вводим: A/B на живом наборе показал, что
грязная «Приходная накладная» отдаёт closed:false на первой попытке и
закрывается на следующей — выход прерывал бы контекст зря.
Проверено: контракт стабом 5/5; на стенде пилота ложное срабатывание снято
(8.8с→0.9с), стопка форм разбирается до стола; полный регресс 25/25, ноль
строк «not clean» (было две — «Тестовые ошибки»).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Раннер регресса теперь держит пул 1С-сеансов сам, вместо накопления контекстов
между тестами и ручного закрытия в хуках. Три необязательных поля webtest.config.mjs
(без них поведение прежнее):
- maxContexts — потолок одновременно живых сеансов (null = без лимита);
- contextPolicy — 'reuse' (держать открытыми в пределах лимита) | 'strict'
(закрывать non-pinned контексты теста сразу после него);
- pinnedContexts — не вытесняются LRU (default = [defaultContext]; [] делает
default вытесняемым на тесном стенде).
Перед setup каждого теста LRU-вытеснение освобождает слот под нужды теста;
уже открытые нужные контексты переиспользуются. Default больше не вечно-pinned.
Исчерпание пула даёт внятную ошибку вместо маскирующего «Browser not connected».
- new: cli/test-runner/context-pool.mjs — чистый планировщик planEviction + LRU.
- cli/commands/test.mjs (v1.4): парсинг/валидация полей, вытеснение с фолбэк-парковкой
на нужный контекст (нельзя закрыть единственный активный), strict-закрытие, LRU-трекинг.
- Доки: regression-spec (§7/§8/глоссарий), regression-guide (рецепт), regress.md.
- Регресс дай-фудит фичу: 14-multi-context-routing роутит в 3-й контекст c,
15-multi-context-handover проверяет вытеснение c на границе; конфиг maxContexts:2.
Юнит-краёв планировщика — в debug/ (gitignored). Live-регресс: 25/25 зелёных.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Привод контракта `run.mjs test` к общей практике (pytest/jest/playwright):
- позиционные аргументы = пути к тестам, можно несколько
(`test a.test.mjs b.test.mjs dir/`); discoverTests объединяет, дедуплицирует,
сортирует (порядок по числовым префиксам сохраняется);
- URL переехал из первого позиционного во флаг --url= (по умолчанию из
webtest.config.mjs) — раньше url-первым путал: второй путь уходил в page.goto()
и падал с криптовым 'Cannot navigate to invalid URL';
- fail-fast: несуществующий путь → понятная ошибка вместо падения goto;
аргумент, похожий на URL, подсказывает про --url=.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>