Commit Graph

705 Commits

Author SHA1 Message Date
Nick Shirokov f257bb428c test(12-formstate): M3 P1 — modal + tabs
modal: F4 на ref-поле открывает модальную форму выбора Контрагентов,
state.modal=true, formCount=2.

tabs: форма элемента Номенклатуры с двумя табами (Основное/Дополнительно)
возвращает state.tabs[].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:43:53 +03:00
Nick Shirokov 71e3691cf1 test(web-test): M3 P1 batch 1 — confirm-save-no/pending, more-menu, clear/ref-form, table checkbox/clear
02-crud: confirm-save-no (rollback при save:false), confirm-pending
(closeForm() без решения возвращает confirmation), more-menu (clickElement
'Ещё' возвращает submenu).

03-fillfields: clear (Shift+F4 через пустое значение), reference-non-quickchoice
(fillFields на quickChoice=false поле — method=dropdown через DLB; чистый
form-path требует hasPick && !hasSelect, такого поля в синтетике нет).

04-selectvalue: clear (selectValue '' → Shift+F4). show-all-form отложен —
требует quickChoice=true каталога с количеством > порога dropdown
(в синтетике нет).

05-table: checkbox (fillTableRow с Boolean), clear (Shift+F4 на ref-ячейке +
восстановление для последующего delete).

Live на webtest: все шаги проходят.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:40:27 +03:00
Nick Shirokov 1af318325d test(05-table): добавить явный tab-loop step с двумя числовыми полями
fillTableRow({Количество, Цена}, {row:1}) — purpose-built проверка inEdit
multi-cell tab-loop. method='direct' для обоих полей, значения
подставляются корректно (live на webtest).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:23:03 +03:00
Nick Shirokov 986480748e Merge branch 'dev' into feature/web-test-runner 2026-05-10 15:10:38 +03:00
Nick Shirokov 71309d2bc2 fix(tests): make cf-edit/set-home-page case platform-loadable
Кейс ссылался на CommonForm.* и DataProcessor.Поиск.Form.ФормаПоиска,
которых не было в workDir — verify-snapshots падал на db-load-xml,
а cf-validate Check 9 (валидация HP form refs) ловил это только под
--with-validation, поэтому в обычной регрессии проблема была не видна.

Поскольку CommonForm пока не умеет создавать ни meta-compile, ни form-add
(он привязывается к существующему объекту-владельцу), заменил ссылки
на формы Catalog/DataProcessor — DSL-покрытие сохранено целиком:
template, string-ref, height, visibility, русский синтаксис типа,
короткая и полная форма roles. Добавлен preRun из 10 шагов
(meta-compile + form-add + role-compile) для синтеза всех ссылок.

Поддержка CommonForm в meta-compile/form-add — отдельная задача.

verify-snapshots: 1/1 ✓ (db-load-xml, db-update проходят).
Полная регрессия: 349/349 ✓.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
w-2026-02-08 w-2026-02-15 w-2026-02-22 w-2026-03-01 w-2026-03-08 w-2026-03-15 w-2026-03-22 w-2026-03-29 w-2026-04-05 w-2026-04-12 w-2026-04-19 w-2026-04-26 w-2026-05-03 w-2026-05-10
2026-05-08 13:57:30 +03:00
Nick Shirokov e1f81a0cde chore(tests): refresh snapshots after meta-compile QuickChoice + form-compile AutoTitle defaults
- QuickChoice<true→false> для Catalog (07b2ec3 «дефолты QuickChoice по реальным
  конфигам» — часть снапшотов уже обновили в dc0382c, эти были пропущены)
- автоген <Title>/<AutoTitle>/<TitleLocation>/<SavedData> в формах
  (76800fc «автоген Title из имени» и серия фич form-compile)
- column-group/ — новый снапшот для кейса из 4f9d9ae (был не закоммичен)

Все 349 unit-тестов и 6 integration-тестов зелёные. verify-snapshots
(платформенная загрузка) — 201/202; отдельный pre-existing fail
cf-edit/set-home-page (Check 9 не валидирует HP form refs) разбираем
отдельно, в дифф этой регенерации не входит.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:45:47 +03:00
Nick Shirokov e8cb5440d8 feat(switch): emit -ExecutionPolicy Bypass for codex target
Codex on Windows launches powershell.exe as a login-shell that loads
the user profile despite -NoProfile in our SKILL.md. With Restricted
ExecutionPolicy this spams "выполнение сценариев отключено". Add
-ExecutionPolicy Bypass for codex; keep canonical -NoProfile -File for
all other platforms.

