$npx -y skills add Arman-Kudaibergenov/1c-ai-development-kit --skill web-testЭтот скилл MUST быть вызван когда пользователь просит проверить или протестировать 1С через браузер в интерактивном режиме (быстрые ручные проверки). SHOULD также вызывать для одноразовой верификации поведения веб-интерфейса 1С. Do NOT использовать для создания файлов автотестов
| 1 | # /web-test — Browser automation for 1C web client |
| 2 | |
| 3 | Automates user interactions with 1C:Enterprise web client via Playwright — navigating sections, filling forms, reading tables and reports, filtering lists. |
| 4 | |
| 5 | ## Quick start |
| 6 | |
| 7 | ```bash |
| 8 | RUN=".claude/skills/web-test/scripts/run.mjs" |
| 9 | |
| 10 | # One-shot: opens browser → runs script → closes browser → exits |
| 11 | node $RUN run http://localhost:8081/bpdemo test-scenario.js |
| 12 | |
| 13 | # Or pipe inline: |
| 14 | cat <<'SCRIPT' | node $RUN run http://localhost:8081/bpdemo - |
| 15 | await navigateSection('Продажи'); |
| 16 | await openCommand('Заказы клиентов'); |
| 17 | await clickElement('Создать'); |
| 18 | await fillFields({ 'Клиент': 'Альфа' }); |
| 19 | await clickElement('Провести и закрыть'); |
| 20 | SCRIPT |
| 21 | ``` |
| 22 | |
| 23 | ## Setup (first time) |
| 24 | |
| 25 | ```bash |
| 26 | cd .claude/skills/web-test/scripts && npm install |
| 27 | ``` |
| 28 | |
| 29 | Requires Node.js 18+. `npm install` downloads Playwright and Chromium. |
| 30 | |
| 31 | ## URL resolution |
| 32 | |
| 33 | Read `.v8-project.json` from project root. Each database has `id` and optional `webUrl`. |
| 34 | Construct URL as `http://localhost:8081/<id>` or use `webUrl` if set. |
| 35 | Use `/web-publish` first if the database is not published. |
| 36 | |
| 37 | ## Execution modes |
| 38 | |
| 39 | ### Autonomous mode (preferred for complete scenarios) |
| 40 | |
| 41 | ```bash |
| 42 | node $RUN run <url> script.js # exits when done, no session |
| 43 | ``` |
| 44 | |
| 45 | ### Interactive mode (step-by-step development) |
| 46 | |
| 47 | ```bash |
| 48 | # 1. Start session (run_in_background=true, prints JSON when ready) |
| 49 | node $RUN start <url> |
| 50 | |
| 51 | # 2. Execute scripts against running session |
| 52 | cat <<'SCRIPT' | node $RUN exec - |
| 53 | const form = await getFormState(); |
| 54 | console.log(JSON.stringify(form, null, 2)); |
| 55 | SCRIPT |
| 56 | |
| 57 | # 3. Screenshot |
| 58 | node $RUN shot result.png |
| 59 | |
| 60 | # 4. Stop (logout + close) |
| 61 | node $RUN stop |
| 62 | ``` |
| 63 | |
| 64 | `start` runs an HTTP server in background. Use `exec`/`shot`/`stop` from other shells. |
| 65 | |
| 66 | ### Writing exec scripts |
| 67 | |
| 68 | All browser.mjs exports are globals — no `import` needed. |
| 69 | `console.log()` output is captured in the JSON response. |
| 70 | `writeFileSync` / `readFileSync` also available. |
| 71 | |
| 72 | ## API reference |
| 73 | |
| 74 | ### Navigation |
| 75 | |
| 76 | #### `navigateSection(name)` → `{ navigated, sections, commands }` |
| 77 | Go to a top-level section (fuzzy match). Returns list of commands in that section. |
| 78 | ```js |
| 79 | await navigateSection('Продажи'); |
| 80 | // { navigated: 'Продажи', sections: [...], commands: ['Заказы клиентов', ...] } |
| 81 | ``` |
| 82 | |
| 83 | #### `openCommand(name)` → form state |
| 84 | Open a command from the function panel (fuzzy). Returns form state of the opened form. |
| 85 | ```js |
| 86 | const form = await openCommand('Заказы клиентов'); |
| 87 | ``` |
| 88 | |
| 89 | #### `navigateLink(url)` → form state |
| 90 | Open any 1C object by metadata path (Shift+F11 dialog). Bypasses section/command navigation. |
| 91 | ```js |
| 92 | await navigateLink('Документ.ЗаказКлиента'); |
| 93 | await navigateLink('РегистрНакопления.ЗаказыКлиентов'); |
| 94 | await navigateLink('Справочник.Контрагенты'); |
| 95 | ``` |
| 96 | |
| 97 | #### `switchTab(name)` → form state |
| 98 | Switch to an already-open tab/window (fuzzy match). |
| 99 | |
| 100 | ### Reading form state |
| 101 | |
| 102 | #### `getFormState()` → `{ fields, buttons, tabs, table, filters, reportSettings? }` |
| 103 | Returns current form structure. This is the primary way to understand what's on screen. |
| 104 | |
| 105 | **fields** — each field has: `name`, `value`, `label?`, `actions?` (select, clear, open), `required?` (true for unfilled mandatory fields) |
| 106 | |
| 107 | **table** — summary only: `{ name, columns, rowCount }`. Use `readTable()` for actual data. |
| 108 | |
| 109 | **reportSettings** — for DCS reports: human-readable filter settings instead of raw technical names: |
| 110 | ```js |
| 111 | const form = await getFormState(); |
| 112 | // form.reportSettings = [ |
| 113 | // { name: "Склад", enabled: true, value: "Склад бытовой техники", actions: ["select"] }, |
| 114 | // { name: "Номенклатура", enabled: false, value: "" } |
| 115 | // ] |
| 116 | ``` |
| 117 | |
| 118 | **errorModal** — if present, 1C showed an error dialog. Read the message and decide how to proceed. |
| 119 | |
| 120 | **confirmation** — if present, a Yes/No dialog is shown. Call `clickElement('Да')` or `clickElement('Нет')`. |
| 121 | |
| 122 | ### Reading data |
| 123 | |
| 124 | #### `readTable({ maxRows?, offset? })` → `{ columns, rows, total, shown, offset }` |
| 125 | Read actual grid data with pagination. Each row is `{ columnName: value }`. |
| 126 | |
| 127 | | Option | Default | Description | |
| 128 | |--------|---------|-------------| |
| 129 | | `maxRows` | 20 | Max rows to return per call | |
| 130 | | `offset` | 0 | Skip first N rows | |
| 131 | |
| 132 | Special row fields: |
| 133 | - `_kind: 'group'` — hierarchical group row |
| 134 | - `_kind: 'parent'` — parent row in hierarchy |
| 135 | - `_tree: 'expanded'|'collapsed'` — tree node state |
| 136 | - `_level: N` — nesting depth in tree view |
| 137 | - `hierarchical: true` — list has groups (on result object) |
| 138 | - `viewMode: 'tree'` — tree view active (on result object) |
| 139 | |
| 140 | ```js |
| 141 | const t = await readTable({ maxRows: 50 }); |
| 142 | console.log('Colu |