From bb02c1b0bdfee262d9db400727d5982c65def8ad Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Tue, 17 Mar 2026 19:07:59 +0300 Subject: [PATCH] feat(web-test): clickElement support for icon-only frameButton + tumblerItem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Icon-only navigation buttons (Назад, Обновить) now match by idName fallback. Tumbler segments (Справа/Снизу/Скрыть) collected as new kind in both getFormState and findClickTarget. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/web-test/scripts/dom.mjs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/.claude/skills/web-test/scripts/dom.mjs b/.claude/skills/web-test/scripts/dom.mjs index 7a9b011d..3889952c 100644 --- a/.claude/skills/web-test/scripts/dom.mjs +++ b/.claude/skills/web-test/scripts/dom.mjs @@ -148,8 +148,17 @@ const READ_FORM_FN = `function readForm(p) { document.querySelectorAll('[id^="' + p + '"].frameButton, [id^="' + p + '"] .frameButton').forEach(el => { if (el.offsetWidth === 0) return; const text = el.innerText?.trim(); - if (!text) return; - buttons.push({ name: text, frame: true }); + const idName = el.id?.replace(p, '') || ''; + if (!text && !idName) return; + buttons.push({ name: text || idName, frame: true }); + }); + + // Tumbler items + document.querySelectorAll('[id^="' + p + '"].tumblerItem').forEach(el => { + if (el.offsetWidth === 0) return; + const text = el.innerText?.trim(); + const idName = el.id?.replace(p, '') || ''; + buttons.push({ name: text || idName, tumbler: true }); }); // Tabs — scoped to form by checking ancestor IDs @@ -664,8 +673,16 @@ export function findClickTargetScript(formNum, text, { tableName, gridSelector } // Frame buttons [...document.querySelectorAll('[id^="' + p + '"] .frameButton, [id^="' + p + '"].frameButton')].filter(el => el.offsetWidth > 0).forEach(el => { const text = norm(el.innerText); - if (!text) return; - items.push({ id: el.id, name: text, label: '', kind: 'frameButton' }); + const idName = el.id.replace(p, ''); + if (!text && !idName) return; + items.push({ id: el.id, name: text || idName, label: text ? '' : idName, kind: 'frameButton' }); + }); + + // Tumbler items (toggle switch segments) + [...document.querySelectorAll('[id^="' + p + '"].tumblerItem')].filter(el => el.offsetWidth > 0).forEach(el => { + const idName = el.id.replace(p, ''); + const text = norm(el.innerText); + items.push({ id: el.id, name: text || idName, label: idName, kind: 'tumbler' }); }); // Checkboxes (div.checkbox) — match by label or internal name