Round-trip safe: cmd_install always copies fresh from .claude/skills/,
so switching codex→cursor strips the EP flag. cmd_switch_runtime
re-emits PS commands via normalize_ps_invocation each pass, so
in-place py↔ps in .codex/skills/ keeps the flag.

Also fix a pre-existing bug in cmd_switch_runtime: file-existence
check used repo_root() instead of project_dir, so in-place runtime
switch in a foreign project always tripped skip_runtime=True and
became a no-op. The bug was masked when project_dir == repo_root
(source-repo workflow).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:40:25 +03:00
Nick Shirokov c496047c6c fix(skills): force UTF-8 console encoding in 7 ps1 scripts
Codex runner on Windows launches PowerShell as login-shell and decodes
stdout/stderr without UTF-8, garbling Cyrillic output. The other 51 ps1
scripts already set `[Console]::OutputEncoding = UTF8`; bring these 7
in line and add `InputEncoding = UTF8` for symmetry.

Touched: epf-init, erf-init, form-add, form-remove, help-add,
template-add, template-remove. Versions bumped in both ps1 and py
headers to keep the pair in sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:16:44 +03:00
Nick Shirokov df9541470c chore(plugins): tighten descriptions and align marketplace entries with Codex schema
- Replace overreaching "полный цикл разработки... до записи видеоинструкций" pitch with grounded one-liner matching the GitHub repo description (XML/CLI abstractions + eyes & hands for web-client testing).
- Drop non-standard per-plugin `interface.shortDescription` from .agents/plugins/marketplace.json — MarketplaceInterface only describes `displayName`, openai/plugins keeps per-plugin entries minimal (name/source/policy/category).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 11:42:12 +03:00
Nick Shirokov 27ecfb707d revert(plugins): drop UTF-8 BOM on SKILL.md — Codex YAML parser breaks on it
BOM before `---` makes Codex's strict frontmatter parser reject every
SKILL.md ("Skipped loading 66 skill(s)"). Without BOM the skills load
and execute correctly; the only remaining issue is mojibake display of
Cyrillic in SKILL.md previews — that's a Codex rendering bug, not ours.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:27:08 +03:00
Nick Shirokov 35bec4a2a1 fix(plugins): prepend UTF-8 BOM to SKILL.md on codex branches
Codex on Windows opens SKILL.md without a declared encoding and
defaults to CP1252, mangling Cyrillic. Adding the BOM lets the loader
auto-detect UTF-8.

Applied only on codex/codex-py builds to leave other ports untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:19:10 +03:00
Nick Shirokov e635a5be52 fix(plugins): drop invalid authentication: OFF from Codex marketplace
Codex schema only accepts `ON_INSTALL` or `ON_USE`; the field is
optional, so omit it for an unauthenticated plugin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:26:09 +03:00
Nick Shirokov dfb258dd3f fix(plugins): prefix descriptions with [PowerShell]/[Python] for distinct cards
Codex plugin browser truncates the description, so the runtime tag
needs to appear at the start. Apply the same prefix to Claude
marketplace.json and plugin.json for consistency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:13:33 +03:00
Nick Shirokov 1866c1335a feat(plugins): Codex plugin support + Python plugin variant for Claude
- Add 1c-skills-py to .claude-plugin/marketplace.json (→ port-claude-code-py)
- New .agents/plugins/marketplace.json — Codex marketplace with PS + Py plugins
- Templates .github/templates/{codex,claude}-plugin.json.tmpl rendered by CI
- build-ports.yml: generate plugin manifests on port-codex/port-codex-py/port-claude-code-py; Codex version YYYY.M.D+sha7 auto-bumped per push
- README: install instructions for Codex + Py variant for Claude
- .gitignore: narrow .agents/ → .agents/skills/ so the marketplace is tracked

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:08:07 +03:00
Nick Shirokov 4813ec5cf2 docs(readme): inline "Другие платформы →" link, drop verbose intro line
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:41:20 +03:00
Nick Shirokov 06ad2f8f99 feat(ci): expand port matrix to all 13 platforms + bump deprecated actions
- Add 20 matrix entries: copilot, augment, cline, kilo, kiro, gemini, opencode, roo, windsurf, agents (PS+Py each)
- Total: 25 port-* branches (Claude Code PS = main, plus 13 × Py + 12 × PS)
- Bump actions/checkout@v4 → @v5, actions/setup-python@v5 → @v6 (removes Node.js 20 deprecation warnings)
- README: replace "соберите локально" placeholders with real branch links for all platforms

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:37:35 +03:00
Nick Shirokov c8ac191a01 feat(ci): port-branches workflow + README install matrix
- .github/workflows/build-ports.yml — auto-build orphan port-* branches on push to main (matrix: claude-code-py, cursor PS+Py, codex PS+Py)
- .github/templates/README.port.md.tmpl — minimal per-port README rendered in CI
- README — new "Версии навыков для разных платформ" section under intro (3 flagships × PS+Py), extended platform table with PowerShell/Python branch links, switch.py moved to "альтернативный способ" subsection
- README — "Work in progress" reworded to "Проект живой, активно развивается"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:29:52 +03:00
Nick Shirokov c9d83b1c92 docs(readme): add plugin install instructions
Document the recommended installation path via Claude Code plugin
marketplace:

  /plugin marketplace add https://github.com/Nikolay-Shirokov/cc-1c-skills
  /plugin install 1c-skills@cc-1c-skills

