Модель может заполнять поля-списки одним значением или массивом через fillFields/
selectValue — раньше это виснет (DLB→форма «Выбор значений», safeClick по surface)
или throw «type dialog» (CB→«Список значений», ложный isTypeDialog). Статически
поле-список не отличить от обычного рефа → детекция поведенческая.
- Рефактор-шов: selectValuesMulti = открытие + dispatchMultiSurface(field,values,
{formNum,isCloudDD,baseForm}); детекторы detectMultiSurface/isValueListSurface.
- Делегация на УЖЕ открытой форме (без переоткрытия/мигания), асимметрично по пути:
DLB (fillReferenceField) — по «DLB открыл форму»; CB (одиночный selectValue, до
isTypeDialog) — по Подбор/СнятьФлажки. Обычный реф (DLB→инлайн / форма «Выбрать»
без этих кнопок) НЕ делегируется.
- fillFields: массив → selectValue(array); одиночное течёт в существующие
hasSelect/hasPick ветки (фикс внутри них).
- Фикс clearPool для платформенного пула: Ctrl+A не выделяет все строки → цикл
построчного удаления (кастомный пул с чекбоксами — через СнятьФлажки).
Регресс 25/25 (обычный реф Контрагент НЕ делегирован). Доп. кейсы в
22-multiselect-listfield. select-value v1.33, fill v1.20.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Приводим авторский контент (.ps1/.psm1/.py/.mjs/.md/.json, пин .bsl)
к единому LF и закрепляем политикой в .gitattributes. Инструмент правки
всегда пишет LF, поэтому единый LF убирает EOL-шум в диффах, ложные
срабатывания blame и налог на ручную синхронизацию CRLF-файлов.
BOM на .ps1 сохранён (git с eol=lf меняет только CR<->LF, BOM не трогает).
Данные 1С (*.xml) и бинарники под нормализацию не берём.
Гейт: PS-порт 459/459, Python-порт 459/459, web-test E2E 22/22 (с пересборкой стенда).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fillFields классифицировал поля по кнопкам: _DLB → ссылка, _CB → pick (если
класс iCalendB → дата). Числовое поле формы (напр. «Цена») имеет _CB с классом
iCalcB (калькулятор) и isDate=false, поэтому уходило в ветку selectValue, которая
ждёт форму выбора → детерминированный фейл "DLB click did not open a popup or
selection form". Калькулятор формой выбора не является.
- dom/forms.mjs: распознаём iCalcB → флаг isCalc (по аналогии с isDate/iCalendB),
пробрасываем его в resolveFieldsScript.
- engine/forms/fill.mjs: ветку paste расширяем на hasPick && (isDate || isCalc) —
калькулятор заполняем через Ctrl+A + paste + Tab, как календарь. Ссылочный
fallback (hasPick без даты/калькулятора) не тронут.
Пробел покрытия: «Цена» в наборе заполнялась только через fillTableRow (Tab-путь),
а fillFields-ветка калькулятора не гонялась. Добавлен 'Цена' в 03-fillfields.test
с assert method=paste и значением 777,00. E2E: тест 03 зелёный.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Все action-функции теперь возвращают плоский form state с extras —
закрыта последняя аномалия API. Раньше:
- fillFields → {filled, form} (вложенный, документировано в SKILL.md)
- fillTableRow → 3 разных shape в 5 ветках (array | {filled, form} | {filled, notFilled, form}),
при этом документация заявляла плоский — код её игнорировал
Теперь обе функции используют returnFormState({filled, notFilled?}) — тот же
паттерн что у всех action-функций после Phase 1+2 (clickElement, selectValue,
closeForm, filterList и т.д.).
Что закрывает:
1. Тихий баг в production-клиенте C:\WS\projects\titan\tests\helpers\query.mjs
на res.filled?.find() — array-ветки fillTableRow возвращали [{...}] без .filled
→ ошибки заполнения параметров запросов молча пропускались. R1/R2-аналог.
2. Костыли r.filled || r в tests/web-test/05-table.test.mjs (2 места) —
убраны, поскольку polymorphism устранён.
3. Расхождение код ↔ документация в fillTableRow.
4. Внутренний polymorphism в row-fill.mjs: убраны два `if (Array.isArray(more))`
костыля в рекурсивных вызовах самого fillTableRow.
Файлы:
- engine/forms/fill.mjs v1.17 → v1.18 (1 ветка → returnFormState)
- engine/table/row-fill.mjs v1.17 → v1.18 (5 веток + 2 рекурсии)
- tests/web-test/05-table.test.mjs (r.filled || r → r.filled)
- .claude/skills/web-test/SKILL.md (сигнатуры fillFields/fillTableRow + общая
ремарка про плоский return shape в начале раздела Actions)
- docs/web-test-guide.md (строки fillFields/fillTableRow/navigateSection;
общая ремарка в начале раздела «Действия»)
В тестах ни один кейс не обращался к .form.X, blast radius нулевой.
Точечный регресс (03/05/06/07/10/16) и полный регресс 19/19 — зелёные.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
getFormState — высокоуровневая операция «прочитать состояние формы»,
семантически в forms/ ближе чем в core/ (foundational плумбинг движка).
engine/core/form-state.mjs → engine/forms/state.mjs
Все 11 importer'ов обновлены. Внутри state.mjs пути исправлены:
'./state.mjs' → '../core/state.mjs', './errors.mjs' → '../core/errors.mjs'.
03-fillfields регресс зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
После полной чистки cycle-импортов в E.13 остались комментарии типа
"getFormState still in browser.mjs", которые больше не верны (он переехал
в engine/core/form-state.mjs). Сметаем устаревшие "moved to / lives in
browser.mjs" комментарии в 8 файлах.
Дополнительно в engine/table/spreadsheet.mjs:
- убраны неиспользуемые импорты readTableScript, resolveGridScript, normYo
(остались с тех пор, как readTable жил в этом файле — до этапа D.12
rename'а в grid.mjs)
- заголовочный комментарий обновлён (без упоминания readTable)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>