test(ui): проверить отмену потока при смене сервера
This commit is contained in:
1 parent
c563583ccb
commit
2c2a3ef078
2 files changed
+39
No files matched your search
@@ -29,6 +29,13 @@
|
|||||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Не начат |
|
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Не начат |
|
||||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Не начат |
|
| 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)
|
## Блок 8.4И — интерфейс в контексте flow-сервера (2026-09-24)
|
||||||
|
|
||||||
- Выбор flow-интерфейса хранится вместе с контекстом backend, live/mock, раздела, источника и объекта. Чужой интерфейс не используется при первом рендере нового контекста. При выборе карточки фильтр сбрасывается; синхронный сброс через useEffect удалён.
|
- Выбор flow-интерфейса хранится вместе с контекстом backend, live/mock, раздела, источника и объекта. Чужой интерфейс не используется при первом рендере нового контекста. При выборе карточки фильтр сбрасывается; синхронный сброс через useEffect удалён.
|
||||||
|
|||||||
@@ -190,3 +190,35 @@ test('Flow: интерфейс прежнего сервера не переда
|
|||||||
await expect(page.getByText('Второй сервер', { exact: true }).filter({ visible: true })).toBeVisible()
|
await expect(page.getByText('Второй сервер', { exact: true }).filter({ visible: true })).toBeVisible()
|
||||||
await expect(page.getByText('Категория 15m', { exact: true })).toHaveCount(0)
|
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<void>(resolve => { release = resolve })
|
||||||
|
let completed = () => {}
|
||||||
|
const delivered = new Promise<void>(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 Мбит/с')
|
||||||
|
})
|
||||||
Reference in new issue
Block a user