Commit Graph

116 Commits

Author SHA1 Message Date
Nick Shirokov cce00a4def fix(web-test): clickElement — pause before auto-clicking confirmation during recording
When video recording is active, wait 1.5s before clicking confirmation
dialog buttons so viewers can see the dialog in the video.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:42:38 +03:00
Nick Shirokov bc4ee63986 fix(web-test): clickElement button wait — CDP network monitor for early exit
Replace 10s waitForSelector timeout with CDP-based network monitoring.
For buttons that trigger server operations without producing a modal/balloon,
the old code waited the full 10s. Now it monitors actual HTTP requests via
Chrome DevTools Protocol and exits 300ms after the last request completes.

- Add startNetworkMonitor() — creates CDP session before click, tracks pending requests
- waitDone() polls for network quiet (300ms debounce) or UI element appearance
- CDP session cleaned up in finally block via cleanup()
- Add optional {timeout} parameter to clickElement for custom wait limits
- Tested: Записать ~1.9s (was ~11.5s), Записать и закрыть ~0.9s, confirmation dialogs OK

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:53:24 +03:00
Nick Shirokov a314ec32fc fix(web-test): fillFields date/time fields — paste instead of selectValue
Date fields have a CB (Choose Button) that opens a calendar, not a selection
form. fillFields detected hasPick → delegated to selectValue → error
"DLB click did not open a popup or selection form".

Fix: detect date fields by `iCalendB` CSS class on CB button (dom.mjs),
propagate `isDate` flag through field mapping, and use clipboard paste
for date fields instead of selectValue. Reference fields with CB (without
iCalendB) continue using selectValue as before.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:40:12 +03:00
Nick Shirokov baefeaa05b fix(web-test): clickElement expand:false — idempotent expand/collapse
expand:false was silently ignored because `if (expand || toggle)` evaluates
to false when expand=false. Now uses `expand != null` to enter the branch,
checks current state (gridListH/gridListV for groups, backgroundImage gx=0
for tree nodes), and only clicks when the state needs to change.

- expand:true on collapsed → expand (click)
- expand:true on expanded → noop (idempotent)
- expand:false on expanded → collapse (click)
- expand:false on collapsed → noop (idempotent)
- toggle → always click (unchanged)

Returns `toggled: true/false` in result to indicate whether click happened.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:27:40 +03:00
Nick Shirokov 2d88cdc864 fix(web-test): fillTableRow row:N — colindex matching, scroll, field sorting
Root cause: fillTableRow used child-index matching between grid header and
body cells. When headers are merged (e.g. "Бизнес-процесс источник" spanning
two body columns), header has more children than body — indices diverge,
click lands on wrong cell, fields stay empty.

Fixes:
- Use `colindex` attribute (set by 1C platform) to match header→body cells
  reliably across merged headers (cellCoords + nextCoords)
- Add `scrollIntoView()` before clicking — fills cells behind horizontal scroll
- Sort fields by colindex before processing — Tab-loop goes left→right
  regardless of field order in the passed object
- Limit F4 to tree grids only — prevents calculator popup on numeric fields
  in flat grids which breaks Tab-loop focus
- Add paste fallback in directEditForm path for plain-text/numeric fields

Tested: 12/12 automated scenarios (single/multi field, add/edit, scroll,
reverse order, mixed types, tree grid, multiple tables, checkbox).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:22:25 +03:00
Nick Shirokov 9bc0240e95 fix(web-test): take error screenshot before fetchErrorStack closes modal
Move screenshot capture to before fetchErrorStack call in the ACTION_FNS
wrapper, so the error modal is still visible on the screenshot. Skip the
duplicate screenshot in catch block when one was already taken.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:32:00 +03:00
Nick Shirokov 4cfcaaaa1c feat(web-test): auto-dismiss platform dialogs in dismissPendingErrors
dismissPendingErrors() now detects and closes leftover platform dialogs
(About, Support Info, Error Report) before checking for 1C error modals.
This prevents action functions from failing with timeouts when a stale
platform dialog blocks interaction via modalSurface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:28:01 +03:00
Nick Shirokov f9c3792528 feat(web-test): detect and close platform dialogs in getFormState/closeForm
getFormState() now returns `platformDialogs` array when platform-level
dialogs are open (About, Support Info, Error Report). These dialogs are
invisible to 1C form detection and not closeable via Escape.
closeForm() detects platform dialogs first and closes them via
_closePlatformDialogs() instead of sending Escape, returning
closedPlatformDialogs in the result.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:20:32 +03:00
Nick Shirokov 9090a81e43 feat(web-test): auto-fetch error call stack on 1C exceptions
When a 1C error modal is detected, automatically retrieve the full call
stack before throwing. Uses two strategies: Path 1 clicks the OpenReport
link for platform exceptions, Path 2 navigates hamburger → About →
Support Info for handled ВызватьИсключение errors. The stack is returned
as structured {raw, entries[{location, code}], timestamp} in the error
result. Handles unstable modal redraws with a 1.5s re-check delay.
Platform dialogs are always cleaned up via try/finally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 19:10:52 +03:00
Nick Shirokov f037324ee9 feat(web-test): expose formCount, openForms, modal in getFormState; closed in closeForm
When the open-windows tab bar is hidden in 1C settings, the model had no
way to know how many forms are open or whether a form is modal. Now
getFormState returns openForms/formCount/modal derived from DOM form
elements (independent of tab bar), and closeForm compares form number
before/after Escape to return closed: true/false.

