import {test,expect} from "@playwright/test" const paths={servers:"/api/servers",gre:"/api/filters/gre-tunnels",probes:"/api/uptime/speed-probes"} as const const body=(path:string,name="Роутер")=>path===paths.servers?[{id:1,name,host:"192.0.2.1",type:"home-router",country:"RU",enabled:true,status:"online",latency:0}]:path===paths.gre?{tunnels:[],failures:[]}:path===paths.probes?{probes:[]}:path==="/api/auth/config"?{required:false}:{} for(const part of ["servers","gre","probes"] as const)for(const malformed of [false,true])test("Карта: первоначальный отказ и повтор "+part+"/"+malformed,async({page})=>{ let failing=true await page.route("**/health",r=>r.fulfill({json:{ok:true}})) await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;return r.fulfill(failing&&p===paths[part]?(malformed?{json:{}}:{status:403,json:{error:"Нет доступа к данным"}}):{json:body(p)})}) await page.goto("/network-map") await expect(page.getByRole("alert").filter({hasText:"Первоначальная загрузка карты"})).toBeVisible() await expect(page.getByText("Данные карты неизвестны",{exact:true})).toBeVisible() failing=false;await page.getByRole("button",{name:"Обновить",exact:true}).click() await expect(page.getByRole("group",{name:"Интерактивная карта сети"}).getByText("Роутер",{exact:true})).toBeVisible() await expect(page.getByRole("alert").filter({hasText:"Первоначальная загрузка карты"})).toHaveCount(0) }) for(const part of ["servers","gre","probes"] as const)test("Карта: частичный отказ сохраняет снимок "+part,async({page})=>{ let failing=false await page.route("**/health",r=>r.fulfill({json:{ok:true}})) await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;return r.fulfill(failing&&p===paths[part]?{status:503,json:{error:"Источник недоступен"}}:{json:body(p,failing?"Новый роутер":"Последний роутер")})}) await page.goto("/network-map") await expect(page.getByRole("group",{name:"Интерактивная карта сети"}).getByText("Последний роутер",{exact:true})).toBeVisible() failing=true;await page.getByRole("button",{name:"Обновить",exact:true}).click() await expect(page.getByRole("alert").filter({hasText:"Последний полный снимок"})).toBeVisible() await expect(page.getByRole("group",{name:"Интерактивная карта сети"}).getByText("Последний роутер",{exact:true})).toBeVisible() await expect(page.getByText("Новый роутер",{exact:true})).toHaveCount(0) }) test("Карта: неизвестный статус не становится оффлайн",async({page})=>{ await page.route("**/health",r=>r.fulfill({json:{ok:true}})) await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;const data=body(p);return r.fulfill({json:p===paths.servers?[{...(data as object[])[0],status:null}]:data})}) await page.goto("/network-map") await expect(page.getByText("1 неизвестно",{exact:true})).toBeVisible() await expect(page.getByText("0 оффлайн",{exact:true})).toBeVisible() await page.getByRole("group",{name:"Интерактивная карта сети"}).getByText("Роутер",{exact:true}).click() await expect(page.locator("span").filter({hasText:/^Неизвестно$/}).first()).toBeVisible() await page.getByRole("button",{name:"Неизвестно",exact:true}).click() await expect(page.getByRole("group",{name:"Интерактивная карта сети"}).getByText("Роутер",{exact:true})).toBeVisible() }) for(const polled of [false,true])test("Карта: реальные и неизвестные ресурсы "+polled,async({page})=>{ await page.route("**/health",r=>r.fulfill({json:{ok:true}})) await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;const data=body(p);return r.fulfill({json:p===paths.servers?[{...(data as object[])[0],...(polled?{cpuLoad:0,totalMemory:1048576,freeMemory:1048576,uptime:"0s",polledAt:"2020-01-01T00:00:00Z"}:{})}]:data})}) await page.goto("/network-map");await page.getByRole("group",{name:"Интерактивная карта сети"}).getByText("Роутер",{exact:true}).click() const panel=page.getByText("Ресурсы",{exact:true}).locator("..") await expect(panel.getByText("История CPU и диск API не передаются.",{exact:false})).toBeVisible() await expect(panel.locator("svg")).toHaveCount(0) await expect(panel.getByText("HDD",{exact:true})).toBeVisible() await expect(panel.getByText("— / —",{exact:true})).toHaveCount(polled?1:2) if(polled){await expect(panel.getByText("0%",{exact:true})).toBeVisible();await expect(panel.getByText("0 МБ / 1 МБ",{exact:true})).toBeVisible();await expect(panel.getByText("0м",{exact:true})).toBeVisible()} else await expect(panel.getByText("время неизвестно",{exact:false})).toBeVisible() await expect(panel.getByText("демо-значения",{exact:false})).toHaveCount(0) })