import {test,expect} from "@playwright/test" import {serverReadSchema} from "../../packages/contracts/src/servers" const rows=Array.from({length:1000},(_,i)=>serverReadSchema.parse({id:i+1,name:"Load node "+String(i+1).padStart(4,"0"),host:"192.0."+Math.floor(i/250)+"."+(i%250+1),port:443,username:"fixture",password:"fixture-only",useSsl:true,verifySsl:true,type:"exit-node",site:"TEST",country:"RU",asn:"",comment:"",enabled:true,lanSubnet:"",wanUplinks:[],createdAt:"2026-10-04T00:00:00Z",updatedAt:"2026-10-04T00:00:00Z",status:"online",latency:0,os:"7.20",model:"CHR",uptime:null,cpuLoad:null,freeMemory:null,totalMemory:null,identityName:null,sessions:0,polledAt:null})) test("large server pagination bounds DOM and searches the whole catalog",async({page},info)=>{ test.setTimeout(90000) await page.route("**/health",r=>r.fulfill({json:{ok:true}}));await page.route("**/api/**",r=>r.fulfill({json:new URL(r.request().url()).pathname==="/api/auth/config"?{required:false}:new URL(r.request().url()).pathname==="/api/servers"?rows:{}})) const start=Date.now();await page.goto("/servers");await expect(page.getByText("Load node 0001",{exact:true})).toBeVisible({timeout:60000});const sample={fixtureRows:rows.length,fixtureBytes:Buffer.byteLength(JSON.stringify(rows)),readyMs:Date.now()-start,renderedRows:await page.locator("tr[data-row-id]").count(),domNodes:await page.locator("*").count()};console.log(JSON.stringify(sample));await info.attach("large-servers-metrics",{body:JSON.stringify(sample),contentType:"application/json"});expect(sample.renderedRows).toBe(50);expect(sample.domNodes).toBeLessThan(5000) await expect(page.getByText("1–50 из 1000",{exact:true})).toBeVisible();await page.getByRole("button",{name:"Следующая страница",exact:true}).click();await expect(page.getByText("Load node 0051",{exact:true})).toBeVisible();await expect(page.locator("tr[data-row-id]")).toHaveCount(50);await page.getByPlaceholder("Поиск по имени, хосту…").fill("Load node 1000");await expect(page.locator("tr[data-row-id]")).toHaveCount(1);await expect(page.getByText("Load node 1000",{exact:true})).toBeVisible();await page.getByPlaceholder("Поиск по имени, хосту…").fill("");await expect(page.locator("tr[data-row-id]")).toHaveCount(50);await expect(page.getByText("1–50 из 1000",{exact:true})).toBeVisible();await page.getByRole("button",{name:"Имя / Хост",exact:true}).click();await page.getByRole("button",{name:"Имя / Хост",exact:true}).click();await expect(page.locator("tr[data-row-id]").first()).toContainText("Load node 1000");await page.getByRole("combobox",{name:"Строк на странице",exact:true}).click();await page.getByRole("option",{name:"5",exact:true}).click();await expect(page.locator("tr[data-row-id]")).toHaveCount(5);await page.getByPlaceholder("Поиск по имени, хосту…").fill("Load node 000");await expect(page.locator("tr[data-row-id]")).toHaveCount(5);await expect(page.getByRole("button",{name:"Следующая страница",exact:true})).toBeVisible();await page.getByRole("button",{name:"Следующая страница",exact:true}).click();await expect(page.locator("tr[data-row-id]")).toHaveCount(4);await page.getByPlaceholder("Поиск по имени, хосту…").fill("");await page.getByRole("combobox",{name:"Строк на странице",exact:true}).click();await page.getByRole("option",{name:"50",exact:true}).click();await page.getByRole("button",{name:"Раскрыть: Load node 1000",exact:true}).click();await expect(page.getByText("Модель: CHR",{exact:true})).toBeVisible();await page.setViewportSize({width:320,height:900});expect(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth)).toBe(true);await expect(page.getByRole("button",{name:"Следующая страница",exact:true})).toBeVisible() })