Tested on ncc (tab bar hidden) and bpdemo (tab bar visible).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 17:23:31 +03:00
Nick Shirokov 6f36e36166 feat(web-test): per-caption voice + speechRate for multi-voice narration
- addNarration: use cap.voice override per caption (fallback to global)
- showCaption/showImage/showTitleSlide: pass opts.voice to caption entry
- showCaption: record caption when text is empty but speech is explicit
- startRecording: add speechRate option (default 70ms/char, 85 for ElevenLabs)
- run.mjs: increase exec timeout to 30min for long recordings
- docs: update recording.md and web-test-recording-guide.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:30:02 +03:00
Nick Shirokov 5b6fcc7c74 fix(web-test): normalize \u00a0 in matching, prefer exact match in clickEddItem
- normYo now replaces \u00a0 (non-breaking space) with regular space — 1C web
  client uses \u00a0 in dropdown items, causing exact match failures
- clickEddItem does two passes: exact match first, then partial — prevents
  "Системы" from matching before "Системы и бизнес-процессы"
- Same \u00a0 fix applied to all inline ny() functions in evaluate scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:35:10 +03:00
Nick Shirokov df47128994 fix(web-test): route reference fields without DLB through selectValue
Reference fields with pick button (_CB) but no dropdown button (_DLB)
were going through the plain paste path, which silently failed for
non-editable fields. Now detected via hasPick flag in resolveFieldsScript
and delegated to selectValue (F4 → selection form).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:22:44 +03:00
Nick Shirokov ea453e5c97 fix(web-test,web-publish): DLB-first approach for combobox fields, fix relative Apache paths
web-test/browser.mjs: fillReferenceField now tries DLB (DropListButton) click
before falling back to paste approach. Combobox/enum fields are filled cleanly
in one step (click dropdown → select item) instead of the old Shift+F4 → Tab →
refocus → paste flow that caused visual artifacts.

web-publish v1.1: normalize ApachePath to absolute when agent passes a relative
path like "tools/apache24", preventing Apache "Forbidden" errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:51:28 +03:00
Nick Shirokov 14b0782904 refactor(web-test): replace fade transitions with auto-cleanup of overlays
CSS fade transitions don't work well with CDP screencast (causes desktop
flash between slides). Instead, showImage/showTitleSlide now automatically
remove the other overlay type — no need to call hide before showing next.

Pattern for consecutive slides:
  showTitleSlide(...) → showImage(...) → showImage(...) → hideImage()
No hideTitleSlide() needed between title and first image.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:41:17 +03:00
Nick Shirokov b7e3bd876d feat(web-test): add fade transitions to showTitleSlide/showImage overlays
- Fade-in (300ms ease) on show: element created with opacity:0, then
  transitioned to opacity:1 via requestAnimationFrame
- Fade-out (300ms ease) on hide: opacity set to 0, wait 350ms, remove
- Applied to showTitleSlide/hideTitleSlide and showImage/hideImage
- No change to showCaption (instant appearance fits subtitle UX better)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:28:33 +03:00
Nick Shirokov b68f4145ce fix(web-test): reduce smart TTS wait from 100ms/char to 70ms/char
Measured real Edge TTS (ru-RU-DmitryNeural) durations:
  57 chars → 4.4s (77ms/char)
  72 chars → 6.0s (84ms/char)
  126 chars → 8.2s (65ms/char)
  745 chars → 48.0s (64ms/char)

