fix(netflow): проверить смену источника и адаптивность формы

This commit is contained in:
Denozordec committed 2026-10-03 12:51:40 +07:00
1 parent fcd8de2a96
commit a575795ff5
13 files changed
+83 -2

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
import {test,expect,type Page} from "@playwright/test"
import {keyedNetflowSettings as settings} from "./fixtures/netflow-settings"
const headers={"access-control-allow-origin":"*","access-control-allow-methods":"GET,POST,PUT,OPTIONS","access-control-allow-headers":"Content-Type,Authorization"}
async function setup(page:Page){
await page.route("**/health",r=>r.fulfill({headers,json:{ok:true}}))
await page.route("**/api/**",r=>{const url=new URL(r.request().url());return r.fulfill(url.pathname==="/api/auth/config"?{headers,json:{required:false}}:url.pathname==="/api/traffic/flow/settings"?{headers,json:{...settings,flowListenPort:url.port==="8101"?4801:4739}}:{headers,status:503,json:{error:"outside NetFlow fixture"}})})
}
for(const action of ["read","put","keys","purge","export"] as const)for(const fails of [false,true])test("NetFlow: поздний ответ старого backend/"+action+"/"+fails,async({page})=>{
await setup(page);let started=false,completed=false,release!:()=>void;const gate=new Promise<void>(resolve=>release=resolve)
const path=action==="keys"?"/api/traffic/flow/settings/generate-keys":action==="purge"?"/api/traffic/flow/purge":action==="export"?"/api/traffic/flow/host-files":"/api/traffic/flow/settings"
await page.route("**"+path,async r=>{
if(new URL(r.request().url()).port!=="8000"||(action==="put"?r.request().method()!=="PUT":action==="read"?r.request().method()!=="GET":false))return r.fallback()
started=true;await gate
const old={...settings,flowListenPort:4740}
const json=action==="read"?old:action==="put"?{ok:true,settings:old}:action==="keys"?{ok:true,created:true,publicKey:old.hostPublicKey,settings:old}:action==="export"?{files:[{id:"wg",label:"WG",filename:"wg.conf",code:"fixture-old"}]}:{ok:true,deleted:{buckets:21,minuteStats:0,minuteDims:0,dailyDims:0},fileBytesBefore:null,fileBytesAfter:null,vacuumed:false}
try{await r.fulfill(fails?{headers,status:503,json:{error:"СТАРАЯ ОШИБКА"}}:{headers,json})}catch{}finally{completed=true}
})
try{
await page.goto("/data-collection");const field=page.getByRole("textbox",{name:"UDP IPFIX",exact:true})
if(action!=="read")await expect(field).toHaveValue("4739")
if(action==="put"){await field.fill("4740");await page.getByRole("button",{name:"Сохранить NetFlow",exact:true}).click()}
if(action==="keys")await page.getByRole("button",{name:"Ключи хоста",exact:true}).click()
if(action==="export")await page.getByRole("button",{name:"Скачать файлы хоста NetFlow",exact:true}).click()
if(action==="purge"){await page.getByRole("button",{name:"Сбросить",exact:true}).click();await page.getByRole("alertdialog").getByRole("button",{name:"Сбросить",exact:true}).click()}
await expect.poll(()=>started).toBe(true);await page.goto("/settings");const url=page.getByPlaceholder("http://localhost:8000");await url.fill("http://localhost:8101");await url.press("Enter");await page.goto("/data-collection");await expect(field).toHaveValue("4801");release();await expect.poll(()=>completed).toBe(true)
await expect(field).toHaveValue("4801");await expect(page.getByText(/СТАРАЯ ОШИБКА/)).toHaveCount(0);await expect(page.getByRole("status").filter({hasText:/подтверждено|подтверждён/})).toHaveCount(0);await expect(page.getByRole("dialog",{name:"Файлы для хоста Docker MM",exact:true})).toHaveCount(0);await expect(page.getByRole("button",{name:"Ключи хоста",exact:true})).toBeEnabled()
}finally{release()}
})
+37
View File
@@ -0,0 +1,37 @@
import { test, expect, type Page } from "@playwright/test"
import { geoip } from "./fixtures/geoip"
import { keyedNetflowSettings } from "./fixtures/netflow-settings"
const common = { enabled: true, intervalSec: 300, retentionDays: 14, lastCollectedAt: null, lastDurationMs: 0, lastError: null }
const values: Record<string, object> = {
"/api/traffic/settings": { ...common, intervalSec: 45 },
"/api/servers-api-ping/settings": { ...common, enabled: false, intervalSec: 120 },
"/api/uptime/settings": { ...common, resourcesEnabled: true, pingEnabled: false, speedEnabled: false, probeIntervalSec: 15, speedIntervalSec: 60 },
"/api/internet-path/settings": common,
"/api/certificates/renew-settings": { enabled: false, intervalSec: 21600, renewBeforeDays: 30 },
}
async function setup(page: Page) {
await page.route("**/health", r => r.fulfill({ json: { ok: true } }))
await page.route("**/api/**", r => {
const path = new URL(r.request().url()).pathname
if (path === "/api/auth/config") return r.fulfill({ json: { required: false } })
if (path === "/api/geoip") return r.fulfill({ json: geoip })
if (path === "/api/scheduler/status") return r.fulfill({ json: { jobs: [] } })
if (path === "/api/scheduler/runs") return r.fulfill({ json: { runs: [] } })
if (path === "/api/traffic/flow/settings") return r.fulfill({ json: {...keyedNetflowSettings,publicEndpoint:"collector.example.test"} })
if (values[path]) return r.fulfill({ json: values[path] })
return r.fulfill({ status: 503, json: { error: "outside settings fixture" } })
})
}
for (const width of [1440, 390, 320]) test("NetFlow: адаптивность/" + width, async ({ page }) => {
await page.setViewportSize({ width, height: 1000 }); await setup(page); await page.goto("/data-collection")
const section = page.getByText("Traffic Flow / NetFlow (IPFIX)", { exact: true }).locator("xpath=ancestor::*[@data-slot='frame'][1]")
await expect(page.getByRole("textbox", { name: "UDP IPFIX", exact: true })).toHaveValue("4739")
await page.getByText("Traffic Flow / NetFlow (IPFIX)", {exact:true}).scrollIntoViewIfNeeded()
expect(await section.evaluate(element => element.scrollWidth <= element.clientWidth + 2)).toBe(true)
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe(true)
await page.screenshot({ path: "docs/ux-ui/screens/netflow-" + width + ".png", fullPage: true })
await page.getByRole("button",{name:"Сохранить NetFlow",exact:true}).scrollIntoViewIfNeeded()
await page.screenshot({path:"docs/ux-ui/screens/netflow-actions-"+width+".png",fullPage:true})
})