From 2c2a3ef07839c99734ea59b0b4c3949ac9b1a159 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Thu, 24 Sep 2026 21:07:44 +0700 Subject: [PATCH] =?UTF-8?q?test(ui):=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=B8=D1=82=D1=8C=20=D0=BE=D1=82=D0=BC=D0=B5=D0=BD=D1=83?= =?UTF-8?q?=20=D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=B0=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D1=81=D0=BC=D0=B5=D0=BD=D0=B5=20=D1=81=D0=B5=D1=80=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ux-ui-progress.md | 7 +++++++ tests/e2e/traffic-flow.spec.ts | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md index 874e98d5..dbfa1196 100644 --- a/docs/ux-ui-progress.md +++ b/docs/ux-ui-progress.md @@ -29,6 +29,13 @@ | 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Не начат | | 12 | Итоговая доступность, адаптивность, производительность и регрессия | Не начат | +## Блок 8.4К — отмена SSE при смене сервера (2026-09-24) + +- Добавлен браузерный сценарий: задержка SSE первого сервера до ответа, переход ко второму, подтверждение requestfailed для отменённой подписки, получение нового измерения и завершение старого обработчика. Старый sample не заменяет данные второго сервера. +- 3 профильных E2E прошли: закрытый SSE, поздний REST с интерфейсом первого сервера и новая проверка отмены SSE. Lint теста/diff-check чистые. Production-код не менялся; build не повторялся. +- Граница проверки: задержка перед получением ответа, не chunk внутри уже открытого ReadableStream. Далее: смена backend, задержка read внутри SSE, свежесть данных и приёмка этапа 8. Реальные IPFIX/RouterOS не проверены. +- Пятичасовое окно обновилось; использовано 10%, недельного — 94%. Локальный коммит без push. + ## Блок 8.4И — интерфейс в контексте flow-сервера (2026-09-24) - Выбор flow-интерфейса хранится вместе с контекстом backend, live/mock, раздела, источника и объекта. Чужой интерфейс не используется при первом рендере нового контекста. При выборе карточки фильтр сбрасывается; синхронный сброс через useEffect удалён. diff --git a/tests/e2e/traffic-flow.spec.ts b/tests/e2e/traffic-flow.spec.ts index 8de6d6d2..289d1f2f 100644 --- a/tests/e2e/traffic-flow.spec.ts +++ b/tests/e2e/traffic-flow.spec.ts @@ -190,3 +190,35 @@ test('Flow: интерфейс прежнего сервера не переда await expect(page.getByText('Второй сервер', { exact: true }).filter({ visible: true })).toBeVisible() await expect(page.getByText('Категория 15m', { exact: true })).toHaveCount(0) }) + +test('Flow: смена сервера отменяет старую SSE-подписку', async ({ page }) => { + await setup(page) + await page.getByRole('button', { name: '15м', exact: true }).click() + await expect(page.getByText('Категория 15m', { exact: true }).filter({ visible: true })).toBeVisible() + let release = () => {} + const gate = new Promise(resolve => { release = resolve }) + let completed = () => {} + const delivered = new Promise(resolve => { completed = resolve }) + await page.route('**/api/traffic/flow/live?**', async route => { + const old = new URL(route.request().url()).searchParams.get('serverId') === '1' + if (old) await gate + const sample = { bpsNow: old ? 99000000 : 7000000, bytes: 200, packets: 2, conversations: 1, uniqueSrc: 1, uniqueDst: 1, topProto: 'TCP', topCategory: old ? 'SSE прежнего сервера' : 'SSE текущего сервера', rxSeries: [1], txSeries: [2], applications: [], protocols: [], sources: [], destinations: [], interfaces: [], conversationsList: [], ifaces: [], live: true } + try { + await route.fulfill({ contentType: 'text/event-stream', body: 'event: sample\ndata: ' + JSON.stringify(sample) + '\n\n' }) + } finally { + if (old) completed() + } + }) + const oldRequest = page.waitForRequest(r => r.url().includes('/flow/live?') && r.url().includes('serverId=1')) + await page.getByRole('button', { name: '5м', exact: true }).click() + await oldRequest + const aborted = page.waitForEvent('requestfailed', r => r.url().includes('/flow/live?') && r.url().includes('serverId=1')) + await page.getByRole('button').filter({ hasText: 'Экспортёр второй' }).click() + await aborted + await expect(page.getByText('SSE текущего сервера', { exact: true }).filter({ visible: true })).toBeVisible() + release() + await delivered + await expect(page.getByText('SSE прежнего сервера', { exact: true })).toHaveCount(0) + await expect(page.getByText('SSE текущего сервера', { exact: true }).filter({ visible: true })).toBeVisible() + await expect(page.getByLabel('Скорость потоков')).toContainText('7.00 Мбит/с') +})