export const name = 'DCS-отчёт: structured smoke + быстрый пользовательский фильтр'; export const tags = ['report', 'smoke']; export const timeout = 90000; export default async function({ navigateSection, openCommand, getFormState, getCommands, clickElement, selectValue, fillFields, readSpreadsheet, closeForm, wait, assert, step, log }) { await step('navigation: команда отчёта зарегистрирована в подсистеме Склад', async () => { const r = await navigateSection('Склад'); const flat = (r.commands || []).flat(); log(`commands: ${JSON.stringify(flat)}`); assert.ok(flat.includes('Остатки товаров'), 'В подсистеме Склад есть команда «Остатки товаров»'); }); await step('open: openCommand отрывает форму отчёта с кнопкой Сформировать', async () => { const s = await openCommand('Остатки товаров'); log(`form=${s.form} formCount=${s.formCount} buttons=${s.buttons?.map(b => b.name).join(',')}`); assert.equal(s.formCount, 1, 'Открыта одна форма'); const submit = s.buttons?.find(b => b.name === 'Сформировать'); assert.ok(submit, 'Есть кнопка «Сформировать»'); assert.equal(submit.default, true, '«Сформировать» — кнопка по умолчанию'); }); await step('reset: сброс пользовательских настроек к стандартным', async () => { // 1С хранит пользовательские настройки между сессиями — сбрасываем к дефолту, // чтобы тест был идемпотентным независимо от предыдущих прогонов. await clickElement('Еще'); await clickElement('Установить стандартные настройки'); }); await step('quickAccess: быстрый фильтр Номенклатура виден и выключен по умолчанию', async () => { const s = await getFormState(); log(`reportSettings: ${JSON.stringify(s.reportSettings)}`); assert.ok(Array.isArray(s.reportSettings) && s.reportSettings.length === 1, 'Один быстрый фильтр в reportSettings'); const f = s.reportSettings[0]; assert.equal(f.name, 'Номенклатура', 'Имя фильтра — заголовок DCS-поля'); assert.equal(f.enabled, false, '@off — выключен по умолчанию'); assert.equal(f.value, '', 'Значение пустое'); assert.ok(Array.isArray(f.actions) && f.actions.includes('select'), 'Доступно действие select'); }); let baseRowCount = 0; let baseTotalSum = ''; await step('generate: отчёт без фильтра возвращает все строки', async () => { await clickElement('Сформировать'); await wait(3); const r = await readSpreadsheet(); log(`headers=${JSON.stringify(r.headers)} total=${r.total} totals=${JSON.stringify(r.totals)}`); assert.deepEqual(r.headers, ['Номенклатура', 'Количество', 'Сумма'], 'Заголовки колонок отчёта'); assert.ok(r.data?.length >= 2, 'В отчёте есть строки данных'); assert.ok(r.totals?.['Сумма'], 'Есть итог по Сумме'); baseRowCount = r.data.length; baseTotalSum = r.totals['Сумма']; }); await step('apply filter: selectValue включает чекбокс и подставляет значение', async () => { const r = await selectValue('Номенклатура', 'Товар 02'); log(`selected: ${JSON.stringify(r.selected)}`); assert.ok(r.selected, 'selectValue вернул объект selected'); const after = await getFormState(); const f = after.reportSettings?.[0]; log(`after filter: ${JSON.stringify(f)}`); assert.equal(f.enabled, true, 'Чекбокс быстрого фильтра автоматически включился'); assert.equal(f.value, 'Товар 02', 'Подставилось выбранное значение'); }); await step('regenerate: отчёт с фильтром возвращает только подходящие строки', async () => { await clickElement('Сформировать'); await wait(3); const r = await readSpreadsheet(); log(`filtered total=${r.total} rows=${r.data?.length} totals=${JSON.stringify(r.totals)}`); assert.ok(r.data.length < baseRowCount, `Строк меньше чем без фильтра (${r.data.length} < ${baseRowCount})`); const named = r.data.filter(row => row['Номенклатура']); assert.ok(named.length >= 1, 'Есть хотя бы одна именованная строка'); assert.ok(named.every(row => row['Номенклатура'] === 'Товар 02'), 'Все именованные строки относятся к «Товар 02»'); const sumKey = Object.keys(r.totals).find(k => k.includes('Сумма')); assert.ok(sumKey, 'В totals есть колонка Суммы (платформа дописывает контекст фильтра)'); assert.notEqual(r.totals[sumKey], baseTotalSum, 'Итог по Сумме изменился после применения фильтра'); }); await step('clear filter: выключение чекбокса возвращает полный набор данных', async () => { // Снять быстрый фильтр через toggle off — fillFields с 'false' выключает чекбокс, // value сохраняется (платформа помнит последний выбор для повторного включения), // но данные при перерасчёте возвращаются к нефильтрованному набору. const r = await fillFields({ 'Номенклатура': 'false' }); log(`toggle off: ${JSON.stringify(r.filled)}`); const after = await getFormState(); assert.equal(after.reportSettings[0].enabled, false, 'Чекбокс выключен'); await clickElement('Сформировать'); await wait(3); const report = await readSpreadsheet(); log(`after clear: rows=${report.data?.length} totals=${JSON.stringify(report.totals)}`); assert.equal(report.data.length, baseRowCount, 'Восстановилось исходное число строк'); assert.equal(report.totals['Сумма'], baseTotalSum, 'Восстановился исходный итог по Сумме'); }); await step('cleanup: закрываем форму отчёта', async () => { const r = await closeForm(); log(`closed=${r.closed} formCount=${r.formCount}`); assert.equal(r.closed, true, 'Форма закрылась'); }); }