test(ui): проверить поздний фрагмент открытого потока
This commit is contained in:
1 parent
53bca894bb
commit
7318c5286b
3 files changed
+73
-3
No files matched your search
@@ -222,3 +222,66 @@ test('Flow: смена сервера отменяет старую SSE-подп
|
||||
await expect(page.getByText('SSE текущего сервера', { exact: true }).filter({ visible: true })).toBeVisible()
|
||||
await expect(page.getByLabel('Скорость потоков')).toContainText('7.00 Мбит/с')
|
||||
})
|
||||
|
||||
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()
|
||||
// Deliberately let the mock stream deliver a chunk after abort. This exercises
|
||||
// the post-read guard, independently of the browser transport's cancellation.
|
||||
await page.evaluate(() => {
|
||||
const originalFetch = window.fetch.bind(window)
|
||||
const state = { pending: false, aborted: false, delivered: false, release: () => {} }
|
||||
Object.assign(window, { delayedFlowStream: state })
|
||||
window.fetch = async (input, init) => {
|
||||
const url = new URL(input instanceof Request ? input.url : String(input), location.href)
|
||||
if (url.pathname !== '/api/traffic/flow/live') return originalFetch(input, init)
|
||||
const old = url.searchParams.get('serverId') === '1'
|
||||
const sample = (late = false) => ({
|
||||
bpsNow: old ? (late ? 99000000 : 1000000) : 7000000,
|
||||
bytes: 200, packets: 2, conversations: 1, uniqueSrc: 1, uniqueDst: 1,
|
||||
topProto: 'TCP', topCategory: old ? (late ? 'Поздний фрагмент' : 'Открытый поток первого') : 'Открытый поток второго',
|
||||
rxSeries: [1], txSeries: [2], applications: [], protocols: [], sources: [],
|
||||
destinations: [], interfaces: [], conversationsList: [], ifaces: [], live: true,
|
||||
})
|
||||
const encode = (late = false) => new TextEncoder().encode('event: sample\ndata: ' + JSON.stringify(sample(late)) + '\n\n')
|
||||
const stream = new ReadableStream<Uint8Array>({
|
||||
start(controller) {
|
||||
controller.enqueue(encode())
|
||||
if (old) state.release = () => controller.enqueue(encode(true))
|
||||
},
|
||||
})
|
||||
const response = new Response(stream, { headers: { 'Content-Type': 'text/event-stream' } })
|
||||
if (old) {
|
||||
init?.signal?.addEventListener('abort', () => { state.aborted = true })
|
||||
const reader = stream.getReader()
|
||||
const read = reader.read.bind(reader)
|
||||
let calls = 0
|
||||
reader.read = async () => {
|
||||
const delayed = ++calls === 2
|
||||
if (delayed) state.pending = true
|
||||
const result = await read()
|
||||
if (delayed) { state.pending = false; state.delivered = true }
|
||||
return result
|
||||
}
|
||||
stream.getReader = (() => reader) as typeof stream.getReader
|
||||
}
|
||||
return response
|
||||
}
|
||||
})
|
||||
await page.getByRole('button', { name: '5м', exact: true }).click()
|
||||
await expect(page.getByText('Открытый поток первого', { exact: true }).filter({ visible: true })).toBeVisible()
|
||||
const streamState = () => page.evaluate(() => {
|
||||
const state = (window as unknown as { delayedFlowStream: { pending: boolean; aborted: boolean; delivered: boolean } }).delayedFlowStream
|
||||
return { pending: state.pending, aborted: state.aborted, delivered: state.delivered }
|
||||
})
|
||||
await expect.poll(streamState).toEqual({ pending: true, aborted: false, delivered: false })
|
||||
await page.getByRole('button').filter({ hasText: 'Экспортёр второй' }).click()
|
||||
await expect(page.getByText('Открытый поток второго', { exact: true }).filter({ visible: true })).toBeVisible()
|
||||
await expect.poll(streamState).toEqual({ pending: true, aborted: true, delivered: false })
|
||||
await page.evaluate(() => (window as unknown as { delayedFlowStream: { release: () => void } }).delayedFlowStream.release())
|
||||
await expect.poll(streamState).toEqual({ pending: false, aborted: true, delivered: true })
|
||||
await expect(page.getByText('Поздний фрагмент', { exact: true })).toHaveCount(0)
|
||||
await expect(page.getByText('Открытый поток второго', { exact: true }).filter({ visible: true })).toBeVisible()
|
||||
await expect(page.getByLabel('Скорость потоков')).toContainText('7.00 Мбит/с')
|
||||
})
|
||||
Reference in new issue
Block a user