Plugin install becomes the recommended option; drop-in copy and
switch.py-based installs remain documented as alternatives for users
who prefer them or who target other AI platforms.

Closes #18.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:40:38 +03:00
Nick Shirokov b1a7e414d0 fix(switch): runtime conversion for ${CLAUDE_SKILL_DIR} paths
After the SKILL.md refactor, paths are wrapped in double quotes and
contain ${CLAUDE_SKILL_DIR}. The legacy RX_PS/RX_PY regexes captured
the leading quote into the path group and didn't accept '$', '{', '}'
characters, breaking three places:

- classify_skill_runtime: misdetected runtime since RX_PY didn't match
  python invocations of variable paths
- check_missing_files: built file paths like '"${CLAUDE_SKILL_DIR}/...py'
  that never existed → false-positive missing → runtime switch skipped
- switch_runtime_content: failed to convert PS->Py / Py->PS for skills
  using the new path format

Fix:
- Regexes now capture optional surrounding quote separately and accept
  any non-whitespace non-quote chars in the path
- New helper expand_skill_path() resolves ${CLAUDE_SKILL_DIR} to the
  actual on-disk path for file existence checks (handles cross-skill
  references via ../<other>/ too)
- check_missing_files derives skill_name from skill_dir to drive the
  expansion

Verified via:
  python scripts/switch.py claude-code --project-dir <tmp> --runtime python
  python scripts/switch.py claude-code --project-dir <tmp> --runtime powershell
  python scripts/switch.py codex --project-dir <tmp>

All produce correct output with quotes preserved and cross-skill
references resolved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:56:26 +03:00
Nick Shirokov 7736ad68a0 feat(switch): handle ${CLAUDE_SKILL_DIR} for non-Claude targets
After SKILL.md refactor, paths use ${CLAUDE_SKILL_DIR} which Claude Code
substitutes natively. Other agents (Cursor, Codex, Copilot, etc.) don't
know about this variable, so switch.py now expands it to a literal path
when the target is not claude-code:

  ${CLAUDE_SKILL_DIR}/<rest>            -> <target_prefix>/<skill_name>/<rest>
  ${CLAUDE_SKILL_DIR}/../<other>/<rest> -> <target_prefix>/<other>/<rest>

For claude-code target the variable is left intact — drop-in install via
copy still works because Claude Code resolves it identically in
project, personal, and plugin scopes.

Verified by running:
  python scripts/switch.py codex --project-dir <tmp>
  python scripts/switch.py claude-code --project-dir <tmp>

Both produce correct output with 0 leftover variable literals in
non-Claude targets and full preservation in Claude target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:31:08 +03:00
Nick Shirokov 501bb58ddb feat(plugin): plugin and marketplace manifests
Add `.claude-plugin/plugin.json` and `.claude-plugin/marketplace.json` so
the repo can be installed via:

  /plugin marketplace add https://github.com/Nikolay-Shirokov/cc-1c-skills
  /plugin install 1c-skills@cc-1c-skills

