32 lines
4.6 KiB
TypeScript
32 lines
4.6 KiB
TypeScript
import { test, expect } from "@playwright/test"
|
|
import { vxlanResponseSchema } from "../../lib/vxlan-response"
|
|
import axe from "axe-core"
|
|
test("VXLAN1000: page/refresh/full search/sort/cache/export/320px",async({page},info)=>{
|
|
test.setTimeout(90000)
|
|
let tunnels=Array.from({length:1000},(_,i)=>({id:"*"+(i+1),name:"vx-test-"+String(i+1).padStart(4,"0"),serverId:"1",vni:i+1,port:0,dstPort:8472,vtepIp:"192.0.2.1",remoteVteps:["198.51.100.1"],l2mtu:1500,arpProxy:false,macLearning:true,comment:"",enabled:true,status:"up"}))
|
|
let failed=false,calls=0;const writes:string[]=[]
|
|
await page.route("**/health",r=>r.fulfill({json:{ok:true}}))
|
|
await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;if(r.request().method()!=="GET")writes.push(p);if(p==="/api/vxlan"){calls++;return r.fulfill(failed?{status:503,json:{error:"Опрос VXLAN недоступен"}}:{json:vxlanResponseSchema.parse({tunnels})})}return r.fulfill({json:p==="/api/auth/config"?{required:false}:p==="/api/servers"?[{id:1,name:"Роутер",host:"192.0.2.1",country:"RU",enabled:true,status:null}]:{}})})
|
|
const started=Date.now();await page.goto("/vxlan?server=1&keep=1")
|
|
const rows=page.locator("tr[data-row-id]");await expect(rows).toHaveCount(50)
|
|
const profile={count:tunnels.length,jsonBytes:Buffer.byteLength(JSON.stringify(tunnels)),rows:await rows.count(),nodes:await page.locator("*").count(),readyMs:Date.now()-started};console.log("VXLAN profile",JSON.stringify(profile));await info.attach("profile",{body:JSON.stringify(profile),contentType:"application/json"})
|
|
const next=page.getByRole("button",{name:"Следующая страница",exact:true})
|
|
for(let i=0;i<19;i++)await next.click()
|
|
await expect(next).toBeDisabled();await expect(rows.first()).toContainText("vx-test-0951")
|
|
const before=calls;await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect.poll(()=>calls).toBeGreaterThan(before);await expect(rows.first()).toContainText("vx-test-0951")
|
|
const search=page.getByPlaceholder("Поиск по имени, VNI, серверу…");await search.fill("vx-test-1000");await expect(rows).toHaveCount(1);await expect(rows.first()).toContainText("vx-test-1000");await search.fill("");await expect(rows).toHaveCount(50)
|
|
await page.getByRole("table").getByRole("button",{name:"VNI",exact:true}).click();await expect(rows.first()).toContainText("vx-test-1000")
|
|
await next.click();const previous=await rows.first().getAttribute("data-row-id")
|
|
failed=true;await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect(page.getByText("Ошибка загрузки: Опрос VXLAN недоступен",{exact:true})).toBeVisible();await expect(rows).toHaveCount(50);await expect(rows.first()).toHaveAttribute("data-row-id",previous!);await expect(rows.first()).toContainText("Неизвестно")
|
|
await page.setViewportSize({width:320,height:1000})
|
|
const action=rows.first().getByRole("button",{name:/Действия:/}),scroll=page.locator('[data-slot="data-grid"] [data-slot="scroll-area-viewport"]')
|
|
await action.scrollIntoViewIfNeeded();await scroll.evaluate(el=>{el.scrollLeft=el.scrollWidth});await expect(action).toBeInViewport()
|
|
expect(await rows.first().getByRole("cell").first().evaluate(el=>{const a=el.getBoundingClientRect(),v=el.closest('[data-slot="scroll-area-viewport"]')!.getBoundingClientRect();return a.left>=v.left-1&&a.right<=v.right+1})).toBe(true)
|
|
await expect.poll(()=>page.evaluate(()=>document.documentElement.scrollWidth)).toBeLessThanOrEqual(320)
|
|
await page.addScriptTag({content:axe.source});expect((await page.evaluate(async()=>(window as unknown as {axe:typeof axe}).axe.run(document.querySelector('[data-slot="data-grid"]')!,{runOnly:{type:"tag",values:["wcag2a","wcag2aa","wcag21a","wcag21aa"]}}))).violations).toEqual([])
|
|
await page.addStyleTag({content:"nextjs-portal{display:none!important}"});await page.screenshot({path:info.outputPath("vxlan-320.png"),animations:"disabled"})
|
|
await action.click();await page.getByRole("menuitem",{name:"Экспорт .rsc",exact:true}).click();await expect(page.getByRole("dialog")).toContainText("актуальность не подтверждена");await page.keyboard.press("Escape")
|
|
failed=false;tunnels=[tunnels[999]];await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect(rows).toHaveCount(1);await expect(rows.first()).toContainText("vx-test-1000")
|
|
await action.click();await page.getByRole("menuitem",{name:"Экспорт .rsc",exact:true}).click();await expect(page.getByRole("dialog")).toContainText("vni=1000");await expect(page.getByRole("dialog")).toContainText("vx-test-1000");expect(writes).toEqual([])
|
|
})
|