fix(ui): распознавать CRLF и комментарии в потоке SSE

This commit is contained in:
Denozordec committed 2026-09-28 11:38:11 +07:00
1 parent f50a29f116
commit ed491c313f
8 files changed
+38 -15

No files matched your search

+12 -2
View File
@@ -10,8 +10,14 @@ export async function installOpenLiveStream(page: Page, path: string, sample: un
if (url.pathname !== path) return originalFetch(input, init)
const stream = new ReadableStream<Uint8Array>({
start(controller) {
const send = () => controller.enqueue(new TextEncoder().encode('event: sample\ndata: ' + JSON.stringify(sample) + '\n\n'))
Object.assign(window, { sendLiveSample: send })
const encode = (value: string) => new TextEncoder().encode(value)
const send = () => {
// A comment may precede an event; CRLF delimiters may cross chunks.
controller.enqueue(encode(': heartbeat\r\nevent: sample\r\ndata: ' + JSON.stringify(sample) + '\r\n\r'))
controller.enqueue(encode('\n'))
}
const heartbeat = () => controller.enqueue(encode(': heartbeat\r\n\r\n'))
Object.assign(window, { sendLiveSample: send, sendLiveHeartbeat: heartbeat })
send()
},
})
@@ -23,3 +29,7 @@ export async function installOpenLiveStream(page: Page, path: string, sample: un
export async function resumeLiveStream(page: Page) {
await page.evaluate(() => (window as unknown as { sendLiveSample: () => void }).sendLiveSample())
}
export async function sendLiveHeartbeat(page: Page) {
await page.evaluate(() => (window as unknown as { sendLiveHeartbeat: () => void }).sendLiveHeartbeat())
}
+4 -2
View File
@@ -1,4 +1,4 @@
import { installOpenLiveStream, resumeLiveStream } from "./live-stream-fixture"
import { installOpenLiveStream, resumeLiveStream, sendLiveHeartbeat } from "./live-stream-fixture"
import { test, expect, type Page } from '@playwright/test'
async function setup(page: Page) {
@@ -328,7 +328,9 @@ test('Flow: молчащий SSE сохраняет данные и восста
const receipt = page.getByLabel('Получение аналитики потоков').locator('time')
await expect(page.getByText('live', { exact: true }).filter({ visible: true })).toHaveCount(3)
const stamp = await receipt.getAttribute('datetime')
await page.clock.fastForward(15_001)
await page.clock.fastForward(10_000)
await sendLiveHeartbeat(page)
await page.clock.fastForward(5_001)
await expect(page.getByText('Нет обновлений live более 15 секунд', { exact: true })).toBeVisible()
await expect(page.getByText('live', { exact: true })).toHaveCount(0)
await expect(page.getByLabel('Скорость потоков')).toContainText('1.00 Мбит/с')
+4 -2
View File
@@ -1,4 +1,4 @@
import { installOpenLiveStream, resumeLiveStream } from "./live-stream-fixture"
import { installOpenLiveStream, resumeLiveStream, sendLiveHeartbeat } from "./live-stream-fixture"
import { test, expect } from '@playwright/test'
for (const variant of ['closed', 'invalid', 'http-error', 'silent'] as const) {
@@ -32,7 +32,9 @@ for (const variant of ['closed', 'invalid', 'http-error', 'silent'] as const) {
if (variant === 'silent') {
await expect(summary.getByText('live', { exact: true }).filter({ visible: true })).toHaveCount(2)
const stamp = await page.getByLabel('Последнее измерение сервера').locator('time').first().getAttribute('datetime')
await page.clock.fastForward(15_001)
await page.clock.fastForward(10_000)
await sendLiveHeartbeat(page)
await page.clock.fastForward(5_001)
await expect(summary.getByText('live', { exact: true })).toHaveCount(0)
await expect(summary).toContainText('17.0')
await expect(page.getByLabel('Последнее измерение сервера').locator('time').first()).toHaveAttribute('datetime', stamp!)