$npx -y skills add Arman-Kudaibergenov/1c-ai-development-kit --skill 1c-web-sessionЭтот скилл MUST быть вызван для управления 1С:Предприятие в веб-клиенте через Playwright MCP: запуск/перезапуск/завершение сеанса, навигация, создание и редактирование справочников и документов. SHOULD также вызывать для генерации тестовых данных через UI и сценарного тестировани
| 1 | # /1c-web-session — Управление 1С в веб-клиенте |
| 2 | |
| 3 | Скилл для работы с 1С:Предприятие через Playwright MCP (браузер). |
| 4 | |
| 5 | > **Источник:** адаптировано из [RooLee10/1c-web-session](https://github.com/RooLee10/1c-web-session) (MIT) |
| 6 | |
| 7 | ## Запуск базы |
| 8 | |
| 9 | 1. Прочитать `CLAUDE.md` проекта — найти URL базы (формат: `http://<сервер>/<публикация>/ru_RU/`) |
| 10 | 2. `browser_navigate` на URL |
| 11 | 3. Обработать лицензию/вход если появятся (см. ниже) |
| 12 | |
| 13 | ## Завершение и перезапуск |
| 14 | |
| 15 | **Сервис и настройки** → **Файл** → **Выход** → **Завершить работу** |
| 16 | |
| 17 | Перезапуск: завершить → `browser_navigate` на URL. |
| 18 | |
| 19 | --- |
| 20 | |
| 21 | ## КРИТИЧЕСКИЕ ПРАВИЛА 1С веб-клиента |
| 22 | |
| 23 | ### 1. Clipboard paste — ЕДИНСТВЕННЫЙ способ ввода |
| 24 | |
| 25 | **Стандартные `fill()`, `type()`, `pressSequentially()` НЕ работают в 1С.** Всегда: |
| 26 | |
| 27 | ```javascript |
| 28 | await page.evaluate((v) => navigator.clipboard.writeText(v), 'Значение'); |
| 29 | await page.keyboard.press('Control+A'); // очистить поле |
| 30 | await page.keyboard.press('Control+V'); |
| 31 | ``` |
| 32 | |
| 33 | ### 2. Суффиксные селекторы — ЕДИНСТВЕННЫЙ надёжный метод |
| 34 | |
| 35 | Формы 1С получают инкрементальные ID (`form26`, `form40`). **Никогда не хардкодить номер формы.** |
| 36 | |
| 37 | ```javascript |
| 38 | // ПРАВИЛЬНО |
| 39 | await page.locator('[id$="_ВидНоменклатуры_DLB"]').click(); |
| 40 | // НЕПРАВИЛЬНО — сломается после первой формы |
| 41 | await page.locator('[id="form40_ВидНоменклатуры_DLB"]').click(); |
| 42 | ``` |
| 43 | |
| 44 | ### 3. DLB-кнопки — универсальный паттерн выбора |
| 45 | |
| 46 | **Все кнопки выбора имеют суффикс `_DLB`** — и перечисления, и справочники: |
| 47 | |
| 48 | ```javascript |
| 49 | await page.locator('[id$="_ВидАттракциона_DLB"]').click(); |
| 50 | await page.waitForTimeout(100); |
| 51 | |
| 52 | if (await page.locator('#editDropDown').count() > 0) { |
| 53 | // Dropdown — перечисление или небольшой справочник |
| 54 | await page.locator('#editDropDown').getByText('Экстремальный').click(); |
| 55 | } else { |
| 56 | // Picker — большой справочник |
| 57 | await page.getByTitle('Выбрать значение (Ctrl+Enter)').waitFor(); |
| 58 | await page.getByText('Экстремальный').click(); |
| 59 | await page.getByTitle('Выбрать значение (Ctrl+Enter)').click(); |
| 60 | } |
| 61 | ``` |
| 62 | |
| 63 | ### 4. Навигационный кеш |
| 64 | |
| 65 | ID разделов (`#themesCell_theme_N`) и пунктов меню (`#cmd_0_3_txt`) уникальны для каждой базы. |
| 66 | |
| 67 | При первом запуске — выполнить `references/scan-nav.js` через `browser_run_code`, результат сохранить в `.claude/1c-nav.json` (Write tool). |
| 68 | |
| 69 | Навигация — только через кешированные ID: |
| 70 | ```javascript |
| 71 | await page.locator('#themesCell_theme_1').click(); // из 1c-nav.json |
| 72 | await page.locator('#cmd_0_3_txt').waitFor({ state: 'visible', timeout: 2000 }); |
| 73 | await page.locator('#cmd_0_3_txt').click(); |
| 74 | ``` |
| 75 | |
| 76 | **НЕ** использовать `getByText('Справочники')` — `strict mode violation`. |
| 77 | |
| 78 | --- |
| 79 | |
| 80 | ## Обработка диалогов |
| 81 | |
| 82 | ### Диалог лицензии |
| 83 | |
| 84 | "Не обнаружено свободной лицензии!" — установить checkbox через JS, нажать "Выполнить запуск": |
| 85 | |
| 86 | ```javascript |
| 87 | async (page) => { |
| 88 | const rows = await page.locator('text=сеанс:').all(); |
| 89 | for (const row of rows) { |
| 90 | const parent = row.locator('xpath=..'); |
| 91 | await parent.locator('input, [class*="check"], [class*="box"]').first().click(); |
| 92 | } |
| 93 | return { clicked: rows.length }; |
| 94 | } |
| 95 | ``` |
| 96 | |
| 97 | ### Форма входа |
| 98 | |
| 99 | Если появляется — сразу `browser_navigate` с тем же URL. **Не нажимать "Войти".** |
| 100 | |
| 101 | ### Модальные диалоги |
| 102 | |
| 103 | | Диалог | Действие | |
| 104 | |--------|----------| |
| 105 | | `beforeunload` | `browser_handle_dialog` с `accept: true` | |
| 106 | | "Данные были изменены" | `locator('a').filter({ hasText: 'Нет' }).click()` | |
| 107 | | Подтверждение (Пометить на удаление?) | `page.keyboard.press('Enter')` | |
| 108 | |
| 109 | --- |
| 110 | |
| 111 | ## Клавиатурные сочетания |
| 112 | |
| 113 | | Сочетание | Действие | |
| 114 | |-----------|----------| |
| 115 | | `Ctrl+Enter` | Записать и закрыть / Провести и закрыть | |
| 116 | | `Ctrl+S` | Записать (без проведения) | |
| 117 | | `Escape` | Закрыть диалог ошибки | |
| 118 | | `Tab` | Следующее поле | |
| 119 | | `F4` | Показать список для выбора | |
| 120 | | `Ins` | Добавить строку в табличную часть | |
| 121 | | `Ctrl+Shift+Z` | Закрыть панель ошибок валидации | |
| 122 | | `Delete` | Пометить на удаление | |
| 123 | |
| 124 | **Проведение:** `Ctrl+Enter` проводит и формирует движения. `Ctrl+S` только записывает. |
| 125 | |
| 126 | --- |
| 127 | |
| 128 | ## Поле "Наименование" при создании |
| 129 | |
| 130 | Поле "Наименование" уже в фокусе при открытии формы нового элемента. Не искать по ID: |
| 131 | |
| 132 | ```javascript |
| 133 | await page.keyboard |