import { test, expect, type Page } from "@playwright/test" import { observedTrafficFixturePayload } from "./traffic-observation-fixture" async function setup(page: Page, terminal = true) { const control = { calls: 0, release: () => {} } const gate = new Promise(resolve => { control.release = resolve }) const server = { id:"1",name:"CHR live",site:"TEST",country:"RU",status:"online",rxNow:2,txNow:3,rxPeak:4,txPeak:5,rxTotal:1,txTotal:2,sessions:1,rxSeries:[1,2],txSeries:[2,3] } await page.route("**/health",r=>r.fulfill({json:{ok:true}})) await page.route("**/api/**",async r=>{ const path=new URL(r.request().url()).pathname if(path.endsWith("/live")) { control.calls++ if(control.calls>1) await gate const sample={rxMbps:control.calls===1?17:0,txMbps:0,at:"2026-10-12T12:00:00Z",timestampKind:"backend-receipt"} const end=terminal&&control.calls===1?'event: error\ndata: '+JSON.stringify({error:"Устройство выключено. Live-поток остановлен"})+'\n\n':'' return r.fulfill({contentType:"text/event-stream",body:'event: sample\ndata: '+JSON.stringify(sample)+'\n\n'+end}) } return r.fulfill({json:observedTrafficFixturePayload(path==="/api/auth/config"?{required:false}:path==="/api/traffic/servers"?{servers:[server]}:path==="/api/traffic/servers/1"?{server}:path.endsWith("/interfaces")||path==="/api/traffic/bound-interfaces"?{interfaces:[]}:path==="/api/traffic/users"?{users:[]}:path==="/api/servers"?[]:{})}) }) await page.goto("/traffic") await expect(page.getByRole("heading",{name:"CHR live",exact:true})).toBeVisible() return control } for(const width of [1440,320])test(`Причина закрытия live сохранена, переподключение сохраняет последнее значение ${width}`,async({page})=>{ await page.setViewportSize({width,height:1000});const c=await setup(page) const status=page.getByRole("status").filter({hasText:"Live-поток: нет свежих данных"}) await expect(status).toContainText("Устройство выключено") await expect(status).not.toContainText("Поток live завершён") await expect(page.getByLabel("Скорость выбранного сервера")).toContainText("17.0") await expect(page.getByLabel("Последнее измерение сервера")).toContainText("ответ RouterOS получен приложением") await status.scrollIntoViewIfNeeded() await status.evaluate(el => { let parent=el.parentElement;while(parent&&(!/auto|scroll/.test(getComputedStyle(parent).overflowY)||parent.scrollHeight<=parent.clientHeight))parent=parent.parentElement;if(parent)parent.scrollTop+=el.getBoundingClientRect().top-parent.getBoundingClientRect().top-24 }) await page.screenshot({path:`docs/ux-ui/screens/traffic-live-error-${width}-2026-10-12.png`,fullPage:true}) await page.getByRole("button",{name:"Переподключить live",exact:true}).click() await expect.poll(()=>c.calls).toBe(2) await expect(page.getByRole("status").filter({hasText:"Подключение live-потока"})).toBeVisible() await expect(page.getByLabel("Скорость выбранного сервера")).toContainText("17.0") c.release();await expect(page.getByLabel("Скорость выбранного сервера")).not.toContainText("17.0") await expect(page.getByLabel("Скорость выбранного сервера").getByText("0 Кбит/с",{exact:true})).toHaveCount(2) expect(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth+1)).toBe(true) })