Отладка содержимого HTML полей в тонком клиенте через Answer42
Коротко
Answer42 — open-source MCP-сервер, который даёт AI-агенту (Claude, Cursor, OpenClaw и любому другому MCP-клиенту) «руки» в 1С:Предприятии: открывать формы, нажимать кнопки, заполнять поля, работать с таблицами, динамическими списками и отчётами. Всё это идёт через штатный клиент тестирования 1С (/TESTMANAGER + /TESTCLIENT), а не через клики по координатам.
В версии 0.6.0 Answer42 научился работать с тем, что API клиента тестирования не видит вовсе, — с живыми веб-страницами в полях HTML-документа. Чат с ИИ-ассистентом, встроенный онлайн-сервис, SPA, график на JavaScript: теперь агент может прочитать их текущий DOM, найти элементы, нажать кнопку, ввести текст, дождаться ответа и посмотреть ошибки консоли страницы. Работает и в Windows-клиенте, и в Linux-клиенте, в том числе на скрытом рабочем столе и в Xvfb.
В статье — как устроен мост на каждой платформе, какие тонкости встретились по дороге и что это открывает для тестирования и автоматизации.
Проблема: API клиента тестирования видит только снимок страницы
У поля HTML-документа в API клиента тестирования есть три полезных метода ТестируемоеПолеФормы: ПолучитьHTMLДокумента(), ВвестиHTMLДокумента() и НажатьНаГиперссылкуВHTMLДокументе(). Мы обернули их в инструменты группы forms:
|
Инструмент |
Метод платформы |
Что делает |
|
html_field_content |
ПолучитьHTMLДокумента |
HTML поля и извлечённый из него видимый текст (без скриптов и стилей) |
|
html_field_click_link |
НажатьНаГиперссылкуВHTMLДокументе |
нажать гиперссылку по тексту или адресу |
|
html_field_input |
ВвестиHTMLДокумента |
записать HTML в поле |
Для статического HTML — отчёта, справки, письма — этого достаточно. Но ПолучитьHTMLДокумента() отдаёт снимок документа на момент окончания загрузки. То, что скрипты страницы успели нарисовать сразу, в снимок попадает; всё, что появилось позже, — ответ чата, данные, пришедшие с сервера, результат клика — нет. А современные встроенные веб-приложения живут именно «после загрузки»: подгружают данные, перерисовывают DOM, реагируют на ввод.
Для иллюстраций в статье мы собрали обезличенную внешнюю обработку «Демо: веб-приложение в поле HTML»: в поле HTML-документа — маленький чат-ассистент, который рисует себя скриптом, принимает вопрос и через долю секунды «отвечает». Обработка открывается во встроенной демо-базе Answer42. На ней хорошо видна разница: html_field_content (то есть ПолучитьHTMLДокумента) возвращает заголовок и приветствие чата — их скрипт нарисовал при загрузке, — но после вопроса ответа в снимке нет, размер HTML не меняется (4377 символов до и после). Живой DOM при этом уже содержит и вопрос, и ответ.

