Commit Graph

56 Commits

Author SHA1 Message Date
Nick Shirokov 6958cc558b perf(web-test): detect .confirm notification for early exit in clickElement
Add .confirm CSS selector to the server-response waitForSelector in
clickElement. 1C web client shows notifications (Изменение/Проведение)
as .confirm elements after write/post operations. This allows early
exit instead of waiting the full 10s timeout. Записать: 14s → 2.6s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:58:21 +03:00
Nick Shirokov 8a286d7191 perf(web-test): skip 10s server-wait for grid edit buttons in clickElement
When clicking toolbar buttons like "Добавить" that put focus into a grid
INPUT cell, skip the 10-second waitForSelector for modal/balloon since
no server round-trip is expected. Also replace fixed waits with polling
in fillTableRow add/row paths. Total: 121s → 62s on composite test suite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:44:52 +03:00
Nick Shirokov a5fa730747 perf(web-test): replace fixed waits with polling in type-direct flow
Replace hardcoded waitForTimeout calls with polling loops that check
DOM state and exit early. Saves ~12s on composite-type test suite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:33:02 +03:00
Nick Shirokov 53219cae6c fix(web-test): handle calculator/calendar popups and type inheritance in fillTableRow
When filling composite-type cells (String+Number+Date), the previous code
tried paste first and only fell back to type selection if paste was rejected.
This failed when rows inherited a type from previous rows — paste succeeded
but the value was silently converted to the wrong type.

Now when { value, type } is specified:
1. Always clear the cell first (Shift+F4) to reset inherited type
2. Open type dialog (F4) and select the requested type
3. Dismiss calculator/calendar popups with Escape
4. Re-enter edit mode if focus was lost, then paste the value

Tested with primitive types (Число/Строка/Дата) and reference types
(Физическое лицо via selection form). Regression-tested existing
composite-type flow in Операции.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:16:37 +03:00
Nick Shirokov b1187865ec feat(web-test): support composite-type fields in fillTableRow
Cells accepting multiple types (e.g. subconto on account 80.01) now
handled via { value, type } syntax. Paste rejection detected
automatically — F4 opens type dialog, picks type, then selects value
from the catalog form.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:18:27 +03:00
Nick Shirokov 22bf17ee00 feat(web-test): support per-field search in selectValue via object syntax
selectValue now accepts search as object { field: value } for per-field
disambiguation in selection forms. All fields use advanced search (Alt+F)
by specific column — more efficient than simple full-text search on large
tables, and navigates to exact row even in virtual grids.

Also fixes filterList modal cleanup: now checks specific dialog form
instead of generic modalSurface, preventing accidental closure of
parent modal forms (e.g. selection forms).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:59:07 +03:00
Nick Shirokov 2e0dcb773b fix(web-test): detect ambiguous type matches in selectValue
When multiple types match the search term in the type selection dialog,
throw a descriptive error listing all matches instead of silently
picking the first one. This prevents the model from getting a misleading
"not found" error when the wrong type was selected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:08:35 +03:00
Nick Shirokov c958f3f818 feat(web-test): support composite-type fields in selectValue
Add `{ type }` option to selectValue for fields that accept multiple
types (e.g. DocumentRef.*). When specified, selectValue navigates
through the type selection dialog via Ctrl+F search before opening
the value selection form. Auto-detects composite fields when type
is not specified and throws a helpful error message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:51:08 +03:00
Nick Shirokov 684e97e518 docs(web-test): document icon-only section panel limitation
navigateSection() now gives a clear error message when the section
panel is in icon-only mode instead of a confusing "not found" error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 15:09:16 +03:00
Nick Shirokov 90b3d5d2e9 fix(web-test): require Message element for confirmation detection
Forms with multiple buttons but no form{N}_Message element were
falsely detected as confirmation dialogs. Real 1C confirmations
(Да/Нет) always have a Message element. Now skip forms without it.

