Commit Graph

8 Commits

Author SHA1 Message Date
Nick Shirokov 08ea3f0806 fix(web-test): клик по строке грида на узких модальных формах подбора
clickElement по строке грида целился в центр `.gridLine`, который на узкой
модальной форме подбора со множеством колонок (≈2775px при окне ~894px) уезжал
за пределы окна → mouse.click мимо строки, выделение не менялось (clickElement
при этом рапортовал успех). Проявлялось на форме множественного выбора (F4).

Общая логика клика вынесена в `ROW_CLICK_POINT_FN` (_shared.mjs): первая видимая
текстовая ячейка строки (skip checkbox/picture, skip tree-toggle, кламп X). Фикс
применён в findClickTargetScript (forms.mjs, row-select) и переиспользован в
scanGridRowsScript (grid.mjs, дедупликация inline-блока — путь selectValue).

Регресс: новый tests/web-test/20-modal-select-row.test.mjs (RED до фикса, GREEN
после). Полный набор — 23/23.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 17:17:32 +03:00
Nick Shirokov ebdd596d4f fix(web-test): числовое поле с калькулятором (iCalcB) заполнять paste, не selectValue
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>
2026-05-31 15:08:14 +03:00
Nick Shirokov f424d2ac70 feat(web-test): фокус на поле ввода через clickElement (fallback)
clickElement как последний fallback (без table) фокусирует одноимённое
поле ввода, не меняя значение — возвращает focused:{field,id,ok}.
Закрывает пробел: клавиши F4/Shift+F4 требовали сфокусированного поля,
но штатного примитива фокуса не было.

- dom/forms.mjs: резолв input.editInput/textarea по имени/заголовку
  последним шагом findClickTargetScript; имена полей в available
- click-form.mjs: focusFormField (клик по инпуту + isInputFocused → ok)
- click.mjs: ветка диспетчера kind === field
- SKILL.md + docs/web-test-guide.md: focused в extras, пример focus→F4
- tests: 19-focus-field.test.mjs (focus/F4/регресс/негатив)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 22:02:12 +03:00
Nick Shirokov b08ee99521 refactor(web-test): извлечены grid read-helpers + cloud-popup в dom/
Новое в dom/grid.mjs (все принимают опциональный gridSelector):
- countGridRowsScript            — кол-во .gridLine в body
- isTreeGridScript               — тип grid'а (есть .gridBoxTree)
- findGridHeadCenterCoordsScript — центр .gridHead для commit-клика
- getSelectedOrLastRowIndexScript — selected row index, fallback на последний

Также:
- isInputFocusedInGrid wrapper (S1) применён в add-row "ready" поллинге
- isNotInListCloudVisibleScript (S3) применён вместо локального notInList
- clickShowAllInNotInListCloudScript — новая в dom/forms.mjs (клик
  "Показать все" в "нет в списке" cloud popup через dispatchEvent)

Метрики row-fill: 1041 → 971 LOC (−70), evaluates 17 → 10. Регресс
05/08/16/10 — зелёный.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:07:10 +03:00
Nick Shirokov 340142b0a2 refactor(web-test): извлечены DOM-скрипты dialog/picker UI из select-value
Применены shared-функции из S2 (findSearchInputScript, findNamedButton,
findCompareTypeRadio, isFormVisible). Добавлены новые для type-dialog и
picker UI:
- findPatternInputIdScript          — Pattern input id (Alt+F dialog)
- isTypeDialogScript                — OK + ValueList + "Выбор типа" title
- isNotInListCloudVisibleScript     — "нет в списке" tooltip popup
- findChildFormByButtonScript       — поиск child-form по имени кнопки
- readTypeDialogVisibleRowsScript   — visible rows + fuzzy matches в ValueList

