Files
MikrotikManager/tests/e2e/large-optimizer-wan-matrix.spec.ts
T

71 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from "@playwright/test"
import axe from "axe-core"
import { writeFileSync } from "node:fs"
import { optimizerServersSchema } from "../../lib/route-optimizer-response"
for (const [wanCount,jhCount] of [[1000,1],[10,100]]) {
test(`Матрица WAN${wanCount} × JH${jhCount} без Exit`, async ({page},info) => {
test.setTimeout(90000)
const common = { host: "192.0.2.1", enabled: true, status: "online", latency: 10, country: "RU", site: "TEST", model: "CHR" }
let servers = optimizerServersSchema.parse([
{ ...common, id: 1, name: "Домашний роутер", type: "home-router", wanUplinks: Array.from({ length: wanCount }, (_, i) => ({ id: `wan${i+1}`, name: `WAN${i+1}`, isp: "ISP", iface: `ether${i+1}`, ip: `198.51.100.${i+1}`, maxDl: 100, maxUl: 100 })) },
...Array.from({ length: jhCount }, (_, i) => ({ ...common, id: i+2, name: `Jump ${i+1}`, type: "jump-host" })),
])
let reads = 0
const writes: string[] = []
await page.route("**/health", r => r.fulfill({ json: { ok: true } }))
await page.route("**/api/**", r => {
const path = new URL(r.request().url()).pathname
if (path === "/api/servers") reads++
if (r.request().method() !== "GET" && !path.endsWith("/preview")) writes.push(path)
return r.fulfill({ json: path === "/api/auth/config" ? { required: false } : path === "/api/servers" ? servers : path === "/api/filters/rules" ? { rulesets: [] } : path === "/api/uptime/speed-probes" ? { probes: [] } : path === "/api/ospf/catalog" ? { interfaces: [], instances: [], neighbors: [], bfdSessions: [], routes: [], failures: [] } : path.endsWith("/ospf/optimize/preview") ? { serverId: 1, serverName: "Домашний роутер", pingWeight: 60, interfacesTotal: 0, changedCount: 0, unchangedCount: 0, interfaces: [], changes: [] } : {} })
})
const started=Date.now(); await page.goto("/route-optimizer?server=1&keep=1")
const table=page.getByRole("table").filter({hasText:"WAN-аплинк"})
await expect(table.locator("tr[data-row-id]")).toHaveCount(Math.min(50,wanCount))
const profile={wanCount,jhCount,bytes:Buffer.byteLength(JSON.stringify(servers)),rows:await table.locator("tr[data-row-id]").count(),columns:await table.getByRole("columnheader").count(),tableNodes:await table.locator("*").count(),pageNodes:await page.locator("*").count(),readyMs:Date.now()-started}
console.log("WAN matrix",JSON.stringify(profile)); writeFileSync(info.outputPath("matrix-profile.json"),JSON.stringify(profile,null,2))
const root=page.getByRole("region",{name:"Матрица WAN и Jump Host"})
await expect(table.getByRole("columnheader")).toHaveCount(3+Math.min(5,jhCount))
if(wanCount>50){
const next=root.getByRole("button",{name:"Следующая страница",exact:true})
await next.click(); await expect(table.locator("tr[data-row-id]").first()).toHaveAttribute("data-row-id","wan51")
const before=reads; await page.getByRole("button",{name:"Обновить",exact:true}).click(); await expect.poll(()=>reads).toBeGreaterThan(before)
await expect(table.locator("tr[data-row-id]").first()).toHaveAttribute("data-row-id","wan51")
await root.getByRole("textbox",{name:"Поиск WAN",exact:true}).fill("WAN1000")
await expect(table.locator("tr[data-row-id]")).toHaveCount(1); await expect(table.locator("tr[data-row-id]").first()).toHaveAttribute("data-row-id","wan1000")
await root.getByRole("textbox",{name:"Поиск WAN",exact:true}).fill("")
for(let i=0;i<19;i++)await next.click()
await expect(next).toBeDisabled();await expect(table.locator("tr[data-row-id]").last()).toHaveAttribute("data-row-id","wan1000")
} else {
const next=root.getByRole("button",{name:"Следующие Jump Host",exact:true})
await next.click();await expect(table.getByRole("columnheader",{name:/Jump 6/})).toBeVisible()
const before=reads;await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect.poll(()=>reads).toBeGreaterThan(before)
await expect(table.getByRole("columnheader",{name:/Jump 6/})).toBeVisible()
await root.getByRole("textbox",{name:"Поиск Jump Host",exact:true}).fill("Jump 100")
await expect(table.getByRole("columnheader")).toHaveCount(4);await expect(table.getByRole("columnheader",{name:/Jump 100/})).toBeVisible()
await root.getByRole("textbox",{name:"Поиск Jump Host",exact:true}).fill("no-such-host")
await expect(root).toContainText("Jump Host: 0 из 100");await expect(table.getByRole("columnheader")).toHaveCount(3)
await root.getByRole("textbox",{name:"Поиск Jump Host",exact:true}).fill("")
for(let i=0;i<19;i++)await next.click()
await expect(next).toBeDisabled();await expect(table.getByRole("columnheader",{name:/Jump 100/})).toBeVisible()
}
await page.setViewportSize({width:320,height:1000})
const scroll=root.locator('[data-slot="scroll-area-viewport"]')
await scroll.evaluate(el=>{el.scrollLeft=el.scrollWidth})
expect(await table.locator('tr[data-row-id]').first().getByRole('cell').first().evaluate(el=>{const a=el.getBoundingClientRect(),v=el.closest('[data-slot="scroll-area-viewport"]')!.getBoundingClientRect();return a.left>=v.left-1&&a.right<=v.right+1})).toBe(true)
expect(await page.evaluate(()=>document.documentElement.scrollWidth)).toBeLessThanOrEqual(320)
await scroll.evaluate(el=>{el.scrollLeft=0});await root.evaluate(el=>el.scrollIntoView({block:"start"}))
await page.addStyleTag({content:"nextjs-portal{display:none!important}"});await page.screenshot({path:info.outputPath("matrix-320.png"),animations:"disabled"})
await page.addScriptTag({content:axe.source})
expect((await page.evaluate(async()=> (window as unknown as {axe:typeof axe}).axe.run(document.querySelector('[aria-label="Матрица WAN и Jump Host"]')!,{runOnly:{type:"tag",values:["wcag2a","wcag2aa","wcag21a","wcag21aa"]}}))).violations.map(v=>({id:v.id,nodes:v.nodes.map(n=>n.target)}))).toEqual([])
servers=servers.slice(0,2).map(server=>server.id===1?{...server,wanUplinks:server.wanUplinks!.slice(0,1)}:server)
await page.getByRole("button",{name:"Обновить",exact:true}).click()
await expect(table.locator('tr[data-row-id]')).toHaveCount(1);await expect(table.locator('tr[data-row-id]').first()).toHaveAttribute('data-row-id','wan1');await expect(table.getByRole('columnheader')).toHaveCount(4)
expect(writes).toEqual([])
})
}