Fixes false positives on small EPF forms with custom buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:29:57 +03:00
Nick Shirokov 8b0664b18d fix(web-test): avoid confusing small EPF form with info dialog in openFile
Check form change before checkForErrors() to prevent misidentifying
a small EPF form (< 20 elements) as an informational modal dialog.
Only call checkForErrors() on suspiciously tiny new forms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:19:24 +03:00
Nick Shirokov 2af73d25bf fix(web-test): handle follow-up info dialog after security confirmation in openFile
After clicking "Да" on the security confirmation, check for a second
informational modal ("please re-open the file"). If present, dismiss it
and retry the full Ctrl+O → filechooser cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:17:33 +03:00
Nick Shirokov 449e2f667e feat(web-test): add openFile() for opening external processors (EPF/ERF)
Opens EPF/ERF files via Ctrl+O → 1C file dialog → native file picker.
Handles security confirmation dialog with up to 2 attempts for re-open.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:11:43 +03:00
Nick Shirokov e23a235ffa fix(web-test): limit ElevenLabs TTS concurrency to 2 and improve error logging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 12:10:01 +03:00
Nick Shirokov 5bccca2475 feat(web-test): add ElevenLabs TTS provider
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:15:36 +03:00
Nick Shirokov 050d42a457 fix(web-test): use video-time timestamps for precise TTS sync
Caption timestamps now use actual video timeline position (frame
counter) instead of wall-clock time, eliminating sync drift from
non-uniform frame duplication in CDP screencast recordings.

Also replace silence-file concatenation with adelay+amix for
sample-accurate TTS placement, and fix exec timeout for long
scenarios (fetch → http.request with 10min timeout).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:13:32 +03:00
Nick Shirokov 5acb586bbf fix(web-test): fix audio-video sync drift in narration
Screencast frame duplication (Math.round) causes video to be ~5% longer
than wall-clock time. Caption timestamps are wall-clock based, so the
audio track drifted ahead by ~8s at the midpoint of a 5-minute video.

Fix:
- stopRecording() saves recordingDuration in captions.json
- addNarration() reads actual video duration via ffprobe and scales
  caption timestamps by videoDuration/recordingDuration ratio
- Phase 2 timeline now tracks actual cumulative position instead of
  computing gaps from previous caption data (prevents MP3 frame
  quantization drift)
- Also fixed findFfmpeg() → resolveFfmpeg() call in addNarration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:45:30 +03:00
Nick Shirokov 7f6ea32533 refactor(web-test): add resolveEdgeTts() with fallback chain
Mirrors resolveFfmpeg() pattern: tries global/project-level import
first, then tools/tts/node_modules/, then throws error with install
instructions. Caches resolved module for subsequent calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 00:03:16 +03:00
Nick Shirokov e9b53505ac fix(web-test): move TTS to tools/tts/, use atempo instead of trimming
- node-edge-tts installed in tools/tts/ (alongside tools/ffmpeg/)
- Speed up TTS with ffmpeg atempo when it exceeds gap to next caption,
  instead of hard-cutting the audio

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:46:50 +03:00
Nick Shirokov 6ce36f7d9b fix(web-test): resolve node-edge-tts from tools/node_modules
Dynamic import needs file:// URL on Windows and explicit entry point
for ESM resolution. Package installed in tools/ alongside ffmpeg.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:29:56 +03:00
Nick Shirokov a13f16e49d feat(web-test): add TTS narration for video recordings
showCaption() collects captions with optional speech parameter,
stopRecording() saves .captions.json, addNarration() generates
TTS voiceover (Edge TTS or OpenAI) and merges audio with video.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:10:37 +03:00
Nick Shirokov 26ea09e2ff fix(web-test): correct video color range for H.264 players
JPEG full range (0-255) was tagged as pc/full in H.264 output, but most
players (VLC, etc.) expect limited range (16-235). Convert JPEG→limited
with scale filter and tag as tv. Also switch preset ultrafast→fast for
5-6x smaller files on static screen content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:05:32 +03:00
Nick Shirokov 98c416b5a7 fix(web-test): highlight commands before form elements
When the function panel is open over a form, highlight() was finding
buttons from the hidden form instead of visible commands on the panel.
Move command search (cmd_XXX_txt) to step 1 — before form-scoped
search — so visible panel commands always take priority. Form elements
searched at step 2 only if no command matched.

