Files
MikrotikManager/tests/e2e/probes-context.spec.ts

26 lines
4.6 KiB
TypeScript

import { test, expect } from "@playwright/test"
const headers={"access-control-allow-origin":"*","access-control-allow-methods":"GET,POST,OPTIONS","access-control-allow-headers":"Content-Type,Authorization"}
for(const change of ["backend","mode"])for(const fails of [false,true])test("Диагностика: поздний запрос/"+change+"/"+fails,async({page})=>{
let started=false,completed=false,release!:()=>void;const gate=new Promise<void>(r=>release=r)
await page.route("**/health",r=>r.fulfill({headers,json:{ok:true}}))
await page.route("**/api/**",r=>{const u=new URL(r.request().url()),p=u.pathname;return r.fulfill({headers,json:p==="/api/auth/config"?{required:false}:p==="/api/servers"?[{id:1,name:u.port==="8101"?"Новый источник":"Прежний источник",host:"192.0.2.1",type:"exit-node",country:"RU",enabled:true,status:"online"}]:p.endsWith("/ros-src-address")?{host:"192.0.2.1",ipv4:"192.0.2.1"}:p.endsWith("/probes/run")?{output:"НОВЫЙ РЕЗУЛЬТАТ"}:{tunnels:[]}})})
await page.goto("/probes?server=1");await expect(page.getByRole("button",{name:"Запустить",exact:true})).toBeEnabled()
await page.route("**/api/servers/1/probes/run",async r=>{if(new URL(r.request().url()).port!=="8000")return r.fallback();started=true;await gate;try{await r.fulfill(fails?{headers,status:503,json:{error:"СТАРАЯ ОШИБКА"}}:{headers,json:{output:"СТАРЫЙ РЕЗУЛЬТАТ"}})}catch{}finally{completed=true}})
await page.getByRole("button",{name:"Запустить",exact:true}).click();await expect.poll(()=>started).toBe(true);await page.getByRole("link",{name:/^Настройки/}).click()
if(change==="backend"){const input=page.getByPlaceholder("http://localhost:8000");await input.fill("http://localhost:8101");await input.press("Enter")}else await page.getByRole("button",{name:"Моковые",exact:true}).click()
await page.goto("/probes?server=1");if(change==="mode")await page.getByRole("option").first().click();await expect(page.getByRole("button",{name:"Запустить",exact:true})).toBeEnabled();release();await expect.poll(()=>completed).toBe(true)
await page.getByRole("button",{name:"Запустить",exact:true}).click()
if(change==="backend")await expect(page.getByText("НОВЫЙ РЕЗУЛЬТАТ",{exact:true})).toBeVisible()
await expect(page.getByText("СТАРЫЙ РЕЗУЛЬТАТ",{exact:true})).toHaveCount(0);await expect(page.getByText("СТАРАЯ ОШИБКА",{exact:true})).toHaveCount(0)
})
for(const change of ["backend","mode"])for(const fails of [false,true])test("Probe schedule ignores late old-source snapshot after ABA/"+change+"/"+fails,async({page})=>{
let started=false,completed=false,first=true,release!:()=>void;const gate=new Promise<void>(r=>release=r)
const row={id:"new-probe",srcServerId:"1",dstServerId:"2",srcInterface:"NEW_SCHEDULE",dstInterface:"",protocol:"tcp",direction:"both",durationSec:"10",enabled:true,lastRunAt:null,lastTxAvgMbps:0,lastRxAvgMbps:null,lastStatus:"done",lastError:null}
await page.route("**/health",r=>r.fulfill({headers,json:{ok:true}}));await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;return r.fulfill({headers,json:p==="/api/auth/config"?{required:false}:p==="/api/servers"?[{id:1,name:"Fixture",host:"192.0.2.1",type:"exit-node",enabled:true,status:"online"}]:p==="/api/uptime/speed-probes"?{probes:[row]}:{tunnels:[]}})})
await page.route("**/api/uptime/speed-probes",async r=>{if(new URL(r.request().url()).port!=="8000"||!first)return r.fallback();first=false;started=true;await gate;try{await r.fulfill(fails?{headers,status:503,json:{error:"OLD_SCHEDULE_ERROR"}}:{headers,json:{probes:[{...row,id:"old-probe",srcInterface:"OLD_SCHEDULE"}]}})}catch{}finally{completed=true}})
await page.goto("/probes?server=1");await page.getByRole("button",{name:"Расписание",exact:true}).click();await expect.poll(()=>started).toBe(true)
async function switchSource(back:boolean){await page.getByRole("link",{name:/^Настройки/}).click();if(change==="backend"){const input=page.getByPlaceholder("http://localhost:8000");await input.fill(back?"http://localhost:8000":"http://localhost:8101");await input.press("Enter")}else await page.getByRole("button",{name:back?"Живые":"Моковые",exact:true}).click();await page.goto("/probes?server=1");await page.getByRole("button",{name:"Расписание",exact:true}).click()}
await switchSource(false);await switchSource(true);await expect(page.getByText(/NEW_SCHEDULE/)).toBeVisible();release();await expect.poll(()=>completed).toBe(true);await expect(page.getByText(/OLD_SCHEDULE/)).toHaveCount(0)
})