Рис. 1. Демо-обработка с веб-приложением в поле HTML-документа, открытая в тест-клиенте
Задача, которую мы ставили: агент должен уметь прочитать такое приложение, найти в нём элементы, задать вопрос и дождаться ответа — то есть работать с ним так же, как пользователь.
Почему не Selenium или Cypress
Для веб-клиента 1С вопрос решается стандартно: он работает в обычном браузере, и к нему подходят Selenium, Playwright, Cypress и инструменты на их основе — браузер отдаёт WebDriver или DevTools Protocol, остальное дело техники. В тонком клиенте браузера нет. Поле HTML-документа рисует WebKit, встроенный в сам процесс 1cv8c, без WebDriver и без DevTools-порта. Подключить к нему внешний фреймворк нельзя — можно только договориться с самим WebKit.
Вторая особенность — версия этого WebKit. Она не самая свежая и, что важнее, разная: на Windows движок поставляется вместе с платформой, на Linux платформа использует системный WebKitGTK. Мы сняли одной и той же проверкой (через html_eval в демо-обработке) возможности движков тонкого клиента 8.5.1.1343 на Windows 11 и на Debian 13:
|
Возможность |
Windows, 8.5.1 |
Linux, 8.5.1 |
|
navigator.userAgent |
AppleWebKit/605.1 … V8WebKit |
AppleWebKit/605.1.15 … Version/15.0 Safari |
|
Движок |
WebKit, поставляемый вместе с платформой; по возможностям — уровень Safari 11–12, 2017–2018 |
системный WebKitGTK 2.36 (libwebkit2gtk-4.0), уровень Safari 15, 2022 |
|
ES2015–2018: let/const, стрелочные функции, классы, async/await, {...obj} |
да |
да |
|
ES2020: ?., ??, BigInt |
нет |
да |
|
ES2022: поля и приватные поля классов |
нет |
да |
|
Ретроспективные проверки в регулярных выражениях (?<=…) |
нет |
нет |
|
fetch |
нет (только XMLHttpRequest) |
да |
|
IntersectionObserver, ResizeObserver, Custom Elements, structuredClone |
нет |
да |
|
CSS: flexbox, grid, grid-gap, переменные --x |
да |
да |
|
CSS: position: sticky |
только -webkit-sticky |
да |
|
CSS: gap для flex, clamp(), aspect-ratio |
нет |
да |
|
CSS: :has(), container queries |
нет |
да |
|
CSS: backdrop-filter |
нет |
только с префиксом -webkit- |
Что из этого следует на практике:
- Одна версия платформы — два разных браузера. Страница, собранная современным бандлером под «последние две версии браузеров», работает в Linux-клиенте и падает с SyntaxError в Windows-клиенте на первом же ?.. Причём падает весь <script>, а не одна строка.
- Windows-движок меняется только вместе с платформой. Он поставляется в составе платформы, поэтому от версии к версии платформы его возможности могут отличаться — а могут и не меняться годами. Рассчитывать на то, что «в следующей версии платформы обновят WebKit» и современный JavaScript заработает сам, не стоит.
- Linux-движок зависит от дистрибутива, а не от 1С. Платформа 8.5 линкуется с libwebkit2gtk-4.0, и какая версия WebKitGTK окажется в системе, решает дистрибутив и его обновления: на одном и том же релизе 1С пользователи разных дистрибутивов получат движки разных лет. Поэтому для Linux-клиента совместимость нужно проверять на тех дистрибутивах, которые реально стоят у пользователей.
- Проверять нужно в тонком клиенте, а не в браузере. Тест «в Chrome всё работает» ничего не говорит о поле HTML-документа. Отсюда и наш подход: работать с тем WebKit, который реально встроен в клиент, — а заодно уметь находить несовместимый код (об этом ниже, в разделе про html_console).
Опора: штатные инструменты разработчика
В обоих тонких клиентах у поля HTML-документа есть штатные инструменты разработчика — Web Inspector с элементами страницы, сетью и консолью. Именно на них Answer42 и опирается: на Windows инспектор открывается сочетанием Ctrl+Alt+Shift+F12 и встраивается в нижнюю часть формы, на Linux WebKitGTK предоставляет сервер удалённой отладки по переменной окружения WEBKIT_INSPECTOR_SERVER. Дальше остаётся автоматизировать то, что разработчик сделал бы руками: открыть инструменты и выполнить код в странице.
Windows: однострочник в консоль встроенного инспектора
Консоль Web Inspector выполняет код в самой инспектируемой странице. Значит, достаточно ввести в неё короткий скрипт, который подключится к Answer42 и будет выполнять присланные выражения. Платформа используется без изменений.

