fix(ui): ограничить карточки оптимизатора с сохранением URL
This commit is contained in:
1 parent
7265709b1c
commit
059fd93520
10 files changed
+123
-11
No files matched your search
@@ -1,22 +1,54 @@
|
||||
import { test, expect } from "@playwright/test"
|
||||
import { writeFileSync } from "node:fs"
|
||||
import axe from "axe-core"
|
||||
import { optimizerServersSchema } from "../../lib/route-optimizer-response"
|
||||
|
||||
test("Оптимизатор1000 домашних устройств: профиль полного экрана", async ({ page }, info) => {
|
||||
test.setTimeout(90000)
|
||||
const servers = optimizerServersSchema.parse(Array.from({ length: 1000 }, (_, i) => ({ id: i+1, name: `Домашний роутер ${i+1}`, host: `10.${Math.floor(i/256)}.${i%256}.1`, type: "home-router", country: "RU", site: "MSK", enabled: true, status: null })))
|
||||
let servers = optimizerServersSchema.parse(Array.from({ length: 1000 }, (_, i) => ({ id: i+1, name: `Домашний роутер ${i+1}`, host: `10.${Math.floor(i/256)}.${i%256}.1`, type: "home-router", country: "RU", site: "MSK", enabled: true, status: null })))
|
||||
let failed = false
|
||||
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 (r.request().method() !== "GET" && !path.endsWith("/preview")) writes.push(path)
|
||||
if (path === "/api/servers" && failed) return r.fulfill({ status: 503, json: { error: "Каталог домашних устройств недоступен" } })
|
||||
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: servers[0].name, pingWeight: 60, interfacesTotal: 0, changedCount: 0, unchangedCount: 0, interfaces: [], changes: [] } : {} })
|
||||
})
|
||||
const start = Date.now(); await page.goto("/route-optimizer?server=1&keep=1")
|
||||
const start = Date.now(); await page.goto("/route-optimizer?server=1&keep=1&home_page=200")
|
||||
const cards = page.getByRole("button", { name: "WAN × JH (0×0)", exact: true })
|
||||
await expect(cards).toHaveCount(1000)
|
||||
await expect(cards).toHaveCount(5)
|
||||
const scope = page.getByRole("region", { name: "Домашние устройства оптимизатора" })
|
||||
await expect(scope.getByRole("status")).toContainText("996–1000 из 1000")
|
||||
await expect(scope.getByText("Домашний роутер 996", { exact: true })).toBeVisible()
|
||||
const profile = { servers: servers.length, bytes: Buffer.byteLength(JSON.stringify(servers)), homeCards: await cards.count(), pageNodes: await page.locator("*").count(), readyMs: Date.now()-start }
|
||||
console.log("Optimizer homes", JSON.stringify(profile)); writeFileSync(info.outputPath("optimizer-homes-profile.json"), JSON.stringify(profile, null, 2))
|
||||
console.log("Optimizer homes pages", JSON.stringify(profile)); writeFileSync(info.outputPath("optimizer-homes-profile.json"), JSON.stringify(profile, null, 2))
|
||||
await scope.getByRole("button", { name: "Предыдущая страница домашних устройств" }).click()
|
||||
await expect(scope.getByRole("status")).toContainText("991–995 из 1000")
|
||||
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(scope.getByRole("status")).toContainText("991–995 из 1000")
|
||||
const search = scope.getByRole("textbox", { name: "Поиск домашних устройств оптимизатора" })
|
||||
await search.fill("Домашний роутер 1000"); await expect(cards).toHaveCount(1)
|
||||
await expect(scope.getByText("Домашний роутер 1000", { exact: true })).toBeVisible()
|
||||
await page.reload(); await expect(cards).toHaveCount(1); await expect(search).toHaveValue("Домашний роутер 1000")
|
||||
await expect(page).toHaveURL(url => url.searchParams.get("keep") === "1" && url.searchParams.get("server") === "1")
|
||||
await search.fill(""); await expect(cards).toHaveCount(5)
|
||||
await expect(scope.getByText("Домашний роутер 1", { exact: true })).toBeVisible()
|
||||
await page.goBack(); await expect(scope.getByRole("status")).toContainText("996–1000 из 1000")
|
||||
failed = true; await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(page.getByRole("alert").filter({ hasText: "Последний полный снимок" })).toBeVisible()
|
||||
await expect(scope.getByRole("status")).toContainText("996–1000 из 1000")
|
||||
await page.addStyleTag({ content: "nextjs-portal{display:none!important}" })
|
||||
await page.setViewportSize({ width: 320, height: 1000 })
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(320)
|
||||
await page.screenshot({ path: info.outputPath("optimizer-homes-baseline-320.png"), animations: "disabled" })
|
||||
await scope.evaluate(el => el.scrollIntoView({ block: "start" }))
|
||||
await page.screenshot({ path: info.outputPath("optimizer-homes-pages-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="Домашние устройства оптимизатора"]')!, { runOnly: { type: "tag", values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"] } }))).violations.map(v => ({ id: v.id, nodes: v.nodes.map(n => n.target) }))).toEqual([])
|
||||
for (const name of ["Предыдущая страница домашних устройств", "Следующая страница домашних устройств"]) expect((await scope.getByRole("button", { name }).boundingBox())!.height).toBeGreaterThanOrEqual(44)
|
||||
failed = false; servers = servers.slice(0, 1)
|
||||
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(cards).toHaveCount(1); await expect(scope.getByText("Домашний роутер 1", { exact: true })).toBeVisible()
|
||||
await expect(page).toHaveURL(url => !url.searchParams.has("home_page") && url.searchParams.get("server") === "1" && url.searchParams.get("keep") === "1")
|
||||
expect(writes).toEqual([])
|
||||
})
|
||||
@@ -8,7 +8,7 @@ const servers: OptimizerApiServer[] = (["home-router", "jump-host", "exit-node"]
|
||||
...(i === 0 ? { wanUplinks: ids.map(id => ({ id: `wan${id}`, name: `WAN${id}`, isp: "ISP", iface: `ether${id}`, ip: `198.51.100.${id}`, maxDl: 100, maxUl: 100 })) } : {}),
|
||||
}))
|
||||
|
||||
async function setup(page: Page, preview: "ok" | "empty" | "error" = "ok", missingExit = false) {
|
||||
async function setup(page: Page, preview: "ok" | "empty" | "error" = "ok", missingExit = false, manyHomes = false) {
|
||||
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
|
||||
await page.route("**/api/**", route => {
|
||||
const path = new URL(route.request().url()).pathname
|
||||
@@ -17,7 +17,7 @@ async function setup(page: Page, preview: "ok" | "empty" | "error" = "ok", missi
|
||||
const interfaces = preview === "empty" ? [] : ids.map(i => ({ id: String(i), interface: `ether${i}`, currentCost: i, optimalCost: 20, score: i, pingMs: i, dlMbps: 100, ulMbps: 50 }))
|
||||
return route.fulfill({ json: {serverId:1,serverName:"Роутер 1",pingWeight:60,unchangedCount:0, interfaces, changes: interfaces, changedCount: interfaces.length, interfacesTotal: interfaces.length } })
|
||||
}
|
||||
return route.fulfill({ json: path === "/api/servers" ? servers.filter(server => !missingExit || server.type !== "exit-node")
|
||||
return route.fulfill({ json: path === "/api/servers" ? [...servers.filter(server => !missingExit || server.type !== "exit-node"), ...(manyHomes ? Array.from({ length: 5 }, (_, i) => ({ ...servers[0], id: i+4, name: `Другой дом ${i+4}`, wanUplinks: [] })) : [])]
|
||||
: path === "/api/auth/config" ? { required: false }
|
||||
: path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false }
|
||||
: path === "/api/filters/rules" ? { rulesets: [{ serverId: "1", rules: ids.map(i => ({ id: String(i), community: `65001:${i}`, communityName: `Сервис ${i}`, gateway: "192.0.2.2", gatewayTunnelId: "", description: "" })) }] }
|
||||
@@ -84,3 +84,19 @@ test("Оптимизатор: без ExitNode отсутствующие инд
|
||||
await expect(grid).not.toContainText("0 б.")
|
||||
await expect(grid.getByRole("button",{name:"Симулировать",exact:true})).toHaveCount(0)
|
||||
})
|
||||
|
||||
|
||||
test("Оптимизатор: закрепление Community сохраняется между страницами устройств", async ({ page }) => {
|
||||
await setup(page, "ok", false, true)
|
||||
const scope = page.getByRole("region", { name: "Домашние устройства оптимизатора" })
|
||||
await page.getByRole("button", { name: "BGP community (12)", exact: true }).click()
|
||||
const rec = scope.getByRole("table").filter({ hasText: "Community" }).locator('tr[data-row-id="1::65001:1::0"]')
|
||||
await rec.getByRole("button", { name: "Закрепить", exact: true }).click()
|
||||
await expect(rec.getByRole("button", { name: "Открепить", exact: true })).toBeVisible()
|
||||
await scope.getByRole("button", { name: "Следующая страница домашних устройств" }).click()
|
||||
await expect(scope.getByRole("status")).toContainText("6–6 из 6")
|
||||
await expect(scope.getByText("Другой дом 8", { exact: true })).toBeVisible()
|
||||
await scope.getByRole("button", { name: "Предыдущая страница домашних устройств" }).click()
|
||||
await page.getByRole("button", { name: "BGP community (12)", exact: true }).click()
|
||||
await expect(rec.getByRole("button", { name: "Открепить", exact: true })).toBeVisible()
|
||||
})
|
||||
Reference in new issue
Block a user