Old 100ms/char overestimated by 30-55%, causing long silent pauses
after speech in showImage/showTitleSlide/showCaption. New 70ms/char
gives ~10% safety margin without excessive silence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:05:13 +03:00
Nick Shirokov dc2056a5d5 fix(web-test): resolve file paths relative to project root, not cwd
All user-facing file functions now resolve relative paths from the
project root (where .claude/ lives) instead of process.cwd().
Fixes showImage, startRecording, addNarration, openFile failing when
the skill is installed in a different project.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 20:56:11 +03:00
Nick Shirokov a4e0faaeb3 feat(web-test): add speech support to showTitleSlide
Title slides can now have TTS narration, same as showCaption/showImage.
Pass opts.speech as string for custom narration text, or true to use
the title text. Includes smart wait for video timeline sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:53:47 +03:00
Nick Shirokov 9d6ceae4f1 fix(web-test): showImage scaling and full preset improvements
- Use min-width/min-height 50% to upscale small images (was showing
  tiny 225px images at native size instead of scaling up)
- Keep max-width/max-height 92% for large images (no regression)
- Change full preset from cover to contain — no content cropping,
  black bars instead of cutting off edges

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:36:22 +03:00
Nick Shirokov 18ad662378 feat(web-test): add showImage/hideImage for displaying images during recording
Show image files (PNG, JPG, etc.) as full-screen overlays during video
recording — useful for presentation slides in video instructions.

- Read file → base64 → inject as <img> overlay (same pattern as showTitleSlide)
- Style presets: blur (default), dark, light, full
- blur: blurred+dimmed copy as background with shadow
- full: object-fit cover, fills entire screen
- TTS speech support with smart wait (same as showCaption)
- Custom background overrides preset
- Fixed no-record stubs: showImage/showTitleSlide not stubbed (visual-only)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:17:31 +03:00
Nick Shirokov bb02c1b0bd feat(web-test): clickElement support for icon-only frameButton + tumblerItem
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) <noreply@anthropic.com>
2026-03-17 19:07:59 +03:00
Nick Shirokov 46f0e6be8c fix(web-test): auto-accept native browser dialogs (confirm/alert)
1C web client uses native confirm() for scripts like vis.js file
access. Without handling, these block Playwright execution.
Added page.on('dialog') handler to auto-accept.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:34:05 +03:00
Nick Shirokov 38ccded7d9 feat(web-test): auto-load 1C browser extension for file operations
Auto-detect 1C:Enterprise browser extension from Chrome/Edge profiles
and load it via launchPersistentContext. Enables native file dialogs
(Excel import/export) without "install extension" prompt.

- findExtension() scans Chrome/Edge User Data by extension ID
- connect() uses launchPersistentContext when extension found, falls
  back to chromium.launch() otherwise
- isConnected() handles both Browser and BrowserContext objects
- Temp userDataDir cleaned on disconnect()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:09:20 +03:00
Nick Shirokov 4e0ce5ba0f fix(web-test): clickElement normalizes ё in grid row text
Grid row search in findClickTargetScript used raw innerText without
norm() — missed ё→е normalization. Target was normalized but row text
was not, so "расчётным" didn't match "расчетным".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 14:19:12 +03:00
Nick Shirokov e948d39adb fix(web-test): clickElement expand support for gridGroup in hierarchy mode
When expand/toggle is passed for gridGroup/gridParent elements,
click the .gridListH/.gridListV triangle icon to expand/collapse
in place instead of dblclick which enters the group. Without
expand, dblclick behavior is preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:27:38 +03:00
Nick Shirokov d9e7d9c107 fix(web-test): fillTableRow enum support + clickElement tab ambiguity
Three fixes:

1. fillTableRow: match cells by column header text (headerText fallback)
   when INPUT id-based fuzzy match fails due to metadata typos

2. fillTableRow: EDD filter preserves standalone enum values like "Создать"
   by only filtering "Создать элемент/группу/:" patterns (was: startsWith)

