import { test, expect } from "@playwright/test" test("OSPF и BFD: переходные и неизвестные состояния не становятся Down", async ({ page }) => { let phase = 0 const host = { serverId: 1, serverName: "Роутер", serverSite: "", serverCountry: "RU" } const iface = { ...host, id: "a", instance: "default", area: "backbone", areaId: "0.0.0.0", interface: "ether1", cost: 7, type: "ptp", disabled: false, inactive: false, priority: 1, helloInterval: 10, deadInterval: 40, useBfd: true } const states = ["full", "2-way", "ExStart", "exchange", "loading", "attempt", "init", "down", "future-state"] const catalog = { neighbors: states.map((state,i) => ({ ...host, id: String(i), address: "192.0.2."+i, routerId: "192.0.2."+i, instance: "default", area: "backbone", areaId: i === 0 ? "0.0.0.1" : "0.0.0.0", interface: "ether1", state, uptime: "1h", stateChanges: 0, priority: 1 })), interfaces: [], instances: [], routes: [], failures: [], bfdSessions: ["up", "init", "down", "admindown", ""].map((state,i) => ({ ...host, id: String(i), localAddr: "192.0.2.1", remoteAddr: "198.51.100."+i, interface: "ether1", state, uptime: null, multihop: false, multiplier: 3, txInterval: 200, rxInterval: 200, holdTime: 600, packetsRx: 0, packetsTx: 0, stateChanges: 0 })) } await page.route("**/health", r => r.fulfill({ json: { ok: true } })) await page.route("**/api/**", r => { const path = new URL(r.request().url()).pathname; return r.fulfill({ json: path === "/api/ospf/catalog" ? { ...catalog, interfaces: phase === 0 ? [] : [iface, { ...iface, id: "b", areaId: "0.0.0.1", cost: 42 }, ...(phase === 2 ? [{ ...iface, id: "c", cost: 9 }] : [])] } : path === "/api/servers" ? [{ id: 1, name: "Роутер", host: "192.0.2.1", country: "RU", enabled: true, status: null }] : path === "/api/auth/config" ? { required: false } : {} }) }) await page.goto("/ospf") await page.getByRole("button", { name: "Соседи", exact: true }).click() const rows = page.locator("tr[data-row-id]") await expect(rows).toHaveCount(9) for (const row of await rows.all()) await expect(row.locator("td").nth(5)).toHaveText("—") for(const state of ["Full", "2-Way", "ExStart", "Exchange", "Loading", "Attempt", "Init", "Down", "Неизвестно"]) await expect(rows.getByText(state, { exact: true })).toHaveCount(1) phase = 1 await page.getByRole("button", { name: "Обновить", exact: true }).click() await expect(rows.first().locator("td").nth(5)).toHaveText("42") await expect(rows.nth(1).locator("td").nth(5)).toHaveText("7") phase = 2 await page.getByRole("button", { name: "Обновить", exact: true }).click() await expect(rows.first().locator("td").nth(5)).toHaveText("42") await expect(rows.nth(1).locator("td").nth(5)).toHaveText("—") await page.getByRole("button", { name: "BFD", exact: true }).click() await expect(rows).toHaveCount(5) for(const state of ["Up", "Init", "Down", "AdminDown", "Неизвестно"]) await expect(rows.getByText(state, { exact: true })).toHaveCount(1) })