Plugin name `1c-skills`, marketplace name `cc-1c-skills` (matches repo
name). Version is omitted in `plugin.json` so Claude Code uses the git
commit SHA — convenient for active development without manual bumps.

Closes part of #18.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:30:32 +03:00
Nick Shirokov cd3a242b12 refactor(skills): portable script paths via ${CLAUDE_SKILL_DIR}
Replace literal `.claude/skills/<owner>/...` paths in SKILL.md with the
`${CLAUDE_SKILL_DIR}` variable that Claude Code substitutes at invocation
time. Same-skill references become `${CLAUDE_SKILL_DIR}/<rest>`,
cross-skill references (erf-* → epf-*) become
`${CLAUDE_SKILL_DIR}/../<other>/<rest>`. All paths now wrapped in double
quotes to handle install locations with spaces.

This unblocks plugin-mode installation: literal `.claude/skills/...`
paths fail when the skill is loaded from `~/.claude/plugins/cache/...`
or from a personal `~/.claude/skills/` install. Drop-in mode continues
to work because Claude Code resolves the variable in all install scopes.

Verified via pilot:
- Project drop-in (cc-1c-skills repo)
- Personal `~/.claude/skills/cf-info/`
- Plugin via `/plugin marketplace add <local-path>`

Scope: 61 SKILL.md, 125 path replacements (8 cross-skill).
Scripts unchanged — they already use \$PSScriptRoot and ../<sibling>
patterns that resolve correctly under the bundled cache layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:30:06 +03:00
Nick Shirokov 7561faf736 test(web-test): покрыть Tumbler через clickElement в radio-шаге
Tumbler-представление RadioButtonField не парсится fillFields, но варианты
видны в state.buttons[] и кликаются через clickElement. Уточнили шаг radio:
- RadioButtons (КатегорияЦены) → fillFields с method=radio
- Tumbler (СпособУчёта) → проверка наличия в buttons[] + clickElement('ФИФО')

Семантика Tumbler через fillFields остаётся как баг web-test/browser.mjs
(см. upload/web-test-bugs.md пункт 5), но рабочий путь интеракции есть.

10/10 smoke зелёные после рестарта Apache.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 18:19:42 +03:00
Nick Shirokov 2849087fd9 test(web-test): покрытие quickChoice + radio (RadioButtons)
03-fillfields:
- reference-dropdown: переведён с Контрагент на Организация
  (после смены quickChoice Контрагенты идут через форму выбора)
- новый шаг radio: КатегорияЦены через method=radio (RadioButtons)

04-selectvalue:
- dropdown: переведён на Организация (quickChoice=true)
- новый шаг direct-form: Контрагент (quickChoice=false), method=form

Закрывает selectValue#3 dropdown (P0), selectValue#6 direct-form (P1),
fillFields#3 radio (P1) из coverage matrix.

Tumbler-представление радио (СпособУчёта) пока не покрыто — getFormState
не возвращает Tumbler в fields[]. Зафиксировано в upload/web-test-bugs.md
пункт 5.

10/10 smoke зелёные на webtest базе.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 16:17:19 +03:00
Nick Shirokov 105171cdc2 test(webtest-config): Организации/quickChoice + radio (RadioButtons+Tumbler)
Расширение синтетики под новые возможности meta-compile/form-compile,
закрывает три ветки coverage matrix:
- Catalog.Организации (quickChoice: true) → selectValue#3 dropdown (P0)
- Catalog.Контрагенты (дефолт quickChoice: false) → selectValue#6 direct-form (P1)
- form-compile radio с видами RadioButtons (КатегорияЦены) и Tumbler
  (СпособУчёта) → fillFields#3 radio (P1)

В шапку ПриходнаяНакладная добавлен реквизит Организация (dropdown ветка),
Контрагент остаётся на форме выбора. Фикстура ЗаполнитьОрганизации создаёт
2 организации (Альфа, Бета); первая подставляется в документы.

