From 6e093517309226bee38e543a1a9eaeaec376f8aa Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 27 May 2026 15:09:24 +0300 Subject: [PATCH] =?UTF-8?q?refactor(web-test):=20returnFormState=20idem=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=B4=D1=83=D0=BF=20(Phase=202,=205=20=D1=81=D0=B0?= =?UTF-8?q?=D0=B9=D1=82=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Дедуп 5 идемпотентных хвостов action-функций — паттерн getFormState + state.X = ... + checkForErrors + if(err) state.errors = err + return сводится к одному returnFormState(extras). Поведение identical. - core/click.mjs: ветка popupItem (1 сайт) - forms/select-value.mjs: openFormAndPick helper, DLB dropdown match, DLB dropdown no-search-first, selection-form direct 3B (4 сайта) Аудит upload/returnFormState-audit.md обещал 13 idem, но при разборе: - click.mjs:final (custom confirmation/hint), close.mjs save=undefined (R3 предупреждение), 6 сайтов fillReferenceField (приватный shape {field, ok, method, value}, не form-state) — осознанно НЕ конвертированы. Реальный Phase 2 — 5 сайтов. Полный регресс 19/19 зелёный (после rebuild стенда — старый стенд накопил 22 Контрагента вместо 4 за прошлые прогоны, не связано с Phase 2). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../web-test/scripts/engine/core/click.mjs | 8 ++--- .../scripts/engine/forms/select-value.mjs | 36 ++++++------------- 2 files changed, 13 insertions(+), 31 deletions(-) diff --git a/.claude/skills/web-test/scripts/engine/core/click.mjs b/.claude/skills/web-test/scripts/engine/core/click.mjs index 2e17e604..3fee9659 100644 --- a/.claude/skills/web-test/scripts/engine/core/click.mjs +++ b/.claude/skills/web-test/scripts/engine/core/click.mjs @@ -1,4 +1,4 @@ -// web-test core/click v1.18 — clickElement dispatcher: spreadsheet cells, submenus, grid groups/trees, buttons/links, tabs. +// web-test core/click v1.19 — clickElement dispatcher: spreadsheet cells, submenus, grid groups/trees, buttons/links, tabs. // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import { @@ -90,11 +90,7 @@ export async function clickElement(text, { dblclick, table, toggle, expand, modi await page.mouse.click(found.x, found.y); } await waitForStable(); - const state = await getFormState(); - state.clicked = { kind: 'popupItem', name: found.name }; - const err = await checkForErrors(); - if (err) state.errors = err; - return state; + return returnFormState({ clicked: { kind: 'popupItem', name: found.name } }); } // No match in popup — fall through to form elements } diff --git a/.claude/skills/web-test/scripts/engine/forms/select-value.mjs b/.claude/skills/web-test/scripts/engine/forms/select-value.mjs index 78c38731..953b25cf 100644 --- a/.claude/skills/web-test/scripts/engine/forms/select-value.mjs +++ b/.claude/skills/web-test/scripts/engine/forms/select-value.mjs @@ -1,4 +1,4 @@ -// web-test forms/select-value v1.19 — Reference & composite-type value selection: selectValue, fillReferenceField, selection/type-dialog pickers. +// web-test forms/select-value v1.20 — Reference & composite-type value selection: selectValue, fillReferenceField, selection/type-dialog pickers. // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import { @@ -677,13 +677,10 @@ export async function selectValue(fieldName, searchText, { type } = {}) { const selFormNum = await detectSelectionForm(); if (selFormNum !== null) { const pickResult = await pickFromSelectionForm(selFormNum, btn.fieldName, searchText || '', formNum); - const state = await getFormState(); - state.selected = { field: btn.fieldName, search: searchText || null, method: 'form' }; - if (pickResult.error) state.selected.error = pickResult.error; - if (pickResult.message) state.selected.message = pickResult.message; - const err = await checkForErrors(); - if (err) state.errors = err; - return state; + const selected = { field: btn.fieldName, search: searchText || null, method: 'form' }; + if (pickResult.error) selected.error = pickResult.error; + if (pickResult.message) selected.message = pickResult.message; + return returnFormState({ selected }); } return null; } @@ -717,11 +714,7 @@ export async function selectValue(fieldName, searchText, { type } = {}) { // Click via evaluate to bypass div.surface overlay await clickEddItem(match.name); await waitForStable(); - const state = await getFormState(); - state.selected = { field: btn.fieldName, search: searchText, method: 'dropdown' }; - const err = await checkForErrors(); - if (err) state.errors = err; - return state; + return returnFormState({ selected: { field: btn.fieldName, search: searchText, method: 'dropdown' } }); } // No match in dropdown — try "Показать все" to open selection form @@ -755,11 +748,7 @@ export async function selectValue(fieldName, searchText, { type } = {}) { if (regularItems.length > 0) { await clickEddItem(regularItems[0].name); await waitForStable(); - const state = await getFormState(); - state.selected = { field: btn.fieldName, search: null, picked: regularItems[0].name, method: 'dropdown' }; - const err = await checkForErrors(); - if (err) state.errors = err; - return state; + return returnFormState({ selected: { field: btn.fieldName, search: null, picked: regularItems[0].name, method: 'dropdown' } }); } } @@ -773,13 +762,10 @@ export async function selectValue(fieldName, searchText, { type } = {}) { throw new Error(`selectValue: field "${btn.fieldName}" opened a type selection dialog — this is a composite-type field. Specify the type: selectValue('${btn.fieldName}', '${searchText || ''}', { type: 'ИмяТипа' })`); } const pickResult = await pickFromSelectionForm(selFormNum, btn.fieldName, searchText || '', formNum); - const state = await getFormState(); - state.selected = { field: btn.fieldName, search: searchText || null, method: 'form' }; - if (pickResult.error) state.selected.error = pickResult.error; - if (pickResult.message) state.selected.message = pickResult.message; - const err = await checkForErrors(); - if (err) state.errors = err; - return state; + const selected = { field: btn.fieldName, search: searchText || null, method: 'form' }; + if (pickResult.error) selected.error = pickResult.error; + if (pickResult.message) selected.message = pickResult.message; + return returnFormState({ selected }); } // 3C. Neither popup nor form — try F4 as last resort