Files
MikrotikManager/tests/e2e/large-uptime-resources.spec.ts
T

83 lines
5.7 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"
test("1000 ресурсов: страницы, поиск, обновление и уменьшение списка", async ({ page }, info) => {
test.setTimeout(90000)
const servers = Array.from({ length: 1000 }, (_, i) => ({ id: i + 1, name: "Ресурс " + String(i + 1).padStart(4, "0"), host: "192.0.2." + (i % 250 + 1), type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", sessions: 0, wanUplinks: [] }))
let resources = servers.map(s => ({ serverId: String(s.id), hasData: true, cpu: 10, cpuHistory: [10], ramUsed: 100, ramTotal: 1000, hddUsed: 10, hddTotal: 100, uptimeSeconds: 60, boardName: "CHR" }))
let calls = 0
const writes: string[] = []
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
await page.route("**/api/**", route => {
const path = new URL(route.request().url()).pathname
if (!["GET", "HEAD"].includes(route.request().method())) writes.push(path)
if (path === "/api/uptime/overview") calls++
return route.fulfill({ json: path === "/api/auth/config" ? { required: false } : path === "/api/servers" ? servers : path === "/api/uptime/overview" ? { probes: [], resources } : path === "/api/uptime/speed-probes" ? { probes: [] } : path === "/api/uptime/speed-test/runs" ? { runs: [] } : {} })
})
const start = Date.now()
await page.goto("/uptime?tab=resources&probe=p1&keep=1")
const rows = page.locator("tr[data-row-id]")
await expect(rows).toHaveCount(50)
const sample = { fixtureRows: 1000, renderedRows: await rows.count(), domNodes: await page.locator("*").count(), readyMs: Date.now() - start }
console.log(JSON.stringify(sample))
await info.attach("large-uptime-resources-metrics", { body: JSON.stringify(sample), contentType: "application/json" })
expect(sample.domNodes).toBeLessThan(4000)
await page.getByRole("button", { name: "Следующая страница", exact: true }).click()
await expect(rows.first()).toHaveAttribute("data-row-id", "51")
const before = calls
await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
await expect.poll(() => calls).toBeGreaterThan(before)
await expect(page.getByRole("button", { name: "Обновить данные", exact: true })).toBeEnabled()
await expect(page.getByText("51–100 из 1000", { exact: true })).toBeVisible()
const search = page.getByPlaceholder("Поиск по имени, площадке…")
await search.fill("Ресурс 1000")
await expect(rows).toHaveCount(1)
await expect(rows.first()).toHaveAttribute("data-row-id", "1000")
await expect(page).toHaveURL(url => url.searchParams.get("rq") === "Ресурс 1000" && url.searchParams.get("probe") === "p1" && url.searchParams.get("keep") === "1")
await page.reload()
await expect(search).toHaveValue("Ресурс 1000")
await expect(rows).toHaveCount(1)
await search.fill("")
await expect(rows).toHaveCount(50)
await page.getByRole("button", { name: "Сервер", exact: true }).click()
await page.getByRole("button", { name: "Сервер", exact: true }).click()
await expect(rows.first()).toHaveAttribute("data-row-id", "1000")
for (let i = 0; i < 3; i++) await page.getByRole("button", { name: "…", exact: true }).last().click()
await page.getByRole("button", { name: "Перейти на страницу 20", exact: true }).click()
await expect(page.getByText("951–1000 из 1000", { exact: true })).toBeVisible()
resources = resources.map(resource => ({ ...resource, cpu: 90 }))
await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
const warnings = page.getByRole("alert").filter({ hasText: "Серверов с предупреждениями: 1000" })
await expect(warnings).toBeVisible()
await expect(warnings.locator("[data-resource-warning]")).toHaveCount(5)
console.log(JSON.stringify({ warningRows: 1000, warningNodes: await warnings.locator("*").count(), domNodes: await page.locator("*").count() }))
expect(await page.locator("*").count()).toBeLessThan(3500)
const summary = warnings.locator("summary")
await summary.focus()
await page.keyboard.press("Enter")
await expect(warnings.locator("[data-resource-warning]")).toHaveCount(55)
await warnings.getByRole("button", { name: "Показать ещё 50", exact: true }).click()
await expect(warnings.locator("[data-resource-warning]")).toHaveCount(105)
await summary.click()
await expect(warnings.locator("[data-resource-warning]")).toHaveCount(5)
await summary.click()
await expect(warnings.locator("[data-resource-warning]")).toHaveCount(55)
await summary.click()
await page.setViewportSize({ width: 320, height: 900 })
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true)
await page.addScriptTag({ content: axe.source })
const audit = await page.evaluate(async () => {
const engine = (window as unknown as { axe: typeof axe }).axe
const root = document.querySelector("[data-resource-warning]")!.closest("[role=alert]")!
return engine.run(root, { runOnly: { type: "tag", values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22aa"] } })
})
await info.attach("resource-warning-axe", { body: JSON.stringify(audit), contentType: "application/json" })
expect(audit.violations.map(violation => ({ id: violation.id, nodes: violation.nodes.map(node => node.target) }))).toEqual([])
resources = resources.slice(0, 1)
await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
await expect(rows).toHaveCount(1)
await expect(rows.first()).toHaveAttribute("data-row-id", "1")
expect(writes).toEqual([])
})