From ebdd596d4f059c18f9a9fc95bef6263aed55351d Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 31 May 2026 15:08:14 +0300 Subject: [PATCH] =?UTF-8?q?fix(web-test):=20=D1=87=D0=B8=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=B5=20=D1=81=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BA=D1=83=D0=BB=D1=8F=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=BC=20(iCalcB)=20=D0=B7=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D1=8F=D1=82=D1=8C=20paste,=20=D0=BD=D0=B5=20selectValue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .claude/skills/web-test/scripts/dom/forms.mjs | 4 +++- .claude/skills/web-test/scripts/engine/forms/fill.mjs | 7 ++++--- tests/web-test/03-fillfields.test.mjs | 6 +++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.claude/skills/web-test/scripts/dom/forms.mjs b/.claude/skills/web-test/scripts/dom/forms.mjs index d4a95e5d..d309764f 100644 --- a/.claude/skills/web-test/scripts/dom/forms.mjs +++ b/.claude/skills/web-test/scripts/dom/forms.mjs @@ -1,4 +1,4 @@ -// web-test dom/forms v1.5 — form detection, content read, click-target/field-button resolution +// web-test dom/forms v1.6 — form detection, content read, click-target/field-button resolution // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import { DETECT_FORM_FN, READ_FORM_FN } from './_shared.mjs'; @@ -331,6 +331,7 @@ export function resolveFieldsScript(formNum, fields) { if (cbEl?.offsetWidth > 0) { last.hasPick = true; if (cbEl.classList.contains('iCalendB')) last.isDate = true; + else if (cbEl.classList.contains('iCalcB')) last.isCalc = true; } allFields.push(last); }); @@ -411,6 +412,7 @@ export function resolveFieldsScript(formNum, fields) { if (found.hasSelect) entry.hasSelect = true; if (found.hasPick) entry.hasPick = true; if (found.isDate) entry.isDate = true; + if (found.isCalc) entry.isCalc = true; if (found._dcsCheckbox) { entry.dcsCheckbox = { inputId: found._dcsCheckbox.inputId, checked: found._dcsCheckbox.checked }; delete found._dcsCheckbox; diff --git a/.claude/skills/web-test/scripts/engine/forms/fill.mjs b/.claude/skills/web-test/scripts/engine/forms/fill.mjs index bada6f2c..b8bfd5e4 100644 --- a/.claude/skills/web-test/scripts/engine/forms/fill.mjs +++ b/.claude/skills/web-test/scripts/engine/forms/fill.mjs @@ -1,4 +1,4 @@ -// web-test forms/fill v1.18 — Fill form fields by name (text/checkbox/date/dropdown/reference). Delegates references to selectValue / fillReferenceField. +// web-test forms/fill v1.19 — Fill form fields by name (text/checkbox/date/number/dropdown/reference). Delegates references to selectValue / fillReferenceField. // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import { @@ -95,8 +95,9 @@ export async function fillFields(fields) { // Combobox/reference with DLB: DLB-first, then paste fallback const refResult = await fillReferenceField(selector, r.field, fields[r.field], formNum); results.push(refResult); - } else if (r.hasPick && r.isDate) { - // Date/time field with calendar CB — use paste (calendar is not a selection form) + } else if (r.hasPick && (r.isDate || r.isCalc)) { + // Date/time (calendar CB) or numeric (calculator CB) field — use paste: + // the pick button is a calendar/calculator widget, not a selection form. await page.click(selector); await page.waitForTimeout(200); await page.keyboard.press('Control+A'); diff --git a/tests/web-test/03-fillfields.test.mjs b/tests/web-test/03-fillfields.test.mjs index 119d7cca..318541b4 100644 --- a/tests/web-test/03-fillfields.test.mjs +++ b/tests/web-test/03-fillfields.test.mjs @@ -15,7 +15,8 @@ export default async function({ navigateSection, openCommand, clickElement, fill const result = await fillFields({ 'Артикул': 'TEST-001', 'Активен': false, // Boolean → CheckBoxField, toggle - 'ДатаПоступления': '15.05.2026', // date + 'ДатаПоступления': '15.05.2026', // date → CB iCalendB calendar, paste + 'Цена': '777', // Number → CB iCalcB calculator, paste 'ВидНоменклатуры': 'Услуга', // EnumRef dropdown }); @@ -23,11 +24,14 @@ export default async function({ navigateSection, openCommand, clickElement, fill for (const f of result.filled) { assert.ok(f.ok, `fillField "${f.field}" должен вернуть ok=true`); } + assert.equal(result.filled.find(f => f.field === 'Цена')?.method, 'paste', + 'Цена через paste (калькулятор ≠ форма выбора)'); const state = await getFormState(); assert.equal(findField(state, 'Артикул')?.value, 'TEST-001', 'Артикул text'); assert.equal(findField(state, 'Активен')?.value, false, 'Активен checkbox=false'); assert.equal(findField(state, 'ДатаПоступления')?.value, '15.05.2026', 'ДатаПоступления'); + assert.equal(findField(state, 'Цена')?.value, '777,00', 'Цена записалась (1С форматирует → 777,00)'); assert.equal(findField(state, 'ВидНоменклатуры')?.value, 'Услуга', 'ВидНоменклатуры dropdown'); await closeForm({ save: false });