3. clickElement: coordinate-based click for tabs without ID, avoiding
   global [data-content] selector that picks invisible duplicates from
   background forms

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:39:44 +03:00
Nick Shirokov 21a0e360ef fix(web-test): fillTableRow stops Tab early when only checkboxes remain
Tab past the last cell in 1C creates extra rows. Now when all unfilled
fields are checkboxes (boolean values), the Tab loop exits immediately
instead of pressing Tab 3 more times on non-INPUT cells.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 13:04:27 +03:00
Nick Shirokov 9f5e244f68 fix(web-test): fillTableRow add+checkbox targets correct row via addedRowIdx
Tab navigation skips checkbox cells (no INPUT). After Tab fill, unfilled
checkbox fields are retried via direct click. Previously the retry hit
the wrong row because the selected row shifted after Tab/commit. Now
we record row count before "Добавить" click and use that index for the
retry, ensuring checkboxes land on the same row as the text fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:59:06 +03:00
Nick Shirokov 18a198d12b fix(web-test): fillTableRow processes remaining fields after checkbox toggle
Previously fillTableRow returned immediately after toggling the first
checkbox field, ignoring any remaining fields. Now it recursively
processes the rest on the same row.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:40:15 +03:00
Nick Shirokov 8fca42193a feat(web-test): readTable/getFormState — expose unnamed checkbox columns
Unnamed checkbox columns (no header text) now appear as "(checkbox)" in
getFormState().tables[].columns and readTable().columns. Checkbox cell
values return "true"/"false" instead of empty strings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:36:38 +03:00
Nick Shirokov b00289e62c feat(web-test): expand alias, tree expand fix, fillTableRow checkbox support
- clickElement: add `expand` option (alias for `toggle`) for tree expand/collapse
- clickElement: fallback to dblclick when tree +/- icon not found (was NumpadAdd)
- dom.mjs: search [tree="true"] in entire line, not just first imgBox
  (fixes trees with checkbox column before tree column)
- fillTableRow: detect checkbox cells after first click, return immediately
  without escalation (dblclick/F4). Checkbox state detected via .select class
- SKILL.md: document `expand` instead of `toggle`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:47:35 +03:00
Nick Shirokov 9cffa81bcc fix(web-test): --no-record stubs return proper objects in run.mjs sandbox
The real fix: run.mjs sandbox was stubbing stopRecording/addNarration as
noop (returning undefined). Now returns { file: null, duration: 0 } so
video scripts work transparently with --no-record.
Also: browser.mjs stopRecording/addNarration handle missing state gracefully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:59:30 +03:00
Nick Shirokov 6667ab38ee fix(web-test): stopRecording/addNarration return stub when not recording
Enables --no-record dry-run of video scripts without errors. stopRecording()
returns { file: null, duration: 0, size: 0 } instead of throwing, and
addNarration(null) returns a matching stub.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:36:19 +03:00
Nick Shirokov 26c5e849a5 fix(web-test): highlight groups — filter logicGroupContainer, keep _div for grids
Group search in highlight() now filters by !classList.contains('logicGroupContainer')
instead of removing _div selector entirely. This skips invisible Representation=None
groups while preserving grid/table _div elements (frameGrid) that are the actual
highlightable panels (Оргструктура, Системы, БизнесПроцессы).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 16:57:45 +03:00
Nick Shirokov ca681676b4 feat(web-test): highlight groups fix, recording auto-stop, fillField alias
- highlight(): exact match by name ignores size filter (supports Representation=None groups),
  error message lists available elements by category
- startRecording(): { force: true } option to restart if already recording
- executeScript(): auto-stop recording on script error (prevents "Already recording")
- fillField(name, value): silent alias for fillFields({ name: value })

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 15:37:21 +03:00
Nick Shirokov e3a9be0036 feat(web-test): add FormNavigationPanel support, fix --no-record server-side
1. Navigation panel: getFormState() returns `navigation` array with
   form navigation links (e.g. "Основное", "Объекты метаданных").
   clickElement() can now click navigation panel items (kind: navigation).
   DOM: `.navigationItem` inside parent `page{N}` container.

2. --no-record: move recording stub from client-side code injection to
   server-side sandbox export replacement. Stubs startRecording,
   stopRecording, addNarration, showCaption, hideCaption, showTitleSlide,
   hideTitleSlide as no-ops. Covers both direct calls and user wrappers
   like record()/finalize().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 12:10:19 +03:00
Nick Shirokov 2ce7b12c4c feat(web-test): add --no-record flag for exec, document toggle option
- exec --no-record injects no-op record() to skip video recording during
  debugging/testing