Платформенная верификация: build-webtest-db (45 шагов, 30.3s) зелёная,
db-create + db-load-xml + db-update проходят. Функциональный прогон
runner.mjs integration/build-webtest — 42 шага зелёные.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 14:58:27 +03:00
Nick Shirokov c9cd0d62ab Merge branch 'dev' into feature/web-test-runner 2026-05-04 13:15:49 +03:00
Nick Shirokov 4f9d9aee97 feat(form-compile): группировка колонок таблицы (ColumnGroup)
Новый DSL-ключ columnGroup со значением-ориентацией horizontal/vertical/inCell
для элемента <ColumnGroup> внутри columns таблицы. Поддерживает вложение,
showTitle/showInHeader/width, тихие синонимы ColumnGroup и ГруппаКолонок.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 11:48:35 +03:00
Nick Shirokov f3466e19fd docs(form-patterns): актуализация под новые возможности form-compile
- Архетипы «Форма обработки» и «Мастер»: кнопки действий перенесены
  с нижней горизонтальной группы на главную АКП формы (autoCmdBar)
- Конвенция «ГруппаКнопок» заменена на «ФормаКоманднаяПанель»
- Принцип компоновки №3: уточнено, что кнопки идут на АКП
- Сворачиваемые группы: исправлен пример — корректный DSL
  (group: collapsible, collapsed: true) вместо несуществующих
  ключей behavior/collapsed на vertical-группе
- Полный пример формы обработки переписан под autoCmdBar
- Из свойств мастера убран commandBarLocation: None (не нужен,
  когда мы сами наполняем АКП)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 20:10:10 +03:00
Nick Shirokov ebf92a8780 feat(form-compile): свойство collapsed для сворачиваемых групп
Добавлен ключ collapsed (для group=collapsible) → <Collapsed>true</Collapsed>:
группа создаётся уже свёрнутой. Раньше DSL умел только включать
сворачиваемое поведение, но начальное состояние задать было нельзя.

Также уточнено описание united: оно про выравнивание левого края полей
ввода (сквозное/локальное), а не про объединение рамок группы.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 20:07:18 +03:00
Nick Shirokov 3d80191ca7 feat(form-compile): поддержка maxWidth/maxHeight для input и label
Добавлены численные maxWidth/maxHeight (XML <MaxWidth>/<MaxHeight>) —
типичный приём для ограничения растяжения поля при autoMaxWidth: false.
До этого DSL знал только булев autoMaxWidth, и ограничить ширину
числом было невозможно.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:58:36 +03:00
Nick Shirokov 6c60398406 feat(form-compile): авто-вид кнопки по контексту АКП
Кнопки внутри cmdBar/autoCmdBar/popup автоматически получают
CommandBarButton (или CommandBarHyperlink при type="hyperlink") —
указывать вид вручную не нужно. Резолвер прощающий: принимает и
короткие DSL-формы, и XML-имена в любом контексте.

Пример «Диалог загрузки файла» в SKILL.md и тест-кейс file-dialog
переведены на нативный паттерн с autoCmdBar вместо отдельной
горизонтальной группы кнопок внизу формы.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:41:43 +03:00
Nick Shirokov 60de083a05 docs(1c-form-spec): RadioButtonField перенесён в статистику (~8.5% форм БП)
Замер по acc_8.3.24: 658 из 7723 форм содержат RadioButtonField
(всего 1389 элементов). Раньше ошибочно числился среди не встреченных.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:48:29 +03:00
Nick Shirokov 5690c82ab8 docs(form-dsl-spec): radio (RadioButtonField) в спецификации DSL
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:45:00 +03:00
Nick Shirokov dc0382cc06 chore(tests): обновлены снапшоты после meta-compile QuickChoice defaults
Снапшоты ссылочных реквизитов теперь содержат QuickChoice=false
в соответствии с дефолтами по реальным конфигам (см. 07b2ec3).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:43:33 +03:00
Nick Shirokov b1e29253d5 feat(form-compile): RadioButtonField и словарь синонимов типов элементов
Поле переключателя с RadioButtonType (Auto/RadioButtons/Tumbler) и
ChoiceList (массив value+presentation). Толерантно к написанию модели:
русские имена тегов (ПолеПереключателя, RadioButtonField),
ВидПереключателя по-русски (Авто/Переключатель/Тумблер),
Перечисление.X.Y без EnumValue, синоним title для presentation,
автогенерация презентации из имени значения.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:43:26 +03:00
Nick Shirokov 07b2ec36af feat(meta-compile): дефолты QuickChoice по реальным конфигам
Catalog/CCT/CoA/CoCT/ExchangePlan: дефолт false (раньше true). Enum: дефолт true (теперь параметризовано). Цифры из acc_8.3.27 + erp_8.3.24 — у Catalog ~95% объектов QuickChoice=false, у Enum ~99% true.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:34:16 +03:00
Nick Shirokov c1a0a54971 feat(web-test): --record и export const params
Раннер v1.7.

