Files
MikrotikManager/tests/e2e/large-communities.spec.ts

52 lines
5.1 KiB
TypeScript

import { test, expect } from "@playwright/test"
import axe from "axe-core"
import { evoCatalog, evoSettings } from "./fixtures/evobgp"
import { parseEvoBgpCatalog } from "../../lib/evobgp-catalog"
test("Communities1000: full search/sort/page/selection/cache/320px", async ({ page }, info) => {
test.setTimeout(90000)
let communities = Array.from({ length: 1000 }, (_, i) => ({ id: "c" + (i + 1), value: "64512:" + (i + 1), name: "community-" + String(i + 1).padStart(4, "0"), description: "Описание", type: "custom", filterIds: [], serverCount: i + 1, prefixCount: i + 1, action: "permit", enabled: true }))
let failed = false, calls = 0
const writes: string[] = []
await page.addInitScript(() => Object.defineProperty(navigator, "clipboard", { value: { writeText: async (value: string) => { (window as unknown as { copied: string }).copied = value } } }))
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" && p !== "/api/evobgp/catalog") writes.push(p)
if (p === "/api/evobgp/catalog") { calls++; return r.fulfill(failed ? { status: 503, json: { error: "Каталог недоступен тест" } } : { json: parseEvoBgpCatalog({ ...evoCatalog, communities }) }) }
return r.fulfill({ json: p === "/api/auth/config" ? { required: false } : p === "/api/evobgp/settings" ? evoSettings : {} })
})
const started = Date.now(); await page.goto("/communities")
const rows = page.locator("tr[data-row-id]"); await expect(rows).toHaveCount(50)
const profile = { count: communities.length, jsonBytes: Buffer.byteLength(JSON.stringify(communities)), rows: await rows.count(), nodes: await page.locator("*").count(), readyMs: Date.now() - started }
console.log("Communities profile", JSON.stringify(profile)); await info.attach("profile", { body: JSON.stringify(profile), contentType: "application/json" })
const next = page.getByRole("button", { name: "Следующая страница", exact: true })
for (let i = 0; i < 19; i++) await next.click()
await expect(next).toBeDisabled(); await expect(rows.first()).toContainText("community-0951")
const refresh = page.getByRole("button", { name: "Обновить каталог EvoBGP", exact: true })
const before = calls; await refresh.click(); await expect.poll(() => calls).toBeGreaterThan(before); await expect(rows.first()).toContainText("community-0951")
const search = page.getByPlaceholder("Поиск community…")
await search.fill("community-1000"); await expect(rows).toHaveCount(1)
const detailButton = rows.first().getByRole("button", { name: "Детали community: 64512:1000", exact: true })
await detailButton.focus(); await page.keyboard.press("Enter")
await expect(page.getByText("Скопировать значение", { exact: true })).toBeVisible()
await expect(page.getByRole("button", { name: "Изменить community", exact: true })).toBeDisabled()
await search.fill(""); await expect(rows).toHaveCount(50)
await page.getByRole("table").getByRole("button", { name: "Серверов", exact: true }).click(); await expect(rows.first()).toContainText("community-1000")
await next.click(); const previous = await rows.first().getAttribute("data-row-id")
failed = true; await refresh.click(); await expect(page.getByText("Каталог не обновлён; показаны последние данные", { exact: true })).toBeVisible()
await expect(rows.first()).toHaveAttribute("data-row-id", previous!)
await page.setViewportSize({ width: 320, height: 1000 })
const copy = rows.first().getByRole("button", { name: /Скопировать community:/ })
await copy.scrollIntoViewIfNeeded(); const viewport = page.locator('[data-slot="data-grid"] [data-slot="scroll-area-viewport"]')
await viewport.evaluate(el => { el.scrollLeft = el.scrollWidth }); await expect(copy).toBeInViewport()
await copy.click(); expect(await page.evaluate(() => (window as unknown as { copied: string }).copied)).toBe("64512:950")
await expect(page.getByText("Скопировать значение", { exact: true })).toHaveCount(1)
await expect.poll(() => page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(320)
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).toEqual([])
await page.addStyleTag({ content: "nextjs-portal{display:none!important}" }); await page.screenshot({ path: info.outputPath("communities-320.png"), animations: "disabled" })
failed = false; communities = [communities[999]]; await refresh.click(); await expect(rows).toHaveCount(1); await expect(rows.first()).toContainText("community-1000")
communities = []; await refresh.click(); await expect(rows).toHaveCount(0); await expect(page.getByText("Выберите community", { exact: false })).toBeVisible()
expect(writes).toEqual([])
})