Highlight search order is now:
0. Open submenu/popup (elementFromPoint overlay)
1. Commands on function panel (visible cmd_ elements)
2. Form elements (buttons, fields, grid rows)
3. Sections (sidebar navigation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:14:26 +03:00
Nick Shirokov 98ece6206e fix(web-test): add startsWith matching to findClickTargetScript
The button/link search in findClickTargetScript jumped from exact
to includes matching, causing "Поступление" to match "Поступление
билетов" instead of "Поступление (акты, накладные, УПД)" when the
shorter name appeared first in DOM order. Add startsWith step for
both name and label between exact and includes matching.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:03:34 +03:00
Nick Shirokov 7c10e5e4b1 fix(web-test): highlight submenu items and command startsWith matching
- Add submenu/popup as priority 0 in highlight() — checks open
  popups before form search, preventing false matches on grid rows
  behind the popup overlay
- Use elementFromPoint + direct overlay for submenu items instead
  of getElementById (1C duplicates IDs in cloud popups — hidden
  copy in form + visible copy in cloud)
- Add startsWith step between exact and includes for section and
  command matching — fixes "Поступление" matching "Поступление
  билетов" instead of "Поступление (акты, накладные, УПД)"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:06:20 +03:00
Nick Shirokov 0fec18bbc4 fix(web-test): unhighlight fillFields before Tab, not after
Move unhighlight() before the fill action in fillFields — prevents
our overlay staying visible while platform focus moves to next field
on Tab/Enter. Consistent with clickElement/selectValue pattern:
highlight → wait → unhighlight → action.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:34:06 +03:00
Nick Shirokov cc751a344e fix(web-test): fix highlight bugs — search priority, modal overlap, section/command support
- Reorder highlight() search: form elements first, sections/commands as
  fallback. Fixes false match where "ОК" matched section "Покупки" via
  substring .includes() ("пок" contains "ок")
- Unhighlight before action in clickElement/selectValue (was only in
  finally block, causing overlay to cover modals opened by the click)
- Add auto-highlight support to navigateSection and openCommand

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:26:49 +03:00
Nick Shirokov f956749e1e feat(web-test): add element highlighting for video recordings
Add highlight/unhighlight/setHighlight/isHighlightMode functions.
Overlay div tracks element position via requestAnimationFrame — follows
layout shifts from async banner loads. Search order: sections → commands
→ buttons/links → fields → grid rows. Auto-highlight mode integrates
with clickElement, fillFields, selectValue.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:47:29 +03:00
Nick Shirokov 2a6f4b1d5f fix(web-test): correct video brightness via color_range flag
JPEG frames from CDP screencast use full range (0-255) but H.264
defaults to limited range (16-235). Add -color_range pc to preserve
full range in output MP4, fixing washed-out/bright appearance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:32:39 +03:00
Nick Shirokov bb07bfae14 feat(web-test): add showTitleSlide/hideTitleSlide for video intros
Full-screen overlay with gradient background, centered title text,
optional subtitle. Useful for intro/outro frames in video recordings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:50:25 +03:00
Nick Shirokov d5fa5349d4 fix(web-test): ё/е normalization, DLB intercept fix, throw on errors
Three improvements to browser automation reliability:

1. ё→е normalization: fuzzy matching now treats ё and е as equivalent
   across all comparison points in both dom.mjs (norm() functions,
   target variables) and browser.mjs (popup, radio, EDD, grid, confirmation
   dialog, advanced search, filter badges). Prevents silent failures when
   script uses ё but 1C displays е or vice versa.

2. DLB intercept handling in selectValue(): added force click + Escape
   fallback when funcPanel overlay blocks the dropdown button click,
   matching the pattern already used in clickElement().

3. Error handling: all exported functions now throw Error instead of
   returning { error } objects. Error messages include function name,
   what was searched, and available alternatives. Scenarios fail fast
   at the broken step; interactive callers can use try/catch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 10:33:19 +03:00
Nick Shirokov 99a5c7168a fix(web-test): real-time video playback via frame duplication
CDP screencast sends frames only on screen changes, causing ffmpeg
to compress pauses and produce sped-up video. Now duplicates the
previous frame to fill timing gaps, maintaining real-time speed.
Also add *.mp4 to .gitignore alongside *.png.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:30:46 +03:00
Nick Shirokov 751a6a8f12 fix(web-test): update ffmpeg download links and clarify prerequisites
Use direct gyan.dev URL instead of generic ffmpeg.org. Rewrite recording.md
prerequisites as clear alternatives (project / global / config).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:04:31 +03:00
Nick Shirokov 43a2691d6a feat(web-test): add video recording via CDP screencast + ffmpeg
New functions: startRecording, stopRecording, isRecording, showCaption, hideCaption.
Recording guide in recording.md with setup, API, examples, troubleshooting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 20:49:47 +03:00
Nick Shirokov e6da514b67 chore(web-test): add source header comments to all scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:32:39 +03:00
Nick Shirokov d6befb0dc8 feat(web-test): DCS report settings — human-readable labels for fillFields/selectValue/getFormState
fillFields({ 'Склад': 'value' }) now auto-resolves via DCS pair label
and auto-enables the checkbox. getFormState() returns reportSettings
array with readable names instead of raw КомпоновщикНастроек... fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 17:05:16 +03:00
Nick Shirokov 5120b135f5 fix(web-test): use e1cib/app/ for reports and data processors
Reports and DataProcessors need e1cib/app/ prefix (opens app form),
while lists/registers/catalogs use e1cib/list/ (opens list form).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:38:21 +03:00
Nick Shirokov 5d18bf4501 fix(web-test): scope readSpreadsheet to current form, improve headers
Two fixes:
- Scope iframe scanning to current form container (prevents reading
  stale data from other open report tabs)
- Improved header detection: use LAST row before data as detail header,
  previous row as group header with fill-forward for merged cells.
  Fixes two-level headers like "Начальный остаток / Долг клиента"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:34:42 +03:00
Nick Shirokov 366378c4b5 feat(web-test): structured readSpreadsheet with header detection
Parse SpreadsheetDocument into { title, meta, headers, data, totals }:
- Auto-detect header row (most non-empty before first numeric row)
- Group header prefix for duplicate column names (Сейчас/Доступно)
- Data rows as objects {column: value}, only non-empty cells
- Separate totals row (Итого/Всего)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:17:40 +03:00
Nick Shirokov 56203e2b71 feat(web-test): add readSpreadsheet() for extracting report data
Reads 1C SpreadsheetDocument (report output) rendered in iframes.
Collects cells from div[x]/div[y] elements across all frames,
returns { rows: string[][], total }.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:07:19 +03:00
Nick Shirokov a17a81fe98 feat(web-test): normalize navigateLink URLs
- Auto-prepend e1cib/list/ when missing
- Translate English type names to Russian (AccumulationRegister → РегистрНакопления, etc.)
- Accepts: full e1cib/..., short Тип.Имя, or English Type.Имя

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:46:30 +03:00
Nick Shirokov e58f5c1f82 feat(web-test): add navigateLink() for direct 1C navigation links
- navigateLink(url): opens form via Shift+F11 dialog with clipboard paste
- Grant clipboard-read/write permissions on browser context creation
- Register navigateLink in ACTION_FNS for auto-error detection
- Document in SKILL.md with examples (e1cib/list/...)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:37:58 +03:00
Nick Shirokov 68fd9bb4a7 feat(web-test): closeForm({ save }) auto-handles confirmation dialog
closeForm now accepts { save: true/false } option:
- save: false → clicks "Нет" on "Save changes?" dialog
- save: true  → clicks "Да" to save and close
- undefined   → returns confirmation as hint (previous behavior)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:06:19 +03:00
Nick Shirokov e18e8cd284 fix(web-test): auto-dismiss pending error modals before actions
Action functions now call dismissPendingErrors() at start, so a leftover
error modal from a previous operation doesn't block subsequent actions.
Diagnostic functions (getFormState, screenshot) are unchanged — they
show current state as-is.

Key fixes:
- Target OK button within modal's form container (#formN_container)
  to avoid clicking wrong pressDefault on the page
- Use force:true click to bypass #modalSurface pointer intercept
- Replace local dismissErrors() in fillReferenceField with shared fn

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 15:02:29 +03:00
Nick Shirokov 5ea6414585 fix(web-test): detect modal errors without #modalSurface dependency
1C platform shows some modal dialogs (e.g. "Не удалось записать") via
ps*win floating windows WITHOUT setting #modalSurface visible. Removed
the modalSurface gate from checkErrorsScript — now scans all small forms
for button patterns regardless of overlay state. The elCount > 100
threshold already filters content forms reliably.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:57:18 +03:00
Nick Shirokov 75558fe46c fix(web-test): detect server-side errors via waitForSelector and ancestry-based button grouping
Two problems solved:
1. Server-side exceptions (ВызватьИсключение in ПередЗаписью) produce modal dialogs
   AFTER the DOM stabilizes. clickElement now uses waitForSelector with MutationObserver
   (doesn't block JS event loop) to detect #modalSurface or .balloon appearance.
2. checkErrorsScript used button IDs to determine form ownership, but 1C modal dialog
   buttons often have empty IDs. Now uses closest('[id$="_container"]') ancestry to
   group pressButtons by form, correctly separating modal buttons from background form
   buttons (e.g. "Зачет оплаты" in ERP order form).

Tested with ТестОшибки CFE extension on ERP — error detected in 7.7s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:28:23 +03:00
Nick Shirokov 90ca2a7c4a feat(web-test): auto-detect 1C errors and stop script execution
Action functions (clickElement, fillFields, selectValue, etc.) are now
wrapped to check for 1C errors (modal dialogs, validation balloons)
after each call. When detected, execution stops immediately with full
diagnostic context:

- error: human-readable 1C error message
- step: which API function triggered the error
- stepArgs: arguments passed to that function
- onecErrors: raw balloon/messages/modal data from DOM
- formState: complete form state at the moment of error
- screenshot: auto-captured error-shot.png

This enables autonomous scripts (run mode) to fail fast with enough
information for the caller (agent or human) to diagnose and decide on
corrective action.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:15:17 +03:00
Nick Shirokov ebda3e6608 feat(web-test): add autonomous run command
`node run.mjs run <url> <script>` — connect, execute, disconnect in one
call. No HTTP server, no session management. Process exits when done.

Useful for CI, subagents, and standalone test scenarios where the full
start/exec/stop lifecycle is unnecessary overhead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:05:34 +03:00
Nick Shirokov 328cb60f18 fix(web-test): strict search input detection in selection forms
Selection forms without a search field (e.g. ERP Соглашения) have only
filter fields like ТипСоглашения. The old code fell back to inputs[0],
typing the search text into the filter field and breaking the form.

Now pickFromSelectionForm only uses inputs whose ID matches known search
field patterns (поиск/search/строкапоиска/SearchString/find). When no
search input is found, it skips text entry and matches rows directly in
the grid — which works because the target value is visible among the rows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:46:10 +03:00
Nick Shirokov 5061d83282 fix(web-test): ERP compatibility — CB button fallback, div-based grid
selectValue: try DLB button first, fallback to CB (Choose Button).
ERP uses _CB suffix instead of _DLB for some reference fields
(Соглашение, Склад).

fillTableRow: handle non-INPUT focus between grid cells. ERP's
div-based grid puts DIV.gridBody focus between editable cells on Tab.
Also treat TEXTAREA cells (e.g. Содержание) as editable grid cells.
Added wrap-around detection to exit when Tab loops back to first cell.

Tested: Заказ клиента in ERP — all fields fill correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:02:41 +03:00