13 lines
4.1 KiB
TypeScript
13 lines
4.1 KiB
TypeScript
import {test,expect,type Page} from "@playwright/test"
|
|
import {emptyAlerts,emptyOutbox} from "./fixtures/alerts"
|
|
const counts={servers:4,filterRules:0,uptimeProbes:0,uptimeSpeedProbes:0,monitoringItems:0,recursiveRoutes:0}
|
|
async function setup(page:Page,reply:(path:string)=>{status?:number;json:unknown}){await page.route("**/health",r=>r.fulfill({json:{status:"ok"}}));await page.route("**/api/**",r=>{const path=new URL(r.request().url()).pathname;return r.fulfill(path==="/api/auth/config"?{json:{required:false}}:path==="/api/alerts"?{json:emptyAlerts}:path==="/api/alerts/outbox"?{json:emptyOutbox}:reply(path))});await page.goto("/alerts")}
|
|
const badge=(page:Page,name:string)=>page.getByRole("navigation",{name:"Основная навигация"}).getByRole("link",{name:new RegExp(name)}).locator("span").last()
|
|
test("Sidebar missing optional counts remain unknown; confirmed zero is displayed",async({page})=>{await setup(page,path=>({json:path==="/api/sidebar-counts"?counts:path==="/api/filters/gre-tunnels"?{tunnels:[],failures:[]}:[]}));await expect(badge(page,"Серверы")).toHaveText("4");await expect(badge(page,"GRE-туннели")).toHaveText("0");await expect(badge(page,"Пользователи")).toHaveText("Пользователи")})
|
|
test("Sidebar partial GRE refresh retains last complete count, other counts update independently",async({page})=>{await page.clock.install();let partial=false;await setup(page,path=>({json:path==="/api/sidebar-counts"?{...counts,servers:partial?5:4}:path==="/api/filters/gre-tunnels"?{tunnels:partial?[]:[{name:"g",serverId:"1"}],failures:partial?[{error:"offline"}]:[]}:[]}));await expect(badge(page,"GRE-туннели")).toHaveText("1");partial=true;await page.clock.fastForward(120001);await expect(badge(page,"Серверы")).toHaveText("5");await expect(badge(page,"GRE-туннели")).toHaveText("1")})
|
|
test("Sidebar GRE does not wait for unavailable summary reader",async({page})=>{await setup(page,path=>path==="/api/sidebar-counts"?{status:503,json:{error:"counts unavailable"}}:{json:path==="/api/filters/gre-tunnels"?{tunnels:[{name:"g",serverId:"1"}],failures:[]}:[]});await expect(badge(page,"GRE-туннели")).toHaveText("1");await expect(badge(page,"Серверы")).toHaveText("Серверы")})
|
|
|
|
test("Sidebar GRE arrives while summary request is pending",async({page})=>{let started=false,release!:()=>void;const gate=new Promise<void>(resolve=>release=resolve);await page.route("**/health",r=>r.fulfill({json:{status:"ok"}}));await page.route("**/api/**",async r=>{const path=new URL(r.request().url()).pathname;if(path==="/api/sidebar-counts"){started=true;await gate;try{await r.fulfill({json:counts})}catch{};return}return r.fulfill({json:path==="/api/auth/config"?{required:false}:path==="/api/alerts"?emptyAlerts:path==="/api/alerts/outbox"?emptyOutbox:path==="/api/filters/gre-tunnels"?{tunnels:[{name:"g",serverId:"1"}],failures:[]}:[]})});try{await page.goto("/alerts");await expect.poll(()=>started).toBe(true);await expect(badge(page,"GRE-туннели")).toHaveText("1");await expect(badge(page,"Серверы")).toHaveText("Серверы");release();await expect(badge(page,"Серверы")).toHaveText("4")}finally{release()}})
|
|
|
|
test("System monitor summary failure preserves API health and last confirmed counts",async({page})=>{await page.clock.install();let fail=false;await setup(page,path=>path==="/api/sidebar-counts"&&fail?{status:503,json:{error:"summary unavailable"}}:{json:path==="/api/sidebar-counts"?counts:path==="/api/filters/gre-tunnels"?{tunnels:[],failures:[]}:[]});const button=page.getByRole("button",{name:"Монитор системы"});await expect(button).toContainText("API доступен");await button.click();const popover=page.locator('[data-slot="popover-content"]');await expect(popover.getByText("4шт.",{exact:true})).toBeVisible();fail=true;await page.clock.fastForward(30001);await expect(popover.getByRole("status")).toContainText("Сводка не обновлена");await expect(popover.getByText("4шт.",{exact:true})).toBeVisible();await expect(button).toContainText("API доступен")})
|