- Document clickElement { toggle: true } for tree node expand/collapse
- Document --no-record in SKILL.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 19:39:29 +03:00
Nick Shirokov 6cb54a8f96 fix(web-test): show detailed message in fillFields error instead of error code
Previously fillFields errors showed only the error code (e.g. "not_found"),
making it ambiguous whether the field or the value was not found. Now shows
the message (e.g. 'Value "X" not found') when available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 19:32:28 +03:00
Nick Shirokov 55ab172ba4 feat(web-test): clickElement on tree nodes defaults to select, toggle is explicit
Previously clickElement always toggled expand/collapse on tree nodes.
Now default = select (click text), and { toggle: true } = expand/collapse
(click tree icon). Hint in response guides the model to use toggle when needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 18:47:52 +03:00
Nick Shirokov 31792a8a2d feat(web-test): search all visible grids for clickElement row targets
Previously findClickTargetScript used querySelector (first grid only),
making clickElement unable to find rows in second+ grids on multi-grid
forms (e.g. system composition wizard). Now uses querySelectorAll to
search all visible grids, and returns gridId so the tree node handler
can locate the correct grid for expand/collapse.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 18:10:25 +03:00
Nick Shirokov 3e8a0a792f fix(web-test): skip includes() fuzzy match for short strings (< 4 chars)
Prevents false positives like "Да" matching "Удаляемые" (group) or
"КомандаУстановитьВсе" (button). Exact and startsWith still work.
Applied to highlight groups, findClickTargetScript buttons/grid-scoped/grid rows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 15:36:49 +03:00
Nick Shirokov 7a6e63078d fix(web-test): commit fillTableRow by clicking grid header instead of data row
Clicking a different data row to exit edit mode re-entered edit on that
row, blocking subsequent button clicks like "Записать". Now the add-path
commit clicks the grid header which cleanly exits edit mode without
re-entering it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:27:08 +03:00
Nick Shirokov 55b0ffa4fd fix(web-test): pass table scope to highlight in clickElement
highlight() was ignoring the table parameter, always highlighting the
first matching button (e.g. "Добавить" for Входящие instead of
Исходящие). Now clickElement passes { table } to highlight, and
highlight pre-resolves the grid via resolveGridScript to pass
gridSelector to findClickTargetScript — same pattern as clickElement
itself.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:20:12 +03:00
Nick Shirokov 21de2a4749 fix(web-test): strip dashes in fuzzy match for fillTableRow cell names
CamelCase cell IDs like "ИсходящиеБизнесПроцессПриемник" have no
dashes, but user keys like "Бизнес-процесс приемник" do. The previous
regex only stripped spaces, leaving the dash and causing match failure.
Now strip both spaces and dashes with /[\s\-]+/g in both the Tab-loop
path and the row/dblclick column-lookup path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 13:50:03 +03:00
Nick Shirokov 07be2bcafd fix(web-test): use includes instead of startsWith for grid button id-prefix fallback
Button ids like allActionsРазделыКоманднаяПанель contain gridName
in the middle, not at the start. Using includes() catches both
prefix patterns (ИсходящиеКоманднаяПанель_Добавить) and infix
patterns (allActionsРазделыКоманднаяПанель).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 12:28:50 +03:00
Nick Shirokov 24a48b4a9f fix(web-test): add Группа+name fallback for grid label extraction
On some forms, #title_div is on the parent group element
(e.g. form0_ГруппаБизнесПроцессы#title_div) rather than
on the grid itself. Add fallback lookup for both getFormState
and resolveGridScript.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 12:11:10 +03:00
Nick Shirokov 91b5204ab2 feat(web-test): add visual label support for multi-grid tables
Extract group title text from #title_div DOM elements so tables can be
referenced by their visible on-screen names (e.g. "Входящие") in addition
to technical attribute names. Labels appear in getFormState().tables[] and
resolveGridScript cascade matching (exact name → exact label → contains).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 12:05:23 +03:00
Nick Shirokov 7e56cd79db fix(web-test): skip checkbox columns in row clicks + document table parameter
Row selection clicks in deleteTableRow and fillTableRow commit now target
the second visible gridBox instead of the first, avoiding accidental
checkbox toggles on forms with checkbox columns (e.g. BP links master).

Also documents the new `table` parameter in SKILL.md for readTable,
clickElement, fillTableRow, deleteTableRow, and getFormState tables[].

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 11:48:57 +03:00
Nick Shirokov 1abc44334c feat(web-test): add table parameter for multi-grid forms
Add semantic table binding to readTable, clickElement, fillTableRow,
and deleteTableRow — resolves the correct grid by name when a form
has multiple tables (e.g. "Входящие"/"Исходящие" in BP links).

- New resolveGridScript() in dom.mjs: cascade match by gridName → columns
- findClickTargetScript: scoped button search within grid's parent container
- getFormState: reports all grids via tables[] array (table still present for compat)
- All grids[grids.length-1] fallbacks wrapped in gridSelector ternary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 11:27:37 +03:00