35 lines
4.0 KiB
TypeScript
35 lines
4.0 KiB
TypeScript
import { test, expect, type Page } from "@playwright/test"
|
|
import { geoip } from "./fixtures/geoip"
|
|
const headers = { "access-control-allow-origin": "*", "access-control-allow-methods": "GET,POST,PUT,OPTIONS", "access-control-allow-headers": "Content-Type,Authorization" }
|
|
const common = { enabled: true, intervalSec: 45, retentionDays: 14, lastCollectedAt: null, lastDurationMs: 0, lastError: null }
|
|
const job = { jobKey: "backups", enabled: true, intervalSec: 60, running: false, lastFinishedAt: null, lastStatus: null, lastDurationMs: 0, lastError: null }
|
|
async function setup(page: Page) {
|
|
await page.route("**/health", r => r.fulfill({ headers, json: { ok: true } }))
|
|
await page.route("**/api/**", r => {
|
|
const path = new URL(r.request().url()).pathname
|
|
if (path === "/api/auth/config") return r.fulfill({ headers, json: { required: false } })
|
|
if (path === "/api/geoip") return r.fulfill({ headers, json: { ...geoip, settings: { ...geoip.settings, updateIntervalSec: new URL(r.request().url()).port === "8101" ? 648000 : 604800 } } })
|
|
if (path === "/api/scheduler/status") return r.fulfill({ headers, json: { jobs: [job] } })
|
|
if (path === "/api/scheduler/runs") return r.fulfill({ headers, json: { runs: [] } })
|
|
if (path === "/api/traffic/settings") return r.fulfill({ headers, json: { ...common, intervalSec: new URL(r.request().url()).port === "8101" ? 77 : 45 } })
|
|
return r.fulfill({ headers, status: 503, json: { error: "outside context fixture" } })
|
|
})
|
|
}
|
|
for (const action of ["read", "put", "run"] as const) for (const fails of [false, true]) test("GeoIP: поздний ответ после смены 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 === "run" ? "/api/geoip/update" : "/api/geoip"
|
|
await page.route("**" + path, async r => {
|
|
if (new URL(r.request().url()).port !== "8000" || (action === "read" ? r.request().method() !== "GET" : action === "put" ? r.request().method() !== "PUT" : false)) return r.fallback()
|
|
started = true; await gate
|
|
try { await r.fulfill(fails ? { headers, status: 503, json: { error: "СТАРАЯ ОШИБКА" } } : { headers, json: action === "run" ? { ok: true, snapshot: { v: 1, job: "geoip_update", sampledAt: "2026-10-03T00:00:00Z", checked: 2, downloaded: 2, skippedUnchanged: 0, bytes: 1024, errors: [] } } : action === "put" ? { ok: true, status: { ...geoip, settings: { ...geoip.settings, updateIntervalSec: 684000 } } } : { ...geoip, settings: { ...geoip.settings, updateIntervalSec: 684000 } } }) } catch {} finally { completed = true }
|
|
})
|
|
try {
|
|
await page.goto("/data-collection")
|
|
if (action === "put") { const field = page.getByRole("textbox", { name: "Интервал GeoIP в часах", exact: true }); await expect(field).toHaveValue("168"); await field.fill("190"); await page.getByRole("button", { name: "Сохранить GeoIP" }).click() }
|
|
if (action === "run") { const run = page.getByRole("button", { name: "Обновить сейчас", exact: true }); await expect(run).toBeEnabled(); await run.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(page.getByRole("textbox", { name: "Интервал GeoIP в часах", exact: true })).toHaveValue("180"); release(); await expect.poll(() => completed).toBe(true)
|
|
await expect(page.getByRole("textbox", { name: "Интервал GeoIP в часах", exact: true })).toHaveValue("180"); await expect(page.getByText(/СТАРАЯ ОШИБКА/)).toHaveCount(0); await expect(page.getByText("Сохранение настроек GeoIP подтверждено", { exact: true })).toHaveCount(0); await expect(page.getByRole("status").filter({ hasText: "Обновление GeoIP подтверждено" })).toHaveCount(0)
|
|
} finally { release() }
|
|
})
|