From 9eb9571e9577d21865109463e437ba32375c6ef8 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 24 Jun 2026 13:22:31 +0300 Subject: [PATCH] =?UTF-8?q?fix(web-test):=20fillTableRow=20=E2=80=94=20?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=BD=D0=B8=D0=B9=20=D0=B2=D1=8B=D1=85=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=D1=81=D0=B5?= =?UTF-8?q?=D1=85=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B9=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tab-цикл не выходил сразу после заполнения последнего поля: ветки заполнения по составному типу и по примитиву делали continue без проверки «все поля закрыты», и цикл протабывал остаток строки до wrap-around. На широких строках с объединёнными колонками (составной субконто) это заметно «бежало» табами до конца строки — холостые итерации + риск ухода фокуса/создания лишней строки. - row-fill v1.24: единая проверка в начале итерации `if (every filled) break`. Значение последнего поля к этому моменту уже зафиксировано (commit-Tab примитива, выбор из формы, либо end-of-row commit для choice-ячейки). - 05-table: guard на количество строк после составного фила. Проверено: полный регресс web-test 22/22; вживую на широкой ТЧ с составным субконто — лишний хвост табов устранён. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/web-test/scripts/engine/table/row-fill.mjs | 8 +++++++- tests/web-test/05-table.test.mjs | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.claude/skills/web-test/scripts/engine/table/row-fill.mjs b/.claude/skills/web-test/scripts/engine/table/row-fill.mjs index 26387d50..226438f7 100644 --- a/.claude/skills/web-test/scripts/engine/table/row-fill.mjs +++ b/.claude/skills/web-test/scripts/engine/table/row-fill.mjs @@ -1,4 +1,4 @@ -// web-test table/row-fill v1.23 — fillTableRow — заполнение строки табличной части/списка через Tab-навигацию и попутный выбор значений. +// web-test table/row-fill v1.24 — fillTableRow — заполнение строки табличной части/списка через Tab-навигацию и попутный выбор значений. // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import { @@ -515,6 +515,12 @@ export async function fillTableRow(fields, { tab, add, row, table, scroll } = {} let firstCellId = null; for (let iter = 0; iter < MAX_ITER; iter++) { + // All requested fields filled → stop. Без этого цикл табает дальше до wrap-around + // (обходит остаток строки впустую): ветки заполнения по составному типу/примитиву + // не выходили сами, что особенно заметно на широких строках (субконто/проводки). + // Значение последнего поля к этому моменту уже зафиксировано (commit-Tab примитива, + // выбор из формы, либо end-of-row commit для choice-ячейки). + if ([...pending.values()].every(p => p.filled)) break; // Read focused element (INPUT or TEXTAREA inside grid = editable cell) const cell = await page.evaluate(readActiveGridCellScript()); diff --git a/tests/web-test/05-table.test.mjs b/tests/web-test/05-table.test.mjs index 59688c69..3f669a7e 100644 --- a/tests/web-test/05-table.test.mjs +++ b/tests/web-test/05-table.test.mjs @@ -140,9 +140,12 @@ export default async function({ navigateSection, openCommand, clickElement, fill assert.ok(item?.ok, `ячейка Источник заполнена без ошибки: ${item?.error || ''} ${item?.message || ''}`); const t = await readTable({ table: 'Товары' }); - log(`Источник cell='${t.rows[0]?.['Источник']}'`); + log(`Источник cell='${t.rows[0]?.['Источник']}' rows=${t.rows.length}`); assert.equal(t.rows[0]?.['Источник'], 'Север', 'exact-preference + клик в видимую ячейку: выбран точный «Север», не «ООО Север»'); + // Guard: после составного фила цикл не должен табать дальше до создания лишней + // строки (раньше ветка type→форма не выходила по «всё заполнено»). + assert.equal(t.rows.length, 1, 'ровно одна строка — лишние табы не создали пустую'); await closeForm({ save: false }); });