Files
MikrotikManager/tests/e2e/migrated-tables.spec.ts

132 lines
7.5 KiB
TypeScript
Raw Permalink 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, type Page } from "@playwright/test"
import type { EvoBgpCatalogSnapshot } from "../../lib/evobgp-context"
import { statisticsDtoSchema } from "../../packages/contracts/src/statistics"
const catalog: EvoBgpCatalogSnapshot = {
fetchedAt: "2026-09-13T00:00:00Z", modules: [],
asns: Array.from({ length: 12 }, (_, i) => ({
id: String(i + 1), asn: `AS${65001 + i}`, org: `Организация ${i + 1}`,
country: "RU", prefixes: i + 1, filter: "", updated: "2026-09-13", enabled: true,
})),
domains: Array.from({ length: 12 }, (_, i) => ({
id: String(i + 1), domain: `test${i + 1}.example`, resolvedIp: `192.0.2.${i + 1}`,
asn: "AS65001", purpose: "Тест", filter: "", updated: "2026-09-13", enabled: true,
})),
ipRanges: Array.from({ length: 12 }, (_, i) => ({
id: String(i + 1), cidr: `192.0.${i + 1}.0/24`, asn: "AS65001", country: "RU",
purpose: "Тест", filter: "", updated: "2026-09-13", enabled: true,
})),
communities: Array.from({ length: 12 }, (_, i) => ({
id: String(i + 1), value: `65001:${i + 1}`, name: `Community ${i + 1}`,
description: `Описание ${i + 1}`, type: "standard", filterIds: [],
serverCount: i + 1, prefixCount: i + 1, action: "permit", enabled: true,
})),
}
async function setup(page: Page, path: string) {
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
await page.route("**/api/**", route => {
const path = new URL(route.request().url()).pathname
const json = path === "/api/auth/config" ? { required: false }
: path === "/api/evobgp/settings" ? { enabled: true, baseUrl: "", secretConfigured: true }
: path === "/api/evobgp/catalog" ? catalog
: path === "/api/servers" ? [] : {}
return route.fulfill({ json })
})
await page.goto(path)
}
for (const [path, placeholder, last] of [
["/asns", "Поиск по ASN, имени, префиксам…", "AS65012"],
["/domains", "Поиск по домену…", "test12.example"],
["/ip-ranges", "Поиск по CIDR, ASN…", "192.0.12.0/24"],
]) {
test(`${path}: страницы и поиск с последней страницы`, async ({ page }) => {
const errors: string[] = []
page.on("pageerror", e => errors.push(e.message))
await setup(page, path)
const rows = page.locator("tr[data-row-id]")
await expect(page.getByText("1–10 из 12", { exact: true })).toBeVisible()
await expect(rows).toHaveCount(10)
await page.getByRole("button", { name: "Следующая страница", exact: true }).click()
await expect(rows).toHaveCount(2)
await expect(rows.last()).toContainText(last)
await page.getByPlaceholder(placeholder).fill(last)
await expect(rows).toHaveCount(1)
await expect(rows.first()).toContainText(last)
await expect(page.getByText("1–1 из 1", { exact: true })).toBeVisible()
await page.getByPlaceholder(placeholder).fill("несуществующее значение")
await expect(rows).toHaveCount(0)
await page.getByPlaceholder(placeholder).fill("")
await expect(rows).toHaveCount(10)
expect(errors).toEqual([])
})
}
test("ASN: числовая сортировка охватывает обе страницы", async ({ page }) => {
await setup(page, "/asns")
await expect(page.getByText("1–10 из 12", { exact: true })).toBeVisible()
await page.getByRole("button", { name: "Префиксов", exact: true }).click()
await expect(page.locator("tr[data-row-id]").first()).toContainText("AS65012")
await page.getByRole("button", { name: "Следующая страница", exact: true }).click()
await expect(page.locator("tr[data-row-id]").last()).toContainText("AS65001")
})
test("Communities: все 12 строк и выбор деталей", async ({ page }) => {
await setup(page, "/communities")
await expect(page.locator("tr[data-row-id]")).toHaveCount(12)
await page.locator('tr[data-row-id="12"]').click()
await expect(page.locator('tr[data-row-id="12"]')).toHaveAttribute("data-state", "selected")
await expect(page.getByText("Описание 12", { exact: true })).toHaveCount(2)
await expect(page.getByText("Описание 12", { exact: true }).last()).toBeVisible()
await page.screenshot({ path: "test-results/communities-migrated.png", fullPage: true })
})
test("Статистика: CompactDataGrid сохраняет 12 строк, сортировку и переход в срез", async ({ page }) => {
const dto = statisticsDtoSchema.parse({
from: "2026-09-01", to: "2026-09-13", grain: "day",
kpis: { bytes: 7800, packets: 78, avgBps: 100, users: 12, servers: 1, ifaces: 1, topCountry: "RU", topService: "https" },
series: [], servers: [], interfaces: [], countries: [], services: [], asns: [],
users: Array.from({ length: 12 }, (_, i) => ({
id: `user-${i + 1}`, label: `Пользователь ${i + 1}`, bytes: (i + 1) * 100,
packets: i + 1, bps: i + 1, percent: i + 1,
})),
})
await page.route("**/api/statistics?**", route => route.fulfill({ json: dto }))
// The general API handler falls back to the previously registered statistics route.
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
await page.route("**/api/**", route => {
const path = new URL(route.request().url()).pathname
if (path === "/api/statistics") return route.fallback()
return route.fulfill({ json: path === "/api/auth/config" ? { required: false } : path === "/api/servers" ? [] : {} })
})
await page.goto("/statistics?from=2026-09-01&to=2026-09-13&dim=users")
const rows = page.locator("tr[data-row-id]")
await expect(rows).toHaveCount(12)
await page.getByRole("button", { name: "Байты", exact: true }).first().click()
await expect(rows.first()).toContainText("Пользователь 12")
await rows.first().click()
await expect(page).toHaveURL(/userId=user-12/)
await expect(page.getByRole("button", { name: "user-12", exact: true })).toBeVisible()
await page.getByRole("button", { name: "user-12", exact: true }).click()
await page.getByPlaceholder("id пользователя").fill("user-2")
await page.getByPlaceholder("id пользователя").press("Enter")
await expect(page).toHaveURL(/userId=user-12/)
await page.getByRole("button", { name: "Применить срез", exact: true }).click()
await expect(page).toHaveURL(/userId=user-2/)
await page.getByRole("button", { name: "Очистить", exact: true }).click()
await expect(page).toHaveURL(/userId=user-2/)
await page.getByRole("button", { name: "Применить срез", exact: true }).click()
await expect(page).not.toHaveURL(/userId=/)
await page.goto("/statistics?from=2026-09-01&to=2026-09-13&country=RU")
await page.getByRole("button", { name: "RU", exact: true }).click()
await page.getByPlaceholder("ISO, напр. US").fill("RUS")
await page.getByPlaceholder("ISO, напр. US").press("Enter")
await expect(page.getByRole("alert").filter({ hasText: "Укажите двухбуквенный код страны." })).toBeVisible()
await expect(page.getByRole("button", { name: "Применить срез", exact: true })).toBeDisabled()
await expect(page).toHaveURL(/country=RU(?:&|$)/)
await page.evaluate(() => window.history.pushState(null, "", "/statistics?country=DE"))
await expect(page.getByRole("button", { name: "DE", exact: true })).toBeVisible()
await expect(page.getByText("Укажите двухбуквенный код страны.", { exact: true })).toHaveCount(0)
})