fix(ui): ограничить таблицу соседей OSPF и сохранить URL узла
This commit is contained in:
1 parent
2554c3572a
commit
1a82c1b41f
8 files changed
+110
-17
No files matched your search
@@ -1,30 +1,65 @@
|
||||
import { test, expect } from "@playwright/test"
|
||||
import { writeFileSync } from "node:fs"
|
||||
import axe from "axe-core"
|
||||
import { ospfCatalogSchema } from "../../lib/ospf-response"
|
||||
|
||||
test("OSPF1000 соседей: профиль всего экрана с topology", async ({ page }, info) => {
|
||||
test.setTimeout(90000)
|
||||
const host = { serverId: 1, serverName: "Роутер 1", serverSite: "", serverCountry: "RU" }
|
||||
const neighbors = Array.from({ length: 1000 }, (_, i) => ({ ...host, id: `n${i + 1}`, address: `10.${Math.floor(i / 256)}.${i % 256}.1`, routerId: `10.${Math.floor(i / 256)}.${i % 256}.1`, instance: "default", area: "backbone", areaId: "0.0.0.0", interface: `ether${i + 1}`, state: "Full", uptime: "1h", stateChanges: 0, priority: 1 }))
|
||||
let neighbors = Array.from({ length: 1000 }, (_, i) => ({ ...host, id: `n${i + 1}`, address: `10.${Math.floor(i / 256)}.${i % 256}.1`, routerId: `10.${Math.floor(i / 256)}.${i % 256}.1`, instance: "default", area: "backbone", areaId: "0.0.0.0", interface: `ether${i + 1}`, state: "Full", uptime: "1h", stateChanges: 0, priority: 1 }))
|
||||
const interfaces = neighbors.map((n, i) => ({ ...host, id: `i${i + 1}`, instance: "default", area: "backbone", areaId: "0.0.0.0", interface: n.interface, cost: i + 1, type: "broadcast", disabled: false, inactive: false, priority: 1, helloInterval: 10, deadInterval: 40, useBfd: false }))
|
||||
const catalog = ospfCatalogSchema.parse({ neighbors, interfaces, instances: [{ ...host, id: "instance1", name: "default", routerId: "192.0.2.1", version: 2, disabled: false, inactive: false, redistribute: "" }], bfdSessions: [], routes: [], failures: [] })
|
||||
let failed = false, reads = 0
|
||||
const writes: string[] = []
|
||||
await page.route("**/health", r => r.fulfill({ json: { ok: true } }))
|
||||
await page.route("**/api/**", r => {
|
||||
const p = new URL(r.request().url()).pathname
|
||||
if (r.request().method() !== "GET") writes.push(p)
|
||||
if (p === "/api/ospf/catalog") { reads++; return r.fulfill(failed ? { status: 503, json: { error: "Каталог OSPF недоступен1000" } } : { json: { ...catalog, neighbors } }) }
|
||||
return r.fulfill({ json: p === "/api/auth/config" ? { required: false } : p === "/api/ospf/catalog" ? catalog : p === "/api/servers" ? [{ id: 1, name: "Роутер 1", host: "192.0.2.1", enabled: true, country: "RU", status: null }] : {} })
|
||||
})
|
||||
await page.setViewportSize({ width: 1440, height: 1000 })
|
||||
const start = Date.now(); await page.goto("/ospf?tab=neighbors&server=1&keep=1")
|
||||
const start = Date.now(); await page.goto("/ospf?tab=neighbors&server=1&node=remote-10.3.231.1&keep=1")
|
||||
const rows = page.locator("tr[data-row-id]")
|
||||
await expect(rows).toHaveCount(1000)
|
||||
await expect(rows).toHaveCount(50)
|
||||
await expect(rows.first()).toHaveAttribute("data-row-id", "1-n951")
|
||||
await expect(page.locator("[data-ospf-node]")).toHaveCount(1001)
|
||||
const profile = { count: neighbors.length, bytes: Buffer.byteLength(JSON.stringify(catalog)), rows: await rows.count(), graphNodes: await page.locator("[data-ospf-node]").count(), svgNodes: await page.getByRole("group", { name: "Топология OSPF", exact: true }).locator("*").count(), pageNodes: await page.locator("*").count(), readyMs: Date.now() - start }
|
||||
console.log("OSPF neighbors baseline", JSON.stringify(profile))
|
||||
console.log("OSPF neighbors table", JSON.stringify(profile))
|
||||
writeFileSync(info.outputPath("ospf-neighbors-profile.json"), JSON.stringify(profile, null, 2))
|
||||
await info.attach("profile", { body: JSON.stringify(profile), contentType: "application/json" })
|
||||
await page.addStyleTag({ content: "nextjs-portal{display:none!important}" })
|
||||
await page.screenshot({ path: info.outputPath("ospf-neighbors-baseline-1440.png"), animations: "disabled" })
|
||||
await page.screenshot({ path: info.outputPath("ospf-neighbors-table-1440.png"), animations: "disabled" })
|
||||
const next = page.getByRole("button", { name: "Следующая страница", exact: true })
|
||||
await expect(next).toBeDisabled()
|
||||
const before = reads; await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect.poll(() => reads).toBeGreaterThan(before); await expect(rows.first()).toHaveAttribute("data-row-id", "1-n951")
|
||||
await page.getByRole("button", { name: "Предыдущая страница", exact: true }).click()
|
||||
await expect(rows.first()).toHaveAttribute("data-row-id", "1-n901")
|
||||
const search = page.getByPlaceholder("Поиск в текущем разделе OSPF…")
|
||||
await search.fill("10.3.231.1"); await expect(rows).toHaveCount(1); await expect(rows.first()).toHaveAttribute("data-row-id", "1-n1000")
|
||||
await expect(page).toHaveURL(url => url.searchParams.get("q") === "10.3.231.1" && url.searchParams.get("keep") === "1")
|
||||
await page.reload(); await expect(rows).toHaveCount(1)
|
||||
await search.fill(""); await expect(rows).toHaveCount(50)
|
||||
await page.getByRole("table").getByRole("button", { name: "Cost", exact: true }).click()
|
||||
await expect(rows.first()).toHaveAttribute("data-row-id", "1-n1000")
|
||||
await next.click(); const previous = await rows.first().getAttribute("data-row-id")
|
||||
failed = true; await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(page.getByRole("alert").filter({ hasText: "Не удалось загрузить OSPF" })).toContainText("Показаны последние полученные данные")
|
||||
await expect(rows.first()).toHaveAttribute("data-row-id", previous!)
|
||||
await expect(rows.first()).toContainText("Неизвестно")
|
||||
await page.setViewportSize({ width: 320, height: 1000 })
|
||||
console.log("OSPF neighbors baseline mobileWidth", await page.evaluate(() => document.documentElement.scrollWidth))
|
||||
await page.screenshot({ path: info.outputPath("ospf-neighbors-baseline-320.png"), animations: "disabled" })
|
||||
const scroll = page.locator('[data-slot="data-grid"] [data-slot="scroll-area-viewport"]')
|
||||
await scroll.evaluate(el => { el.scrollLeft = el.scrollWidth })
|
||||
const pinned = rows.first().getByRole("cell").first()
|
||||
expect(await pinned.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)
|
||||
await rows.first().scrollIntoViewIfNeeded()
|
||||
await page.addScriptTag({ content: axe.source })
|
||||
expect((await page.evaluate(async () => (window as unknown as { axe: typeof axe }).axe.run(document.querySelector('[data-slot="data-grid"]')!, { runOnly: { type: "tag", values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"] } }))).violations.map(v => ({ id: v.id, nodes: v.nodes.map(n => n.target) }))).toEqual([])
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(320)
|
||||
await page.addStyleTag({ content: "nextjs-portal{display:none!important}" })
|
||||
await page.screenshot({ path: info.outputPath("ospf-neighbors-table-320.png"), animations: "disabled" })
|
||||
failed = false; neighbors = [neighbors[999]]; await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(rows).toHaveCount(1); await expect(rows.first()).toHaveAttribute("data-row-id", "1-n1000")
|
||||
expect(writes).toEqual([])
|
||||
})
|
||||
Reference in new issue
Block a user