diff --git a/tests/skills/integration/build-webtest-config.test.mjs b/tests/skills/integration/build-webtest-config.test.mjs index 101593a7..f3837a2b 100644 --- a/tests/skills/integration/build-webtest-config.test.mjs +++ b/tests/skills/integration/build-webtest-config.test.mjs @@ -144,6 +144,9 @@ export const steps = [ // (04-selectvalue/direct-form проверяет open-form path; история обходит его). { name: 'Контрагент', type: 'CatalogRef.Контрагенты', choiceHistoryOnInput: 'DontUse' }, { name: 'Склад', type: 'String', length: 50 }, + // Источник — составной тип (для 03-fillfields/composite). + // Платформа покажет селектор типа в UI перед выбором значения. + { name: 'Источник', type: 'CatalogRef.Контрагенты + CatalogRef.Номенклатура + CatalogRef.Организации' }, { name: 'Комментарий', type: 'String', length: 200 }, ], tabularSections: [{ @@ -154,6 +157,8 @@ export const steps = [ { name: 'Цена', type: 'Number', length: 15, precision: 2 }, { name: 'Сумма', type: 'Number', length: 15, precision: 2 }, { name: 'Согласовано', type: 'Boolean' }, + // Источник — составной тип в ТЧ (для edit-dblclick через выбор типа) + { name: 'Источник', type: 'CatalogRef.Контрагенты + CatalogRef.Номенклатура + CatalogRef.Организации' }, ], }], }, @@ -595,6 +600,7 @@ export const steps = [ { input: 'Организация', path: 'Объект.Организация', title: 'Организация' }, { input: 'Контрагент', path: 'Объект.Контрагент', title: 'Контрагент' }, { input: 'Склад', path: 'Объект.Склад', title: 'Склад' }, + { input: 'Источник', path: 'Объект.Источник', title: 'Источник' }, { input: 'Комментарий', path: 'Объект.Комментарий', title: 'Комментарий' }, { table: 'Товары', path: 'Объект.Товары', title: 'Товары', changeRowSet: true, columns: [ { input: 'Номенклатура', path: 'Объект.Товары.Номенклатура', title: 'Номенклатура' }, @@ -602,6 +608,10 @@ export const steps = [ { input: 'Цена', path: 'Объект.Товары.Цена', title: 'Цена' }, { input: 'Сумма', path: 'Объект.Товары.Сумма', title: 'Сумма' }, { check: 'Согласовано', path: 'Объект.Товары.Согласовано', title: 'Согласовано' }, + // Имя элемента отличается от Источник (в шапке) — иначе ContextMenu + // companion-имена дублируются в одной форме. form-compile использует + // имя элемента, не путь, для генерации companion-имён. + { input: 'ИсточникТЧ', path: 'Объект.Товары.Источник', title: 'Источник' }, ]}, ], }, diff --git a/tests/web-test/03-fillfields.test.mjs b/tests/web-test/03-fillfields.test.mjs index 06b7e7f5..39b4f47e 100644 --- a/tests/web-test/03-fillfields.test.mjs +++ b/tests/web-test/03-fillfields.test.mjs @@ -1,10 +1,10 @@ export const name = 'fillFields: text, checkbox, date, dropdown, reference'; export const tags = ['fillfields', 'smoke']; -export const timeout = 60000; +export const timeout = 120000; const findField = (state, name) => state.fields?.find(f => f.name === name || f.label === name); -export default async function({ navigateSection, openCommand, clickElement, fillFields, filterList, closeForm, getFormState, assert, step, log }) { +export default async function({ navigateSection, openCommand, clickElement, fillFields, fillTableRow, selectValue, filterList, closeForm, getFormState, assert, step, log }) { await step('text+checkbox+date+dropdown: fillFields на Номенклатура', async () => { await navigateSection('Склад'); @@ -122,4 +122,36 @@ export default async function({ navigateSection, openCommand, clickElement, fill await closeForm({ save: false }); }); + + await step('composite: selectValue с {type} в шапке и ТЧ накладной', async () => { + // ПриходнаяНакладная.Источник — составной тип: + // CatalogRef.Контрагенты + CatalogRef.Номенклатура + CatalogRef.Организации + // fillFields без type→ошибка с подсказкой «specify the type»; + // selectValue('Источник', value, {type:'Контрагенты'}) выбирает тип в диалоге. + await navigateSection('Склад'); + await openCommand('Приходная накладная'); + await clickElement('Создать'); + + // Шапка: выбор Контрагента в составном поле + const headRes = await selectValue('Источник', 'ООО Север', { type: 'Контрагенты' }); + log('header: type=' + headRes.selected?.type + ' method=' + headRes.selected?.method); + assert.equal(headRes.selected?.method, 'form', 'composite header → method=form'); + assert.equal(headRes.selected?.type, 'Контрагенты', 'type=Контрагенты выбран'); + + const state1 = await getFormState(); + const headField = state1.fields?.find(f => f.name === 'Источник'); + assert.equal(headField?.value, 'ООО Север', 'значение в шапке установилось'); + + // ТЧ: добавить строку, выбрать тип Организация (квик-чойс — без формы выбора) + await clickElement('Добавить'); + const rowRes = await fillTableRow( + { Источник: { value: 'Альфа', type: 'Организации' } }, + { row: 0 }, + ); + log('row: ' + JSON.stringify(rowRes.filled?.[0])); + assert.equal(rowRes.filled?.[0]?.ok, true, 'composite row → ok'); + assert.equal(rowRes.filled?.[0]?.type, 'Организации', 'выбран тип Организации в ТЧ'); + + await closeForm({ save: false }); + }); }