fix(web-test): focus-click для reveal/scroll не должен входить в edit-mode

После focus-click перед PageDown (reveal-loop) или ArrowRight/Left (horizontal
scroll) клавиатурная навигация ломалась если click попадал в Number/Date
ячейку — она автоматически входила в edit-mode, и стрелки начинали навигацию
внутри input вместо движения по гриду.

Два изменения:

1. findFocusCellScript generic mode (без direction) теперь берёт cells[0]
   вместо cells.slice(1) — то есть первую видимую колонку. В document
   tabular sections это типично Reference (Номенклатура), которая не
   входит в edit-mode по single click. Защиту от tree-toggles оставил
   точечно: для tree-гридов (presence of .gridBoxTree) пропускаем
   первую колонку как и раньше.

2. В click-cell.mjs после focus-click в revealAndFindCell и scrollGridToCell
   добавил тот же isInputFocusedInGrid + Escape страховочный фолбек,
   что и в deleteTableRow — на случай если focus всё же попал в input.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-29 12:12:08 +03:00
parent 9766b8262e
commit 0e5ad754e8
2 changed files with 23 additions and 5 deletions
+9 -3
View File
@@ -1,4 +1,4 @@
// web-test dom/grid v1.5 — grid resolution + table reading + edit-time helpers // web-test dom/grid v1.6 — grid resolution + table reading + edit-time helpers
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
/** /**
@@ -596,12 +596,18 @@ export function findFocusCellScript(gridSelector, { rowIdx, direction } = {}) {
visible.sort((a, b) => a.r.x - b.r.x); visible.sort((a, b) => a.r.x - b.r.x);
candidates = direction === 'ArrowRight' ? [...visible].reverse() : visible; candidates = direction === 'ArrowRight' ? [...visible].reverse() : visible;
} else { } else {
// Generic focus mode: any visible cell past the first column (tree toggles). // Generic focus mode (used by reveal-loop): pick the FIRST visible cell —
// typically a Reference column (Номенклатура in документах) which doesn't
// auto-enter edit mode on click. Number/Date/String cells auto-edit and
// break subsequent PageDown navigation.
// For tree grids (presence of .gridBoxTree), skip first column to avoid
// toggling expand/collapse of the row.
const isTree = !!body.querySelector('.gridBoxTree');
const cells = [...line.children] const cells = [...line.children]
.filter(b => b.offsetWidth > 0) .filter(b => b.offsetWidth > 0)
.map(b => ({ b, r: b.getBoundingClientRect(), checkbox: !!b.querySelector('.checkbox') })); .map(b => ({ b, r: b.getBoundingClientRect(), checkbox: !!b.querySelector('.checkbox') }));
if (!cells.length) return null; if (!cells.length) return null;
candidates = cells.length > 1 ? cells.slice(1) : cells; candidates = isTree && cells.length > 1 ? cells.slice(1) : cells;
} }
const pick = candidates.find(v => !v.checkbox) || candidates[0]; const pick = candidates.find(v => !v.checkbox) || candidates[0];
if (!pick) return null; if (!pick) return null;
@@ -1,4 +1,4 @@
// web-test table/click-cell v1.1 — click a cell in a form grid by (row, column). // web-test table/click-cell v1.2 — click a cell in a form grid by (row, column).
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills // Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
// //
// Routed from core/click.mjs when the user calls clickElement({row, column}) and // Routed from core/click.mjs when the user calls clickElement({row, column}) and
@@ -22,7 +22,7 @@
import { page } from '../core/state.mjs'; import { page } from '../core/state.mjs';
import { waitForStable } from '../core/wait.mjs'; import { waitForStable } from '../core/wait.mjs';
import { modifierClick, returnFormState } from '../core/helpers.mjs'; import { modifierClick, returnFormState, isInputFocusedInGrid } from '../core/helpers.mjs';
import { scrollHorizontallyByKey } from '../core/scroll-horiz.mjs'; import { scrollHorizontallyByKey } from '../core/scroll-horiz.mjs';
import { import {
findGridCellScript, findFocusCellScript, snapshotGridScript, findGridCellScript, findFocusCellScript, snapshotGridScript,
@@ -115,6 +115,12 @@ async function revealAndFindCell({ formNum, gridSelector, target, scroll }) {
if (!focusPt) return { error: 'no_focusable_cell' }; if (!focusPt) return { error: 'no_focusable_cell' };
await page.mouse.click(focusPt.x, focusPt.y); await page.mouse.click(focusPt.x, focusPt.y);
await page.waitForTimeout(FOCUS_WAIT_MS); await page.waitForTimeout(FOCUS_WAIT_MS);
// Click on a Number/Date cell auto-enters edit mode in 1С; PageDown there
// is a no-op. Exit edit mode before driving the reveal loop.
if (await isInputFocusedInGrid({ gridSelector })) {
await page.keyboard.press('Escape');
await page.waitForTimeout(150);
}
let prevSnap = await page.evaluate(snapshotGridScript(gridSelector)); let prevSnap = await page.evaluate(snapshotGridScript(gridSelector));
for (let i = 0; i < limit; i++) { for (let i = 0; i < limit; i++) {
@@ -155,6 +161,12 @@ async function scrollGridToCell({ formNum, gridSelector, target, cell }) {
if (!focusPt) throw new Error('clickElement: no visible cell to focus for horizontal scroll'); if (!focusPt) throw new Error('clickElement: no visible cell to focus for horizontal scroll');
await page.mouse.click(focusPt.x, focusPt.y); await page.mouse.click(focusPt.x, focusPt.y);
await page.waitForTimeout(FOCUS_WAIT_MS); await page.waitForTimeout(FOCUS_WAIT_MS);
// Click on a Number/Date cell auto-enters edit mode in 1С; arrow keys there
// navigate text inside the input rather than scrolling the viewport. Exit first.
if (await isInputFocusedInGrid({ gridSelector })) {
await page.keyboard.press('Escape');
await page.waitForTimeout(150);
}
await scrollHorizontallyByKey({ await scrollHorizontallyByKey({
page, page,