fix(ui): восстанавливать контекст OSPF из URL

This commit is contained in:
Denozordec committed 2026-09-30 19:58:43 +07:00
1 parent af05ad5cda
commit 1d522527b4
7 files changed
+130 -44

No files matched your search

+1
View File
@@ -30,6 +30,7 @@ for (const change of ["backend", "mode"]) for (const operation of ["read", "writ
await page.getByRole("button", { name: operation === "read" ? "Обновить" : "Оптимизировать OSPF", exact: true }).click()
await expect.poll(() => started).toBe(true)
await page.goBack()
await page.goBack()
await expect(page).toHaveURL(/settings/)
if (change === "backend") {
const input = page.getByPlaceholder("http://localhost:8000")
+38
View File
@@ -0,0 +1,38 @@
import { test, expect, type Page } from "@playwright/test"
const host=(id:number)=>({serverId:id,serverName:"Роутер "+id,serverSite:"",serverCountry:"RU"})
const iface=(id:number)=>({...host(id),id:"*1",instance:"default",area:"backbone",areaId:"0.0.0.0",interface:"ether"+id,cost:20,type:"broadcast",disabled:false,inactive:false,priority:1,helloInterval:10,deadInterval:40,useBfd:false})
const catalog={interfaces:[iface(1),iface(2)],neighbors:[],instances:[],bfdSessions:[],routes:[],failures:[]}
async function setup(page:Page){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:path==="/api/servers"?[1,2].map(id=>({id,name:"Роутер "+id,host:"192.0.2."+id,country:"RU",enabled:true,status:null})):path==="/api/auth/config"?{required:false}:{}})})}
test("OSPF: устройство и вкладка переживают reload/back",async({page})=>{
await setup(page);await page.goto("/ospf?server=2&tab=bfd&keep=x")
await expect(page.getByRole("button",{name:"BFD",exact:true})).toHaveAttribute("aria-pressed","true")
await expect(page.getByRole("option").filter({hasText:"Роутер 2"})).toHaveAttribute("aria-selected","true")
await page.getByRole("button",{name:"Интерфейсы",exact:true}).click()
await expect(page.getByText("ether2",{exact:true})).toBeVisible();await expect(page.getByText("ether1",{exact:true})).toHaveCount(0)
await page.reload();await expect(page.getByText("ether2",{exact:true})).toBeVisible()
await page.getByRole("option").filter({hasText:"Роутер 1"}).click()
await expect(page).toHaveURL(/server=1/);await expect(page).toHaveURL(/keep=x/)
await page.goBack();await expect(page.getByText("ether2",{exact:true})).toBeVisible()
await page.goBack();await expect(page.getByRole("button",{name:"BFD",exact:true})).toHaveAttribute("aria-pressed","true")
})
for(const context of ["server=999","tab=broken","server=1&server=2","tab=bfd&tab=routes"])test("OSPF: недоступный URL не показывает общий каталог "+context,async({page})=>{
await setup(page);await page.goto("/ospf?"+context+"&keep=x")
const alert=page.getByRole("alert").filter({hasText:"Контекст OSPF недоступен"});await expect(alert).toBeVisible()
await expect(page.getByText("ether1",{exact:true})).toHaveCount(0)
await expect(page.getByLabel("Сводка OSPF",{exact:true})).toContainText("неизвестно")
await alert.getByRole("button",{name:"Сбросить контекст OSPF"}).click()
await expect(page).toHaveURL(/keep=x/);await expect(alert).toHaveCount(0);await expect(page.getByText("ether1",{exact:true})).toBeVisible()
})
for(const fails of [false,true])test("OSPF: history во время записи освобождает lock "+fails,async({page})=>{
await setup(page);let writes=0,started=false,reads=0;let release!:()=>void;const gate=new Promise<void>(resolve=>{release=resolve})
await page.route("**/api/ospf/catalog",r=>{reads++;return r.fulfill({json:catalog})})
await page.route("**/api/servers/1/ospf/optimize",async r=>{writes++;started=true;await gate;return r.fulfill(fails?{status:503,json:{error:"Старая ошибка"}}:{json:{serverId:1,serverName:"Роутер 1",pingWeight:60,optimizedCount:0,applied:[],interfaces:[]}})})
await page.goto("/ospf");await page.getByRole("option").filter({hasText:"Роутер 1"}).click()
await page.getByRole("button",{name:"Оптимизировать OSPF",exact:true}).click();await expect.poll(()=>started).toBe(true)
await page.goBack();await expect(page).not.toHaveURL(/server=1/)
await page.goForward();const optimize=page.getByRole("button",{name:"Оптимизировать OSPF",exact:true});await expect(optimize).toBeDisabled()
const before=reads;const response=page.waitForResponse(r=>r.url().includes("/api/servers/1/ospf/optimize"));release();await (await response).finished()
await expect.poll(()=>reads).toBe(before+1);await expect(optimize).toBeEnabled();expect(writes).toBe(1)
await expect(page.getByText("Старая ошибка",{exact:false})).toHaveCount(0)
await expect(page.locator("[data-sonner-toast]").filter({hasText:"API подтвердил оптимизацию OSPF"})).toHaveCount(0)
})