Рис. 2. После работы инструментов html_*: вопрос задан через html_type, ответ прочитан html_text; внизу формы — встроенный Web Inspector с однострочником моста в консоли
Шаг 1. Найти WebKit-представления тест-клиента
Каждое поле HTML-документа — это окно класса WebViewWindowClass внутри окна формы. Answer42 перечисляет окна процесса тест-клиента; если клиент запущен на скрытом рабочем столе (аналог Xvfb для Windows), перечисление идёт через EnumDesktopWindows по дескриптору этого рабочего стола.
Шаг 2. Нажать Ctrl+Alt+Shift+F12 без клавиатуры
SendInput на скрытый рабочий стол не доходит, а просто отправить WM_KEYDOWN недостаточно: WebKit проверяет состояние модификаторов. Поэтому поток Answer42 подключается к очереди ввода потока окна через AttachThreadInput, выставляет Ctrl, Alt и Shift в общем состоянии клавиатуры через SetKeyboardState и отправляет WM_SYSKEYDOWN с VK_F12 (в lParam выставлен бит 29 — «Alt нажат»). Модификаторы держатся, пока сообщение не обработано, затем состояние клавиатуры восстанавливается.
Шаг 3. Отличить инспектор от HTML-полей
1С встраивает интерфейс инспектора в форму как ещё одно окно WebViewWindowClass того же процесса. В первой версии Answer42 принимал его за новое HTML-поле, открывал инспектор для инспектора и 25 секунд ждал подключения. Решение — снимок списка WebView до и после горячей клавиши: всё, что появилось, запоминается как интерфейс инспектора и само никогда не инспектируется.
Шаг 4. Ввести мост в консоль
Самая капризная часть. Список граблей, на которые мы наступили:
- Esc нельзя. В Web Inspector Esc открывает консоль и ставит в неё курсор, но в тест-клиенте Esc первой обрабатывает 1С — и закрывает форму вместе с чатом.
- Клик по координатам ненадёжен. Позиция строки ввода зависит от DPI и раскладки панелей. Итоговая схема: клик в середину интерфейса инспектора (чтобы у него появился фокус) и сочетание Ctrl+` — штатная команда «перейти в строку консоли». Клавиша сопоставляется по коду, поэтому раскладка не важна. Затем Ctrl+A выделяет то, что могло остаться от прошлых попыток.
- Фокус приходит асинхронно. Строка ввода иногда получает первый символ после второго, поэтому вводимый текст начинается с пробела, который поглощает эту гонку.
- Enter в конце строки не всегда выполняет код. Консоль сначала спрашивает у страницы, завершено ли выражение, и может вставить перевод строки. Если перед Enter нажать Home и поставить курсор в начало, код выполняется сразу.
- Интерфейс инспектора может ещё грузиться — тогда клик и символы теряются. Answer42 периодически повторяет ввод.
Символы вводятся сообщениями WM_CHAR прямо в окно интерфейса инспектора. Сам однострочник — около 330 символов ES5:
(function(){var w=new WebSocket('ws://127.0.0.1:<порт>/answer42-page');
w.onopen=function(){w.send(JSON.stringify({type:'hello',token:'<токен>'}))};
w.onmessage=function(e){var m=JSON.parse(e.data),r;
try{r={type:'reply',id:m.id,value:(0,eval)(m.expression)}}
catch(x){r={type:'reply',id:m.id,error:String(x&&x.message||x)}}
w.send(JSON.stringify(r))}})()
(для читаемости разбит на строки, в консоль вводится одной строкой).

Рис. 3. Консоль встроенного инспектора: Answer42 ввёл однострочник моста с портом и одноразовым токеном
Шаг 5. Безопасность подключения
Мост работает в странице, поэтому заголовок Origin у подключения — адрес самой страницы (https://…), и проверка источника ничего не даёт. Вместо неё каждый ввод несёт одноразовый токен (secrets.token_urlsafe): WebSocket-сервер Answer42 слушает только 127.0.0.1 и закрывает любое подключение без действующего токена; токен нельзя использовать повторно.
Встроенные веб-сервисы обычно открываются по https, а мост подключается по незашифрованному ws://127.0.0.1. Это первое, что мы проверяли в эксперименте на реальном веб-приложении: WebKit тонкого клиента подключение разрешает и лишь пишет в консоль предупреждение «was allowed to run insecure content». CSP проверенного приложения подключение тоже не блокировала.
Мост живёт в странице, поэтому перезагрузка или переход по ссылке его сбрасывает. Answer42 замечает разрыв WebSocket, помечает страницу закрытой и при следующем вызове html_* вводит однострочник заново — инспектор к этому моменту уже открыт. Первое подключение к странице в наших прогонах занимало 13–27 секунд (открытие инспектора, загрузка его интерфейса, ввод), дальше команды выполняются за доли секунды. Сейчас первое подключение оптимизировано и занимает менее 5 секунд.
Linux, способ 1: удалённый отладчик WebKitGTK
В Linux-клиенте 1С HTML-поля рисует системный WebKitGTK — тонкий клиент 8.5 линкуется с libwebkit2gtk-4.0 (на тестовом стенде Debian 13 — версия 2.36). У WebKitGTK есть то, чего нет у Windows-порта: встроенный сервер удалённой отладки. Если запустить процесс с переменной окружения WEBKIT_INSPECTOR_SERVER=127.0.0.1:<порт>, WebKit откроет на этом порту сервер, к которому можно подключиться как фронтенд инспектора. Никаких окон, горячих клавиш и ввода с клавиатуры.
Answer42 выбирает свободный локальный порт и передаёт переменную тест-клиенту при запуске (для этого runtime.start_test_client получил параметр extra_env). Дальше — протокол.
Протокол удалённого инспектора
Протокол удалённого инспектора описан в исходном коде WebKitGTK — открытого проекта. В актуальных версиях это собственный SocketConnection поверх TCP; сообщение устроено так:
|
Поле |
Формат |
|
Размер тела |
uint32, big endian |
|
Флаги |
uint8; бит 0 — параметры в little-endian |
|
Тело |
имя сообщения, завершённое NUL, затем параметры в формате GVariant |
Answer42 использует пять сообщений:
|
Сообщение |
Сигнатура GVariant |
Направление и смысл |
|
SetupInspectorClient |
(ay) |
клиент → сервер: регистрация фронтенда |
|
SetTargetList |
(ta(tsssb)) |
сервер → клиент: соединение и список целей (id, тип, заголовок, URL, есть ли локальный отладчик) |
|
Setup |
(tt) |
клиент → сервер: подключиться к цели |
|
SendMessageToBackend |
(tts) |
клиент → сервер: JSON протокола инспектора |
|
SendMessageToFrontend |
(tts) |
сервер → клиент: ответы и события |
Для сериализации GVariant мы не стали тянуть PyGObject: кодировщик и декодер нужных сигнатур занимают пару десятков строк на чистом Python (выравнивание t по 8 байт, строки с NUL, таблица смещений для элементов переменной длины в конце структуры и массива).
Страницы как цели и домен Target
Каждое поле HTML-документа — цель типа WebPage. Протокол инспектора для таких целей мультиплексирован доменом Target: после Setup приходит событие Target.targetCreated с идентификатором page-цели, а Runtime.evaluate нужно заворачивать в Target.sendMessageToTarget и ждать ответ в событии Target.dispatchMessageFromTarget:
→ {"id":7,"method":"Target.sendMessageToTarget",
"params":{"targetId":"page-65",
"message":"{\"id\":7,\"method\":\"Runtime.evaluate\",\"params\":{...,\"returnByValue\":true}}"}}
← {"id":7,"result":{}}
← {"method":"Target.dispatchMessageFromTarget",
"params":{"targetId":"page-65","message":"{\"id\":7,\"result\":{\"result\":{\"value\":...}}}"}}
При навигации WebKit создаёт новую page-цель и сообщает об этом через Target.didCommitProvisionalTarget — Answer42 переключается на неё сам. Ещё одна особенность: тонкий клиент держит несколько скрытых WebView с about:blank. Пустые страницы Answer42 пропускает, а about:blank с содержимым (HTML-поле, заполненное текстом, а не URL) оставляет.
На Linux подключение к странице занимает около половины секунды — заметно быстрее, чем на Windows.
Сервер отладки слушает только 127.0.0.1 и не требует авторизации: любой процесс на машине может подключиться к нему и выполнить код в странице. Для тестовых стендов это приемлемо, для рабочих мест пользователей — нет.
Linux, способ 2: мост в интерфейсе инспектора через G_RESOURCE_OVERLAYS
Удалённый отладчик удобен, но у него есть цена: открытый порт без авторизации и запуск клиента в режиме отладки. Второй способ работает со встроенным инспектором — тем же, что открывает разработчик по Ctrl+Alt+Shift+F12, — и не открывает никаких портов. В Answer42 это режим html_mode=patched на Linux.
Как подложить мост, ничего не меняя в системе
На Windows интерфейс инспектора — это обычные файлы рядом с платформой. В WebKitGTK он поставляется иначе: как ресурсы GLib (GResource), встроенные в саму библиотеку libwebkit2gtk. Менять системную библиотеку мы, разумеется, не будем. Но у GLib есть штатный механизм для разработчиков — переменная окружения G_RESOURCE_OVERLAYS: она позволяет для конкретного процесса подменить ресурс по его пути файлом из указанного каталога. Это описанная в документации GIO возможность, предназначенная как раз для отладки интерфейсов без пересборки.
Answer42 подменяет ровно один ресурс интерфейса инспектора — файл локализованных строк localizedStrings.js из /org/webkit/inspector/Localizations/en.lproj. Интерфейс инспектора загружает его при открытии в любом случае. Наша версия файла содержит три вещи:
- пустой словарь строк — интерфейс инспектора просто показывает исходные английские подписи;
- параметры сессии: порт локального WebSocket Answer42 и одноразовый токен;
- мост — около пятидесяти строк ES5, которые встраиваются в обмен сообщениями между интерфейсом инспектора и страницей.
Файл лежит в каталоге сессии, а переменная передаётся только процессу тест-клиента:
G_RESOURCE_OVERLAYS=/org/webkit/inspector/Localizations/en.lproj=<каталог сессии>/inspector-overlay
Ничего не устанавливается, права администратора не нужны, системные файлы и платформа не меняются; когда сессия завершается, вместе с процессом клиента исчезает и подмена.
Как открыть инспектор
Инспектор встроенного WebKitGTK открывается тем же сочетанием Ctrl+Alt+Shift+F12 и встраивается в форму. Есть особенность: виджеты GTK — не отдельные окна X11, поэтому клавиши получает элемент, на котором стоит фокус. Answer42 сначала ставит фокус в нужное HTML-поле штатным методом клиента тестирования (активация элемента формы), а затем отправляет сочетание в окно клиента через xdotool (расширение XTEST сервера X — обычный способ эмулировать клавиатуру, в том числе в Xvfb).
По той же причине на Linux нельзя повторить Windows-способ с вводом загрузчика в консоль: клавиши уходят не в консоль инспектора, а в элемент страницы с фокусом. В проверке набранный загрузчик попал в поле ввода чата и был отправлен как сообщение. Поэтому на Linux Answer42 такой режим отклоняет.
Что делает мост в интерфейсе инспектора
Интерфейс инспектора общается со страницей через объекты InspectorFrontendHost (отправка команд) и InspectorFrontendAPI (приём ответов и событий). Мост подключается к Answer42 по WebSocket с одноразовым токеном и:
- отправляет присланные Answer42 команды протокола инспектора — Runtime.evaluate с операциями над страницей — через InspectorFrontendHost.sendMessageToBackend;
- перехватывает ответы на свои команды (у них идентификаторы из отдельного диапазона) и пересылает их Answer42, не показывая в интерфейсе инспектора; всё остальное интерфейс получает как обычно;
- учитывает домен Target: в WebKitGTK команды странице заворачиваются в Target.sendMessageToTarget, а ответы приходят в Target.dispatchMessageFromTarget;
- пересылает события Console.messageAdded — поэтому html_console видит сообщения консоли с момента загрузки страницы.
Интерфейс инспектора переживает перезагрузку страницы, поэтому и мост не нужно подключать заново. Если инспектор откроет человек без сессии Answer42, мост ничего не делает: у него нет параметров подключения.
Сравнение двух способов
|
|
Удалённый отладчик (remote) |
Мост в инспекторе (patched) |
|
Механизм |
WEBKIT_INSPECTOR_SERVER — сервер отладки WebKitGTK |
G_RESOURCE_OVERLAYS — подмена одного ресурса интерфейса инспектора |
|
Открытый порт |
да, 127.0.0.1 без авторизации |
нет; мост сам подключается к Answer42 с одноразовым токеном |
|
Окно инспектора |
не открывается |
встроено в форму, видно на скриншотах |
|
Что нужно на машине |
ничего |
xdotool |
|
Подключение к странице |
около 0,5 с |
около 0,8 с |
|
Сообщения консоли |
с загрузки страницы |
с загрузки страницы |
|
Режим в Answer42 |
html_mode=remote, по умолчанию на Linux |
html_mode=patched |
По умолчанию на Linux Answer42 использует удалённый отладчик: он не требует дополнительных пакетов и не занимает место на форме. Мост в инспекторе выбирают, когда открытый отладочный порт нежелателен.
Только документированные возможности
Важный для нас принцип: мост не вмешивается в платформу и не опирается на её внутреннее устройство. Обе ветки используют то, что описано и поддерживается их авторами:
- Windows — сочетание Ctrl+Alt+Shift+F12, которым платформа 1С открывает инструменты разработчика для поля HTML-документа в тонком клиенте. Это штатный инструмент отладки встроенных веб-страниц. Answer42 лишь нажимает его программно и вводит код в штатную консоль — так же, как это сделал бы разработчик руками.
- Linux, первый способ — переменная окружения WEBKIT_INSPECTOR_SERVER: известная, описанная в документации WebKitGTK возможность включить сервер удалённой отладки у любого приложения на WebKitGTK. Её поддерживает сам WebKitGTK, а не 1С; Answer42 передаёт её только процессу тест-клиента.
- Linux, второй способ — переменная окружения GLib G_RESOURCE_OVERLAYS, штатный механизм GIO для подмены ресурсов приложения файлами при отладке, и то же сочетание Ctrl+Alt+Shift+F12, отправленное через стандартное расширение XTEST сервера X. Подменяется один файл интерфейса инспектора и только для процесса тест-клиента.
Чего мы сознательно не делаем: не изменяем файлы платформы и интерфейс инспектора, не внедряемся в процесс 1cv8c, не перехватываем его сетевой трафик и не подменяем сертификаты, не используем недокументированные ключи и внутренние API. Поэтому мост не зависит от внутреннего устройства конкретной сборки платформы, не требует прав администратора и не меняет установленную платформу — все изменения живут ровно столько, сколько живёт сессия тест-клиента.
Почему не обработка или расширение в тестируемой базе
Естественный вопрос: зачем мост к WebKit, если можно написать обработку или расширение, открыть его в клиенте тестирования и работать с HTML-полем средствами встроенного языка? Такой подход возможен, но в реальной эксплуатации он проигрывает почти по всем пунктам.
- Модель сервиса. В облачных базах (1cfresh, 42Clouds и аналогичных) открытие внешних обработок пользователем запрещено, а расширение можно установить только через механизмы сервиса, с проверкой и профилями безопасности. Тестировать «как есть» нельзя: сначала нужно согласовать и опубликовать код, который к тому же не имеет отношения к самой проверке. Answer42 в тестируемую базу ничего не загружает — менеджер тестирования со своей обработкой работает в отдельной локальной базе, а тестируемая база видит только обычного пользователя тонкого клиента.
- Тестируется ровно то, что будет у пользователя. Расширение меняет конфигурацию: может потребовать реструктуризации и монопольного режима, повлиять на права, на безопасный режим, на поведение форм и на результат самой проверки. Мост не меняет ни метаданные, ни данные, ни права — после завершения сессии в базе не остаётся следов.
- Не нужны лишние права. Для внешней обработки тестовому пользователю нужно право интерактивного открытия внешних обработок, для расширения — права администратора. Мосту достаточно тех прав, с которыми пользователь и так работает с формой.
- Одно решение для всех конфигураций. Бухгалтерия, Управление торговлей, ERP, отраслевые и самописные конфигурации, разные режимы совместимости — мосту всё равно, что за конфигурация: он работает на уровне клиента, а не метаданных. Обработку или расширение пришлось бы проверять и поддерживать под каждую конфигурацию и её версии.
- Асинхронность веб-приложения. Ответ чата, подгрузка данных, перерисовка — всё это происходит в странице асинхронно. Из встроенного языка такие изменения приходится отслеживать опросом через клиентские вызовы. Ожидания Answer42 (html_wait) выполняются прямо в странице и возвращают результат сразу, как только условие выполнено.
- Ошибки консоли и совместимость. Встроенный язык не видит консоль страницы: ни ошибок загрузки скриптов, ни необработанных исключений. html_console и проверка скриптов показывают их агенту напрямую — это главный инструмент для поиска кода, несовместимого со встроенным WebKit.
- Готовый результат для агента. Ответы приходят агенту в JSON без промежуточной сериализации DOM во встроенном языке и обратно; длинные тексты и структуры элементов не упираются в ограничения передачи данных между клиентом и сервером 1С.
- Одинаково на всех стендах. Один и тот же сценарий работает на базе разработчика, на тестовом стенде, на копии рабочей базы и в облаке — без развёртывания, согласования и удаления служебного кода на каждом из них.
Сводно:
|
|
Обработка / расширение в базе |
Мост Answer42 |
|
Модель сервиса (открытие обработок запрещено) |
нужны согласование и публикация кода |
работает без изменений в базе |
|
Изменения в тестируемой базе |
метаданные расширения, возможна реструктуризация |
нет |
|
Права тестового пользователя |
открытие внешних обработок или администрирование |
обычные права работы с формой |
|
Ожидание асинхронных изменений страницы |
опросом из встроенного языка |
html_wait в самой странице |
|
Ошибки консоли и совместимость скриптов |
недоступны |
html_console, проверка скриптов |
|
Разные конфигурации и стенды |
сопровождение под каждую |
одно решение |
Операции над страницей: одна функция на ES5
Чтение, поиск, клик и ввод выполняются одинаково на обеих платформах: Answer42 отправляет в страницу вызов самодостаточной функции OPS_JS(op, args) и получает JSON. Функция написана на ES5 — встроенный WebKit Windows-клиента не понимает многое из современного JavaScript (подробнее ниже). Операции: info, text, html, query, click, type, eval, hook_console, console, check_scripts.
Несколько деталей, которые важны для современных фронтенд-фреймворков:
- Ввод. Простое присваивание el.value = ... React и похожие библиотеки не замечают — они перехватывают сеттер свойства. Поэтому type вызывает нативный сеттер value из прототипа HTMLInputElement / HTMLTextAreaElement, затем генерирует события input и change. С submit=true дополнительно отправляется Enter (keydown/keypress/keyup с keyCode=13) и при наличии — submit формы.
- Клик. click прокручивает элемент в видимую область, ставит фокус и генерирует mousedown, mouseup и click — некоторые компоненты реагируют только на первые два.
- Поиск. Элемент ищется CSS-селектором и/или по тексту (вхождение или точное совпадение), с индексом среди совпадений. query возвращает тег, id, класс, value, href, placeholder, role, aria-label и видимость — этого агенту хватает, чтобы понять структуру незнакомой страницы.
- Результат. Возвращаемое значение приводится к JSON: DOM-элементы описываются, коллекции превращаются в массивы, глубина ограничена.
html_console: ошибки консоли и «неподдержанный синтаксис»
Пока мы разбирались со встроенным WebKit, стал очевиден ещё один сценарий: веб-приложение, которое прекрасно работает в браузере, может просто не запуститься в тонком клиенте. Поэтому появился инструмент html_console — ошибки и предупреждения консоли страницы плюс проверка её скриптов.
- Linux. Answer42 включает домен Console на каждой page-цели, и WebKit отдаёт сообщения с момента загрузки страницы — включая ошибки разбора скриптов.
- Windows. Мост появляется в странице только при подключении, поэтому ранние ошибки он не видит. С момента подключения он перехватывает window.onerror (включая ошибки загрузки ресурсов), unhandledrejection и console.error/console.warn; момент начала сбора указан в поле collected_since.
- Проверка скриптов (check_scripts). Каждый <script> страницы — встроенный или загруженный по src — заново компилируется через new Function(...). Так находятся скрипты, которые этот WebKit не может разобрать, даже если ошибка случилась до подключения моста.
В демо-обработке есть второй встроенный скрипт — «современный» помощник страницы с оператором опциональной цепочки, как его сгенерировал бы бандлер без транспиляции. Кроме него, мы добавили в страницу отложенный вызов несуществующей функции:
var preferredTheme = window.matchMedia?.('(prefers-color-scheme: dark)')?.matches; // <script> страницы
setTimeout(function(){ answer42MissingFunction(); }, 0);
|
Клиент |
Что вернул html_console |
|
Windows |
проверка скриптов: inline script #1 — SyntaxError: Unexpected token '.' (строка 4); консоль: ReferenceError: Can't find variable: answer42MissingFunction. Ошибка разбора случилась при загрузке, до подключения моста, — её нашла только проверка скриптов |
|
Linux (WebKitGTK 2.36) |
только ReferenceError — оператор ?. здесь поддерживается |
Вывод практический: одна и та же страница может работать в Linux-клиенте и ломаться в Windows-клиенте. html_console позволяет поймать такие проблемы автоматически, ещё до того, как их найдут пользователи.
Инструменты
Группа html включается сама после start_session (мост теперь запускается по умолчанию, html_agent=true). Если живых страниц несколько, нужная выбирается параметром page — идентификатором из html_pages или частью URL / заголовка.
|
Инструмент |
Назначение |
|
html_pages |
список живых страниц HTML-полей; подключает новые и перезагрузившиеся |
|
html_text |
текст страницы или элементов по CSS-селектору |
|
html_query |
элементы по селектору или тексту с атрибутами и видимостью |
|
html_click |
нажать элемент |
|
html_type |
ввести значение в поле, при submit=true — отправить |
|
html_wait |
дождаться появления или исчезновения текста или элемента |
|
html_eval |
выполнить произвольный JavaScript в странице |
|
html_console |
ошибки и предупреждения консоли, проверка синтаксиса скриптов |
Так выглядит сценарий агента на демо-обработке: открыть её, задать вопрос чату и прочитать ответ (MCP-вызовы в упрощённой записи):
start_session(execute="DemoHtmlField.epf") # встроенная демо-база + /Execute
html_pages() # → [{page: "p1", url: "about:blank"}]
html_query(selector="button, textarea") # → textarea#input, button#send «Отправить»
html_type(selector="#input", value="Какие остатки на складе?", submit=true)
html_wait(text="бумага А4") # ответ пришёл через 0,7 с
html_text(selector="#log") # вся переписка текстом
html_console() # → inline script #1: SyntaxError (?.)
stop_session()
Результаты живых прогонов (платформа 8.5.1.1343): Windows — демо-обработка во встроенной демо-базе на скрытом рабочем столе; Linux — веб-приложение в поле HTML-документа на Debian 13 с Xvfb:
|
Проверка |
Windows (скрытый рабочий стол) |
Linux (Debian 13, Xvfb) |
|
html_pages — первое подключение |
5 с |
0,5 с |
|
последующие команды |
доли секунды |
доли секунды |
|
html_query, html_type, html_wait, html_text |
работают |
работают |
|
html_console: ошибки с момента загрузки |
только проверкой скриптов |
да, из домена Console |
|
ошибка «элемент не найден» |
ошибка инструмента |
ошибка инструмента |
Какие возможности это открывает
- Тестирование встроенных веб-приложений. Чаты с ИИ-ассистентами, онлайн-сервисы (ЭДО, банк-клиенты, маркетплейсы, карты), редакторы и дашборды на JavaScript внутри форм теперь можно проверять тем же сценарием и тем же агентом, что и обычные формы 1С.
- Сквозной (end-to-end) тест ИИ-ассистента внутри 1С. Агент задаёт вопрос встроенному ассистенту как пользователь, дожидается ответа и сверяет его с данными базы — через обычные инструменты Answer42 (table_rows, tabular_documents, отчёты). Получается «агент, который тестирует агента».
- Совместимость с тонким клиентом. html_console и проверка скриптов ловят код, который не разбирается встроенным WebKit, и разницу между Windows- и Linux-клиентом — до выхода в продуктив, а не по жалобам пользователей.
- Чтение данных из HTML-представлений. Отчёты, справки и карточки, которые конфигурация показывает HTML-ом, агент читает как текст или структуру DOM, а не по скриншоту.
- Диагностика. html_eval даёт доступ к состоянию страницы: переменным приложения, localStorage, результатам сетевых запросов — то, что раньше требовало ручной работы в инспекторе.
- Доказательная запись. Шаги с HTML-полями попадают в PDF-отчёт Answer42 вместе со скриншотами окна, как и остальные действия.
Ограничения
- На Windows инспектор остаётся встроенным в нижнюю часть формы и виден на скриншотах.
- Первое подключение к странице на Windows занимает около 5 секунд, на Linux — около секунды.
- На Windows html_console собирает сообщения с момента подключения моста; ранние ошибки находит только проверка скриптов.
- Поддерживаются тонкий клиент Windows (встроенный WebKit) и Linux (WebKitGTK). Веб-клиент 1С работает в обычном браузере — для него есть другие инструменты.
- Порт удалённого отладчика на Linux не защищён авторизацией — только для тестовых стендов.
Итог
- На Windows инспектор остаётся встроенным в нижнюю часть формы и виден на скриншотах.
- Первое подключение к странице на Windows занимает около 5 секунд, на Linux — около секунды.
- На Windows html_console собирает сообщения с момента подключения моста; ранние ошибки находит только проверка скриптов.
- Поддерживаются тонкий клиент Windows (встроенный WebKit) и Linux (WebKitGTK). Веб-клиент 1С работает в обычном браузере — для него есть другие инструменты.
- Порт удалённого отладчика на Linux не защищён авторизацией — только для тестовых стендов.
Итог
Поле HTML-документа перестало быть «чёрным ящиком» для автоматизации тонкого клиента. Мост к встроенному WebKit — около тысячи строк Python и одна функция на ES5; он опирается только на штатные инструменты разработчика и работает на обеих платформах тонкого клиента. Самое интересное, на наш взгляд, — то, что это открывает: автоматическое тестирование встроенных ИИ-ассистентов и веб-приложений тем же агентом, который уже умеет работать с формами 1С.
Про остальные возможности Answer42 можно почитать в предыдущей статье: //infostart.ru/1c/articles/2779743/
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.