T5 --record: startRecording перед каждым тестом, stopRecording
после (и в passed, и в failed ветке). Файл
{reportDir}/{testIdx}-{slug}.mp4. testResult.video содержит путь.
В Allure — attachment типа video/mp4. config.record читается
тоже. Использует существующую инфраструктуру browser.mjs.

T6 export const params: материализация в N тестов на этапе
discovery. Имя через {key}-шаблон в mod.name (например
'demo {type}'); если шаблона нет — суффикс [index]. Тест-функция
получает param как второй аргумент: default(ctx, param).
В отчёте каждый набор — отдельная test entry с собственным uuid
в Allure / testcase в JUnit.

Live-проверка:
- params: 2 теста с именами demo A / demo B из шаблона.
- record: mp4 91KB на 6-секундном тесте, путь в JSON и
  Allure attachment video/mp4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:19:52 +03:00
Nick Shirokov 927c0827f3 feat(web-test): --format=allure и --format=junit
Раннер v1.6. Реализованы оба формата отчётов из spec §9.

allure: {reportDir}/{uuid}-result.json на каждый тест. uuid через
randomUUID, labels из tags, steps рекурсивно с attachments из
step.screenshot, statusDetails для упавших шагов и тестов.
Пропускает skipped (нет start/stop).

junit: один XML в --report=path.xml. Валидация: --format=junit
требует --report=. xmlEscape для name/message/trace. <failure>
для упавших, <skipped/> для пропущенных, <system-out> со ссылкой
на screenshot.

Валидация формата (json|allure|junit) на старте cmdTest.
testResult теперь хранит start/stop в мс — нужно для Allure
и полезно в JSON-отчёте.

Live-проверка: 01-navigation в Allure (5 шагов с attachments,
все ссылки на существующие PNG); JUnit с passed и forced-fail
(спецсимволы корректно экранированы).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:03:31 +03:00
Nick Shirokov 56cd18a6b4 feat(web-test): --screenshot=on-failure|every-step|off + --report-dir
Раннер v1.5. Парсит --screenshot и --report-dir, мерж с config.screenshot.
- every-step: после успешного step() пишет {reportDir}/{testIdx}-{stepIdx}-{slug}.png,
  путь в step.screenshot.
- off: ни пошаговых, ни error-shot.
- on-failure (default): error-shot уехал из .claude/skills/web-test/
  в {reportDir}/error-{testIdx}-{slug}.png.

reportDir фоллбэчит: --report-dir → dirname(--report) → testDir.

Известная нестыковка: error-shot из buildContext/executeScript остаётся в
.claude/skills/web-test/error-shot.png — затронем при T2 (Allure).

Live-проверка: 01-navigation с every-step (5 PNG), off (пусто),
default on-failure на стуб-failing тесте (error-shot в reportDir).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 15:54:38 +03:00
Nick Shirokov 3ac1d425cd test(11-report): DCS-отчёт ОстаткиТоваров + smoke с быстрым фильтром
Синтетика: добавлен template-add ОсновнаяСхемаКомпоновкиДанных к отчёту
(без него skd-compile писал Template.xml в незарегистрированный путь),
переписан DSL skd-compile — fields внутри dataSets, типы полей, totalFields,
явный settingsVariants со structure и быстрым отбором по Номенклатуре
(@off @user @quickAccess).

Тест 11-report покрывает: регистрацию команды в подсистеме, открытие формы
отчёта с дефолтной кнопкой Сформировать, видимость и структуру быстрого
DCS-фильтра, формирование отчёта, применение фильтра через selectValue
(auto-enable чекбокса + значение), пересчёт с фильтром, снятие фильтра
через fillFields toggle off с восстановлением исходных данных.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 15:22:22 +03:00
Nick Shirokov 3c596f4550 test(12-formstate): smoke базовых полей getFormState
Покрывает форму списка (form, formCount, openForms, tables, buttons)
и форму элемента (fields с label и value, проверка по конкретному
полю Наименование).
2026-05-02 20:15:20 +03:00
Nick Shirokov 36d29a51a9 test(09-filter): smoke filterList simple-search и advanced-column
Покрывает:
- filterList('Север') — поиск по всем колонкам списка Контрагенты
- filterList('Север', { field: 'Наименование' }) — фильтр по
  конкретной колонке через расширенный поиск
