Files
MikrotikManager/tests/e2e/traffic-short-history.spec.ts
T
Denozordec e461dc21bd
Docker images / prepare-release (push) Successful in 9s
Docker images / backend-test (push) Successful in 4m3s
Docker images / frontend-image (push) Successful in 2m13s
Docker images / updater-image (push) Successful in 39s
Docker images / netflow-agent-image (push) Successful in 31s
Docker images / backend-image (push) Successful in 1m37s
Docker images / publish-release (push) Successful in 13s
Docker images / notify-webhook (push) Successful in 2s
fix(traffic): строить непрерывную историю коротких периодов
2026-10-16 19:27:30 +07:00

39 lines
3.2 KiB
TypeScript

import {test, expect} from '@playwright/test'
import {buildTrafficFromSamples} from '../../backend/src/services/traffic-rate'
for (const mode of ['servers','flows'] as const) for (const minutes of [5,15]) {
test(`${mode}: ${minutes} минут рисуются линией`, async ({page}) => {
const end=Date.now(), name='Короткая история'
const history=(span:number)=>buildTrafficFromSamples(Array.from({length:span*2+1},(_,i)=>({
interfaceName:'ether1',sampledAt:new Date(end-span*60000+i*30000).toISOString(),
rxBytes:i*3750000,txBytes:i*1875000,rxBps:0,txBps:0,running:true,disabled:false,
})),end-span*60000,end,undefined,undefined,true)
await page.route('**/health',r=>r.fulfill({json:{ok:true}}))
await page.route('**/api/**',r=>{
const url=new URL(r.request().url()),path=url.pathname,span=url.searchParams.get('range')==='5m'?5:url.searchParams.get('range')==='15m'?15:60
const built=history(span),server={id:'1',name,site:'TEST',country:'RU',status:'online',...built,rxTotal:1,txTotal:1,volumeUnit:'GiB'}
const card={id:'1',name,subtitle:'',site:'TEST',country:'RU',status:'online',rxNow:1,txNow:0,sessions:1,bytes:60000,rxSeries:[1,2,1],txSeries:[0,0,0]}
const analytics={bpsNow:1000000,bytes:60000,packets:10,conversations:1,uniqueSrc:1,uniqueDst:1,topProto:'TCP',rxSeries:Array.from({length:span},(_,i)=>1+i%3),txSeries:Array(span).fill(0),applications:[],protocols:[],sources:[],destinations:[],interfaces:[],conversationsList:[],ifaces:[],live:false}
if(path.endsWith('/live'))return r.fulfill({status:503,json:{error:'Live выключен в проверке истории'}})
const json=path==='/api/auth/config'?{required:false}:path==='/api/traffic/servers'?{servers:[server]}:
path==='/api/traffic/servers/1'?{server}:path==='/api/traffic/flow/exporters'?{exporters:[card]}:
path==='/api/traffic/flow/analytics'?analytics:path==='/api/traffic/flow/clients'?{clients:[]}:
path==='/api/traffic/flows'?{exportersOnline:1,bytesPerMin:1,uniqueSrc:1,uniqueDst:1,topProto:'TCP',talkers:[],listenerBound:true}:
path==='/api/traffic/users'?{users:[]}:path.endsWith('/interfaces')||path.endsWith('/bound-interfaces')?{interfaces:[]}:
path==='/api/servers'?[]:{}
return r.fulfill({json})
})
await page.goto('/traffic')
if(mode==='flows')await page.getByRole('group',{name:'Разделы трафика'}).getByRole('button',{name:'Потоки',exact:true}).click()
await page.getByRole('button',{name:`${minutes}м`,exact:true}).click()
const chart=page.getByRole('region',{name:'История RX/TX'})
await expect(chart).toBeVisible()
const curves=chart.locator('path.recharts-line-curve')
await expect(curves).toHaveCount(2)
await expect.poll(async()=>((await curves.first().getAttribute('d'))?.match(/[CL]/g)||[]).length).toBeGreaterThan(2)
await expect.poll(()=>curves.first().evaluate(el=>(el as SVGGraphicsElement).getBBox().width/el.closest('[role="region"]')!.clientWidth)).toBeGreaterThan(0.7)
await expect(chart.locator('[data-isolated-direction]')).toHaveCount(0)
await page.screenshot({path:`tmp/netflow-agent-stand/traffic-short-${mode}-${minutes}.png`,fullPage:true})
})
}