From 70be567b13504a67446a1a1e94a5f9e44cb4a38f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 27 May 2026 18:25:26 +0300 Subject: [PATCH] =?UTF-8?q?test(web-test):=20=D0=BF=D0=BE=D0=BA=D1=80?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D0=B5=20multi-select=20(Ctrl/Shift=20+=20cli?= =?UTF-8?q?ckElement)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clickElement поддерживает modifier: 'ctrl'|'shift' для multi-select строк списка с момента введения, но не было ни одного теста. Добавлен 17-multiselect.test.mjs: - ctrl-add: click+ctrl-click → 2 выделенные строки - shift-range: shift-click формирует диапазон от anchor'а - readTable отмечает _selected: true на выделенных строках Полный регресс 20/20 зелёный. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/web-test/17-multiselect.test.mjs | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/web-test/17-multiselect.test.mjs diff --git a/tests/web-test/17-multiselect.test.mjs b/tests/web-test/17-multiselect.test.mjs new file mode 100644 index 00000000..1c4e0818 --- /dev/null +++ b/tests/web-test/17-multiselect.test.mjs @@ -0,0 +1,50 @@ +export const name = 'multi-select: clickElement с modifier ctrl/shift на gridRow'; +export const tags = ['table', 'multi-select']; +export const timeout = 60000; + +// Покрытие feature `modifier: 'ctrl' | 'shift'` у clickElement для grid-row. +// Ctrl+click добавляет строку в выделение; Shift+click выделяет диапазон от +// anchor'a (последнего non-modifier клика). readTable отмечает выделенные +// строки полем _selected: true. +// +// Свежая синтетика содержит ровно 4 Контрагентов (ООО Север, ООО Юг, ООО +// Восток, ООО Запад). Используем их для предсказуемых проверок. + +export default async function({ navigateSection, openCommand, clickElement, readTable, closeForm, assert, step, log }) { + + await step('setup: открыть список Контрагентов', async () => { + await navigateSection('Склад'); + await openCommand('Контрагенты'); + const t = await readTable(); + log(`Контрагентов в списке: ${t.total}`); + assert.ok(t.total >= 3, `Нужно как минимум 3 строки для multi-select теста, есть ${t.total}`); + }); + + await step('ctrl-add: click ООО Север + ctrl-click ООО Юг → 2 выделенные строки', async () => { + await clickElement('ООО Север'); + await clickElement('ООО Юг', { modifier: 'ctrl' }); + const t = await readTable(); + const selected = t.rows.filter(r => r._selected).map(r => r['Наименование']); + log(`selected after ctrl-add: ${JSON.stringify(selected)}`); + assert.equal(selected.length, 2, '2 выделенные строки после ctrl-add'); + assert.includes(selected, 'ООО Север', 'ООО Север выделен'); + assert.includes(selected, 'ООО Юг', 'ООО Юг выделен'); + }); + + await step('shift-range: shift-click на третью строку → диапазон выделен', async () => { + // Сбрасываем выделение одиночным кликом, anchor = ООО Север + await clickElement('ООО Север'); + // Shift+click на ООО Восток (третий по списку) — должен выделить Север..Восток + await clickElement('ООО Восток', { modifier: 'shift' }); + const t = await readTable(); + const selected = t.rows.filter(r => r._selected).map(r => r['Наименование']); + log(`selected after shift-range: ${JSON.stringify(selected)}`); + assert.ok(selected.length >= 2, `Диапазон должен включать минимум 2 строки, выделено ${selected.length}`); + assert.includes(selected, 'ООО Север', 'anchor ООО Север в диапазоне'); + assert.includes(selected, 'ООО Восток', 'shift-target ООО Восток в диапазоне'); + }); + + await step('cleanup: закрыть форму', async () => { + await closeForm(); + }); +}