- unfilterList — восстановление исходного набора

Третий запланированный кейс (text-field filter) семантически совпадает
с advanced-column когда колонка строкового типа — оставлен на регресс P1.
2026-05-02 20:11:58 +03:00
Nick Shirokov 11e961c816 test(07-tabs): smoke переключение страниц формы Основное/Дополнительно
Покрывает clickElement по имени страницы как механизм переключения
вкладок формы. Используем форму элемента Номенклатура: page1
показывает шапку (Артикул, ВидНоменклатуры, ...), page2 — Дополнительно
(ЕдиницаИзмерения, Комментарий). Verify: набор state.fields различен
после переключения и совпадает после возврата.
2026-05-02 20:07:46 +03:00
Nick Shirokov 05ca810461 test(06-document): сверка с Комментарий=docId, защита от грязной базы
Раньше verify-list брал первый попавшийся проведённый документ Север —
если в базе уже лежал проведённый Север из прошлого прогона, тест
проходил даже если текущий не сохранился. Теперь среди кандидатов
открываем каждый и сверяем Комментарий с уникальным docId текущего
прогона; ассерт срабатывает только при совпадении.
2026-05-02 20:04:38 +03:00
Nick Shirokov a0407b74dc test(06-document): проверка закрытия по смене номера формы вместо костыля
Раньше использовалось отсутствие поля Контрагент после Провести и закрыть
как косвенный признак закрытия — это работало, но было привязано к
конкретному реквизиту накладной. Заменил на сравнение state.form до и
после: номер активной формы меняется (11 → 5), это прямой и общий
признак, что мы переключились с формы документа на другую.
2026-05-02 19:58:56 +03:00
Nick Shirokov 3aad254399 test(06-document): smoke workflow проведения накладной
Создание, заполнение шапки и табличной части, Провести и закрыть,
проверка появления документа в списке с Проведён=Да.

Проверка закрытия формы документа: в синтетике web-test форма списка и
форма документа делят один слот (formCount=1 в обоих состояниях),
поэтому используем признак отсутствия поля Контрагент в текущем
state.fields после Провести и закрыть — если поле есть, мы остались
на форме документа.
2026-05-02 19:54:34 +03:00
Nick Shirokov 07753921be test(05-table): smoke add/edit/delete для табличной части накладной
Покрывает работу с табличной частью Товары документа Приходная накладная:
- fillTableRow с add:true добавляет строки последовательно
- fillTableRow с row:N редактирует существующую строку (Tab-навигация)
- deleteTableRow удаляет строку по индексу

Закрытие формы без сохранения (save:false) — соответствует новой
семантике после фикса form-compile (SavedData).
2026-05-02 19:49:19 +03:00
Nick Shirokov ba0c71fa45 test(smoke): починить 01-navigation и 04-selectvalue после фикса form-compile
01-navigation: первое открытое окно 1С имеет form=0 (number), и
assert.ok(state.form, ...) валился на falsy при первом запуске сессии.
Сменил на state.form != null.

04-selectvalue: явный save:false при закрытии модифицированной формы
накладной — после фикса SavedData=true главного реквизита платформа
требует решения по confirmation dialog.
2026-05-02 19:45:15 +03:00
Nick Shirokov 33c9fdade0 test(03-fillfields): boolean → CheckBoxField, явный save:false при закрытии
После фикса form-compile (kind=check для Boolean + SavedData=true для
главного реквизита) Активен передаётся как настоящий boolean (toggle),
getFormState возвращает value:true/false. Закрытие модифицированных форм
теперь требует явного save:false — иначе платформа показывает
confirmation dialog «Записать?».
2026-05-02 19:40:26 +03:00
Nick Shirokov 1c1fe7b2d9 test(02-crud): убрать устаревший комментарий про T11/SavedData
После фикса form-compile (a59be4b SavedData=true для главного реквизита)
canonical confirm-save-yes flow работает без ручного патча Form.xml —
предупреждение в шаге неактуально.
2026-05-02 19:26:56 +03:00