select-value.mjs: 950 → 880 LOC (−70), inline page.evaluate 24 → 7
(планировали ≤8). Регресс 06/11/13 зелёный; полный регресс зелёный
(Checkpoint-1 пройден). 04-selectvalue auto-history шаг — pre-existing
test-isolation issue (см. S1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:38:01 +03:00
Nick Shirokov 7f7ab2f217 refactor(web-test): извлечены DOM-скрипты filter.mjs в dom/filter.mjs
Все 17 inline page.evaluate в engine/table/filter.mjs вынесены в
именованные dom-генераторы. Engine-модуль стал чистым orchestrator-ом.

Новое в dom/forms.mjs (shared с будущим S3 select-value):
- findSearchInputScript(formNum)        — поиск SearchString/ПоискаСтроки input
- findNamedButtonScript(text)           — кнопка a.press по innerText (Найти, OK)
- findCompareTypeRadioScript(form, idx) — радио CompareType#N#radio
- isFormVisibleScript(form)             — есть ли видимые элементы form{N}

Новое в dom/filter.mjs:
- findFirstGridCellCoordsScript          — координаты первой клетки грида
- findColumnFirstCellCoordsScript        — клетка по имени колонки (fuzzy header
                                           match с needDlb-fallback)
- readFieldSelectorInfoScript            — FieldSelector value + DLB coords
- pickFieldInSelectorDropdownScript      — выбор поля в FieldSelector DLB-edd
- readFilterDialogInfoScript             — Pattern id+value+isDate+isRef
- findFilterBadgeCloseScript             — × badge по имени поля
- findFirstFilterBadgeCloseScript        — × первого видимого badge (для clear-all)

Попутно: добавлен импорт readSubmenuScript (был pre-existing broken
import в Еще-fallback ветке Alt+F).

Метрики filter.mjs: 390 → 256 LOC (−134, −34%), inline page.evaluate
17 → 0. Регресс 09-filter / 02-crud / 05-table — зелёный.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:16:23 +03:00
Nick Shirokov 85003782db refactor(web-test): извлечены detect-new-form и edit-state из inline в dom/
Дедуплицированы 15 копий detect-new-form (13 в row-fill + 2 локальные
обёртки в select-value), 6 копий INPUT-focused, 4 проверки calendar/
calculator popup, 1 INPUT-focused-inside-grid.

Новое:
- dom/forms.mjs: detectNewFormScript(prev, {strict}) — объединяет broad
  и strict варианты
- dom/edit-state.mjs: isInputFocusedScript({allowTextarea}),
  isInputFocusedInGridScript, findOpenPopupScript
- helpers.mjs: переписан detectNewForm на dom-script; добавлены тонкие
  обёртки isInputFocused, isInputFocusedInGrid, findOpenPopup

Метрики row-fill: 1235 → 1065 LOC (−170), inline page.evaluate 47 → 20.
Поведение идентично; точечный регресс зелёный (02/03/05/06/10/16).
04-selectvalue auto-history шаг — pre-existing baseline issue (state-
driven, не связан с S1, воспроизводится на HEAD).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:54:36 +03:00
Nick Shirokov 71607bef99 refactor(web-test): dom.mjs распилен по dom/ (1434 → 41 LOC facade)
Внутренности movе в dom/:
- _shared.mjs — HAS_VISIBLE_MODAL_FN, DETECT_FORM_FN, DETECT_FORMS_FN, READ_FORM_FN
- forms.mjs — detectFormScript, readFormScript, findClickTargetScript, findFieldButtonScript, resolveFieldsScript
- form-state.mjs — getFormStateScript
- grid.mjs — resolveGridScript, readTableScript
- nav.mjs — readSectionsScript, readTabsScript, switchTabScript, readCommandsScript, navigateSectionScript, openCommandScript
- submenu.mjs — readSubmenuScript, clickPopupItemScript
- errors.mjs — checkErrorsScript

dom.mjs остался публичным entry-point с теми же 17 экспортами.
Регресс tests/web-test/ зелёный (19/19, 9m 22s).
2026-05-26 17:47:13 +03:00