From ba19b4111df5c90136a64d046a063bedce407c17 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 5 Apr 2026 14:57:52 +0300 Subject: [PATCH] =?UTF-8?q?feat(web-test):=20=D1=81=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B5=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D1=83=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B5=D0=B3=D1=80=D0=B5?= =?UTF-8?q?=D1=81=D1=81-=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 22 шага: cf-init → meta-compile (10 объектов) → form-compile (3 формы, вкл. 2 вкладки для Номенклатуры) → skd-compile → subsystem-compile (Склад + Администрирование) → role-compile (полные права) → cf-validate. Расширения: иерархический справочник, разнотипные реквизиты (Number, Boolean, Date, String unlimited), FillChecking, вторая подсистема. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/web-test-runner-spec.md | 2 +- .../integration/build-webtest-config.test.mjs | 361 ++++++++++++++++++ 2 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 tests/skills/integration/build-webtest-config.test.mjs diff --git a/docs/web-test-runner-spec.md b/docs/web-test-runner-spec.md index 3ab062f9..ffa5ad4e 100644 --- a/docs/web-test-runner-spec.md +++ b/docs/web-test-runner-spec.md @@ -784,6 +784,6 @@ function buildContext({ noRecord = false } = {}) -> object | 5 | Хуки (prepare/cleanup + before/after) | run.mjs: поддержка _hooks.mjs | #3 | done 2026-04-05 | | 6 | Файл конфигурации + контексты | run.mjs: webtest.config.mjs, BrowserContext'ы, маршрутизация | #3 | config done, BrowserContext pending | | 7 | Форматы отчётов (Allure, JUnit) | run.mjs: --format=allure/junit | #3 | -- | -| 8 | Синтетическая конфигурация | integration/build-webtest-config.test.mjs | спека | -- | +| 8 | Синтетическая конфигурация | integration/build-webtest-config.test.mjs | спека | done 2026-04-05 | | 9 | Smoke-тесты (01-06) | tests/web-test/01-06*.test.mjs | #3, #8 | -- | | 10 | Остальные тесты (07-13) | tests/web-test/07-13*.test.mjs | #9 | -- | diff --git a/tests/skills/integration/build-webtest-config.test.mjs b/tests/skills/integration/build-webtest-config.test.mjs new file mode 100644 index 00000000..350a0de8 --- /dev/null +++ b/tests/skills/integration/build-webtest-config.test.mjs @@ -0,0 +1,361 @@ +// build-webtest-config.test.mjs — Integration test: build synthetic configuration for web-test regression +// Extends base-config with: diverse field types, hierarchical catalog, two-tab form, +// second subsystem, full-rights role. +// Steps: cf-init → meta-compile → form-add + form-compile → skd-compile +// → subsystem-compile → role-compile → cf-edit → cf-validate + +export const name = 'Сборка конфигурации для web-test'; +export const setup = 'none'; +export const cache = 'webtest-config'; + +export const steps = [ + // ── 1. Init empty configuration ── + { + name: 'cf-init: пустая конфигурация', + script: 'cf-init/scripts/cf-init', + args: { '-Name': 'ТестоваяВебКонфигурация', '-OutputDir': '{workDir}' }, + validate: { script: 'cf-validate/scripts/cf-validate', flag: '-ConfigPath' }, + }, + + // ── 2. Metadata objects ── + + // Справочник Контрагенты — простой, для CRUD и ссылочных полей + { + name: 'meta-compile: Справочник Контрагенты', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Catalog', name: 'Контрагенты', + codeLength: 9, descriptionLength: 100, + attributes: [ + { name: 'ИНН', type: 'String', length: 12 }, + { name: 'Телефон', type: 'String', length: 20 }, + { name: 'Адрес', type: 'String', length: 200 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Catalogs/Контрагенты' }, + }, + + // Справочник Номенклатура — иерархический, все типы полей + { + name: 'meta-compile: Справочник Номенклатура', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Catalog', name: 'Номенклатура', + codeLength: 11, descriptionLength: 150, + hierarchical: true, + attributes: [ + { name: 'Артикул', type: 'String', length: 25 }, + { name: 'Цена', type: 'Number', length: 15, precision: 2 }, + { name: 'Активен', type: 'Boolean' }, + { name: 'ДатаПоступления', type: 'Date' }, + { name: 'Комментарий', type: 'String' }, + { name: 'ЕдиницаИзмерения', type: 'String', length: 10 }, + ], + fillChecking: { 'Description': 'ShowError' }, + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Catalogs/Номенклатура' }, + }, + + // Перечисление ВидыНоменклатуры + { + name: 'meta-compile: Перечисление ВидыНоменклатуры', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Enum', name: 'ВидыНоменклатуры', + values: ['Товар', 'Услуга', 'Работа'], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Enums/ВидыНоменклатуры' }, + }, + + // Документ ПриходнаяНакладная — шапка + ТЧ + { + name: 'meta-compile: Документ ПриходнаяНакладная', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Document', name: 'ПриходнаяНакладная', + attributes: [ + { name: 'Контрагент', type: 'String', length: 100 }, + { name: 'Склад', type: 'String', length: 50 }, + { name: 'Комментарий', type: 'String', length: 200 }, + ], + tabularSections: [{ + name: 'Товары', + attributes: [ + { name: 'Номенклатура', type: 'String', length: 150 }, + { name: 'Количество', type: 'Number', length: 15, precision: 3 }, + { name: 'Цена', type: 'Number', length: 15, precision: 2 }, + { name: 'Сумма', type: 'Number', length: 15, precision: 2 }, + ], + }], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Documents/ПриходнаяНакладная' }, + }, + + // Регистр накопления ОстаткиТоваров + { + name: 'meta-compile: Регистр накопления ОстаткиТоваров', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'AccumulationRegister', name: 'ОстаткиТоваров', + registerType: 'Balance', + dimensions: [ + { name: 'Номенклатура', type: 'String', length: 150 }, + ], + resources: [ + { name: 'Количество', type: 'Number', length: 15, precision: 3 }, + { name: 'Сумма', type: 'Number', length: 15, precision: 2 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'AccumulationRegisters/ОстаткиТоваров' }, + }, + + // Регистр сведений КурсыВалют + { + name: 'meta-compile: Регистр сведений КурсыВалют', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'InformationRegister', name: 'КурсыВалют', + writeMode: 'RecorderSubordinate', + dimensions: [ + { name: 'Валюта', type: 'String', length: 10 }, + ], + resources: [ + { name: 'Курс', type: 'Number', length: 10, precision: 4 }, + { name: 'Кратность', type: 'Number', length: 10 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'InformationRegisters/КурсыВалют' }, + }, + + // Константа ОсновнаяВалюта + { + name: 'meta-compile: Константа ОсновнаяВалюта', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Constant', name: 'ОсновнаяВалюта', + valueType: 'String', length: 10, + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Constants/ОсновнаяВалюта' }, + }, + + // Общий модуль ОбщиеФункции + { + name: 'meta-compile: Общий модуль ОбщиеФункции', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'CommonModule', name: 'ОбщиеФункции', + server: true, clientManagedApplication: false, + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'CommonModules/ОбщиеФункции' }, + }, + + // Отчёт ОстаткиТоваров + { + name: 'meta-compile: Отчёт ОстаткиТоваров', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Report', name: 'ОстаткиТоваров', + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Reports/ОстаткиТоваров' }, + }, + + // ── 3. Forms ── + + // Форма элемента Контрагенты — простая + { + name: 'form-add: Форма элемента Контрагенты', + script: 'form-add/scripts/form-add', + args: { '-ObjectPath': '{workDir}/Catalogs/Контрагенты.xml', '-FormName': 'ФормаЭлемента' }, + }, + { + name: 'form-compile: Форма элемента Контрагенты', + script: 'form-compile/scripts/form-compile', + input: { + title: 'Контрагент', + attributes: [ + { name: 'Объект', type: 'FormDataStructure', main: true }, + ], + elements: [ + { input: 'Наименование', path: 'Объект.Description', title: 'Наименование' }, + { input: 'ИНН', path: 'Объект.ИНН', title: 'ИНН' }, + { input: 'Телефон', path: 'Объект.Телефон', title: 'Телефон' }, + { input: 'Адрес', path: 'Объект.Адрес', title: 'Адрес' }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputPath': '{workDir}/Catalogs/Контрагенты/Forms/ФормаЭлемента/Ext/Form.xml' }, + validate: { script: 'form-validate/scripts/form-validate', flag: '-FormPath', path: 'Catalogs/Контрагенты/Forms/ФормаЭлемента/Ext/Form.xml' }, + }, + + // Форма элемента Номенклатура — 2 вкладки, все типы полей + { + name: 'form-add: Форма элемента Номенклатура', + script: 'form-add/scripts/form-add', + args: { '-ObjectPath': '{workDir}/Catalogs/Номенклатура.xml', '-FormName': 'ФормаЭлемента' }, + }, + { + name: 'form-compile: Форма элемента Номенклатура (2 вкладки)', + script: 'form-compile/scripts/form-compile', + input: { + title: 'Номенклатура', + attributes: [ + { name: 'Объект', type: 'FormDataStructure', main: true }, + ], + elements: [ + { pages: 'Страницы', children: [ + { page: 'Основное', children: [ + { input: 'Наименование', path: 'Объект.Description', title: 'Наименование' }, + { input: 'Артикул', path: 'Объект.Артикул', title: 'Артикул' }, + { input: 'Цена', path: 'Объект.Цена', title: 'Цена' }, + { input: 'Активен', path: 'Объект.Активен', title: 'Активен' }, + { input: 'ДатаПоступления', path: 'Объект.ДатаПоступления', title: 'Дата поступления' }, + ]}, + { page: 'Дополнительно', children: [ + { input: 'ЕдиницаИзмерения', path: 'Объект.ЕдиницаИзмерения', title: 'Единица измерения' }, + { input: 'Комментарий', path: 'Объект.Комментарий', title: 'Комментарий' }, + ]}, + ]}, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputPath': '{workDir}/Catalogs/Номенклатура/Forms/ФормаЭлемента/Ext/Form.xml' }, + validate: { script: 'form-validate/scripts/form-validate', flag: '-FormPath', path: 'Catalogs/Номенклатура/Forms/ФормаЭлемента/Ext/Form.xml' }, + }, + + // Форма документа ПриходнаяНакладная + { + name: 'form-add: Форма документа ПриходнаяНакладная', + script: 'form-add/scripts/form-add', + args: { '-ObjectPath': '{workDir}/Documents/ПриходнаяНакладная.xml', '-FormName': 'ФормаДокумента' }, + }, + { + name: 'form-compile: Форма документа ПриходнаяНакладная', + script: 'form-compile/scripts/form-compile', + input: { + title: 'Приходная накладная', + attributes: [ + { name: 'Объект', type: 'FormDataStructure', main: true }, + ], + elements: [ + { input: 'Контрагент', path: 'Объект.Контрагент', title: 'Контрагент' }, + { input: 'Склад', path: 'Объект.Склад', title: 'Склад' }, + { input: 'Комментарий', path: 'Объект.Комментарий', title: 'Комментарий' }, + { table: 'Товары', path: 'Объект.Товары', title: 'Товары', columns: [ + { input: 'Номенклатура', path: 'Объект.Товары.Номенклатура', title: 'Номенклатура' }, + { input: 'Количество', path: 'Объект.Товары.Количество', title: 'Количество' }, + { input: 'Цена', path: 'Объект.Товары.Цена', title: 'Цена' }, + { input: 'Сумма', path: 'Объект.Товары.Сумма', title: 'Сумма' }, + ]}, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputPath': '{workDir}/Documents/ПриходнаяНакладная/Forms/ФормаДокумента/Ext/Form.xml' }, + validate: { script: 'form-validate/scripts/form-validate', flag: '-FormPath', path: 'Documents/ПриходнаяНакладная/Forms/ФормаДокумента/Ext/Form.xml' }, + }, + + // ── 4. DCS for report ── + { + name: 'skd-compile: Схема отчёта ОстаткиТоваров', + script: 'skd-compile/scripts/skd-compile', + input: { + dataSets: [{ + name: 'НаборДанных', + type: 'Query', + query: 'SELECT Номенклатура, Количество, Сумма FROM AccumulationRegister.ОстаткиТоваров', + }], + fields: [ + { name: 'Номенклатура', title: 'Номенклатура' }, + { name: 'Количество', title: 'Количество' }, + { name: 'Сумма', title: 'Сумма' }, + ], + }, + args: { '-DefinitionFile': '{inputFile}', '-OutputPath': '{workDir}/Reports/ОстаткиТоваров/Templates/ОсновнаяСхемаКомпоновкиДанных/Ext/Template.xml' }, + validate: { script: 'skd-validate/scripts/skd-validate', flag: '-TemplatePath', path: 'Reports/ОстаткиТоваров/Templates/ОсновнаяСхемаКомпоновкиДанных/Ext/Template.xml' }, + }, + + // ── 5. Subsystems ── + { + name: 'subsystem-compile: Подсистема Склад', + script: 'subsystem-compile/scripts/subsystem-compile', + input: { + name: 'Склад', + synonym: 'Склад', + content: [ + 'Catalogs.Контрагенты', + 'Catalogs.Номенклатура', + 'Documents.ПриходнаяНакладная', + 'AccumulationRegisters.ОстаткиТоваров', + 'Reports.ОстаткиТоваров', + ], + }, + args: { '-DefinitionFile': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'subsystem-validate/scripts/subsystem-validate', flag: '-SubsystemPath', path: 'Subsystems/Склад' }, + }, + { + name: 'subsystem-compile: Подсистема Администрирование', + script: 'subsystem-compile/scripts/subsystem-compile', + input: { + name: 'Администрирование', + synonym: 'Администрирование', + content: [ + 'InformationRegisters.КурсыВалют', + 'Constants.ОсновнаяВалюта', + ], + }, + args: { '-DefinitionFile': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'subsystem-validate/scripts/subsystem-validate', flag: '-SubsystemPath', path: 'Subsystems/Администрирование' }, + }, + + // ── 6. Role with full rights ── + { + name: 'role-compile: Роль Администратор', + script: 'role-compile/scripts/role-compile', + input: { + name: 'Администратор', + objects: [ + 'Catalog.Контрагенты: Read View Add Update Delete', + 'Catalog.Номенклатура: Read View Add Update Delete', + 'Document.ПриходнаяНакладная: Read View Add Update Delete Posting UnPosting', + 'AccumulationRegister.ОстаткиТоваров: Read', + 'InformationRegister.КурсыВалют: Read View Add Update Delete', + 'Report.ОстаткиТоваров: Use View', + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'role-validate/scripts/role-validate', flag: '-RightsPath', path: 'Roles/Администратор' }, + }, + + // ── 7. Register all objects in Configuration.xml ── + { + name: 'cf-edit: Регистрация объектов в конфигурации', + script: 'cf-edit/scripts/cf-edit', + input: [ + { operation: 'add-childObject', value: 'Catalog.Контрагенты' }, + { operation: 'add-childObject', value: 'Catalog.Номенклатура' }, + { operation: 'add-childObject', value: 'Enum.ВидыНоменклатуры' }, + { operation: 'add-childObject', value: 'Document.ПриходнаяНакладная' }, + { operation: 'add-childObject', value: 'AccumulationRegister.ОстаткиТоваров' }, + { operation: 'add-childObject', value: 'InformationRegister.КурсыВалют' }, + { operation: 'add-childObject', value: 'Constant.ОсновнаяВалюта' }, + { operation: 'add-childObject', value: 'CommonModule.ОбщиеФункции' }, + { operation: 'add-childObject', value: 'Report.ОстаткиТоваров' }, + { operation: 'add-childObject', value: 'Subsystem.Склад' }, + { operation: 'add-childObject', value: 'Subsystem.Администрирование' }, + { operation: 'add-childObject', value: 'Role.Администратор' }, + ], + args: { '-ConfigPath': '{workDir}', '-DefinitionFile': '{inputFile}' }, + }, + + // ── 8. Final validation ── + { + name: 'cf-validate: Финальная валидация конфигурации', + script: 'cf-validate/scripts/cf-validate', + args: { '-ConfigPath': '{workDir}' }, + }, +];