From b658f7127f27014eb0942af3cdc0425305e7b46f Mon Sep 17 00:00:00 2001 From: Denozordec Date: Sun, 4 Oct 2026 00:45:30 +0700 Subject: [PATCH] =?UTF-8?q?fix(test):=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=81=D0=BA=D0=B2=D0=BE=D0=B7=D0=BD=D1=8B=D1=85=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D1=80=D0=BE=D0=BA=20=D0=B4=D0=B0=D1=88=D0=B1?= =?UTF-8?q?=D0=BE=D1=80=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ux-ui-performance.md | 48 +++++++++++++++++++++++++++++++ docs/ux-ui-plan.md | 2 +- docs/ux-ui-progress.md | 8 ++++++ docs/ux-ui-stage-12.md | 8 ++++++ tests/e2e/gre-links.spec.ts | 12 ++++---- tests/e2e/uptime-links.spec.ts | 14 ++++----- tests/e2e/vxlan-links.spec.ts | 14 ++++----- tests/e2e/wireguard-links.spec.ts | 12 ++++---- 8 files changed, 91 insertions(+), 27 deletions(-) create mode 100644 docs/ux-ui-performance.md diff --git a/docs/ux-ui-performance.md b/docs/ux-ui-performance.md new file mode 100644 index 00000000..bc7ca245 --- /dev/null +++ b/docs/ux-ui-performance.md @@ -0,0 +1,48 @@ +# Локальная проверка производительности UX/UI + +Состояние на2026-10-04; этап12.3 продолжается. Эти измерения относятся к Playwright/Edge/Next dev без CPU throttling и реальной сети. readyMs — wall clock от page.goto до готовой строки, включая компиляцию/подставной API; разные прогоны имеют разную прогретость. Это не production SLA и не p95. Fixtures проверяют UI на реальном формате DTO, но не ёмкость PostgreSQL/RouterOS. + +| Сценарий | Размер fixture | Строк в DOM до → после | DOM nodes до → после | Наблюдаемый dev ready до → после | +| --- | --- | --- | --- | --- | +| Серверы |1000 ServerRead,501462 JSON bytes |1000 →50 |41569 →2644 |3345 →1058/1543ms | +| Статистика/CompactDataGrid |1000 users,88894 JSON bytes массива |1000 →50 |12585 →1210 |5195 →2928/1195ms | +| BGP |1000 полных сессий |1000 →50 |25657 →1932 |2990 →898ms | +| Очередь проблем |1000 offline servers |5 начальных,55 после раскрытия,105 после кнопки |831 начальный dashboard |1081ms; baseline до не замерялся | + +Профили: large-servers.spec.ts, large-statistics.spec.ts, large-bgp.spec.ts, dashboard-data.spec.ts. Измерения приложены к Playwright test results как JSON. Полные массивы всё ещё загружаются/валидируются/фильтруются на клиенте. Pagination ограничивает строки DOM, но не число pivot колонок; широкая pivot требует отдельной проверки. Порционное раскрытие очереди допускает постепенный полный список по запросу пользователя. + +## Оставшиеся специализированные grids + +Ниже точный поиск manualPagination:true, а не заключение о дефекте: часть экранов может уже ограничивать данные API. Перед сменой режима нужно проверить читателя, общий recordCount, порядок/drag и выбор из URL. Требуемые сценарии:1000 строк, последняя страница, поиск/сортировка всего среза, обновление на второй странице, уменьшение набора, детали/URL/права,320px. Firewall нельзя слепо разбивать с потерей порядка правил; traffic требует согласовать page/limit с backend. + +| Файл | Следующая проверка | +| --- | --- | +| [backups-data-grid.tsx](../components/data-grids/backups-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [certificates-data-grid.tsx](../components/data-grids/certificates-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [communities-data-grid.tsx](../components/data-grids/communities-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [data-collection-scheduler-data-grid.tsx](../components/data-grids/data-collection-scheduler-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [filters-data-grid.tsx](../components/data-grids/filters-data-grid.tsx) | Порядок/drag и операции до ограничения DOM | +| [firewall-rules-data-grid.tsx](../components/data-grids/firewall-rules-data-grid.tsx) | Порядок/drag и операции до ограничения DOM | +| [firewall-scenario-rules-data-grid.tsx](../components/data-grids/firewall-scenario-rules-data-grid.tsx) | Порядок/drag и операции до ограничения DOM | +| [gre-pools-data-grid.tsx](../components/data-grids/gre-pools-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [gre-tunnels-data-grid.tsx](../components/data-grids/gre-tunnels-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [ospf-bfd-data-grid.tsx](../components/data-grids/ospf-bfd-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [ospf-neighbors-data-grid.tsx](../components/data-grids/ospf-neighbors-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [ospf-routes-data-grid.tsx](../components/data-grids/ospf-routes-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [probes-schedule-data-grid.tsx](../components/data-grids/probes-schedule-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [probes-speed-probes-data-grid.tsx](../components/data-grids/probes-speed-probes-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [recursive-routes-data-grid.tsx](../components/data-grids/recursive-routes-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [route-optimizer-comm-recs-data-grid.tsx](../components/data-grids/route-optimizer-comm-recs-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [route-optimizer-full-routes-data-grid.tsx](../components/data-grids/route-optimizer-full-routes-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [route-optimizer-ospf-preview-data-grid.tsx](../components/data-grids/route-optimizer-ospf-preview-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [route-optimizer-wan-matrix-data-grid.tsx](../components/data-grids/route-optimizer-wan-matrix-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [subusers-data-grid.tsx](../components/data-grids/subusers-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [traffic-flows-data-grid.tsx](../components/data-grids/traffic-flows-data-grid.tsx) | API page/limit, manualSorting и общий счётчик | +| [uptime-resources-data-grid.tsx](../components/data-grids/uptime-resources-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [uptime-speed-history-data-grid.tsx](../components/data-grids/uptime-speed-history-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [users-data-grid.tsx](../components/data-grids/users-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [vxlan-data-grid.tsx](../components/data-grids/vxlan-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [wireguard-data-grid.tsx](../components/data-grids/wireguard-data-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | +| [wireguard-peers-grid.tsx](../components/data-grids/wireguard-peers-grid.tsx) | Потребитель API, контекст/детали и fixture1000 | + +Всего27 специализированных grids; ни один из этого перечня не принят этим документом на больших данных. Следующая группа — uptime-resources/probes-speed/probes-schedule, затем сетевые/admin grids по профилям. Общий журнал: [ux-ui-progress.md](ux-ui-progress.md). diff --git a/docs/ux-ui-plan.md b/docs/ux-ui-plan.md index ad7890cd..e03a1559 100644 --- a/docs/ux-ui-plan.md +++ b/docs/ux-ui-plan.md @@ -4,7 +4,7 @@ ## Актуальная точка продолжения — 2026-10-03 -Этап 11Б завершён в границах локальной приёмки (11Б.7); внешний выпуск не проверен. 12.1 принят локально: доступность оболочки/клавиатура/health в описанных сценариях. 12.2.1 принят локально: strict BGP catalog/partial/nullable counters. 12.2.2 принят локально: strict traffic DTO и агрегация без выдуманных точек. 12.2.3 принят локально: observations для server traffic от backend до dashboard. 12.2.4 принят локально: strict servers/probes и unknown server status. 12.2.5 принят локально: реальные ping samples/unknown/ось RTT/Recharts. 12.2.6 принят локально: strict GRE/WireGuard/VXLAN и device failures. 12.2.7 принят локально: strict Internet path snapshot/fallback. 12.2.8 принят локально: подтверждение полного backend сбора. 12.2.9 принят локально: метрики участков и наблюдаемый WAN без эвристической подмены. 12.3.1 принят локально:1000 серверов/штатная пагинация. 12.3.2 принят локально: пагинация CompactDataGrid/1000 строк статистики. 12.3.3 принят локально: порционный DOM очереди проблем. 12.3.4 принят локально: большой BGP каталог/страница при обновлении. Далее production build накопленных изменений и переходы дашборда, затем12.3.5 остальные специализированные grids и12.4 сводная регрессия. См. docs/ux-ui-stage-12.md. Внешние ограничения 11Б сохраняются. +Этап 11Б завершён в границах локальной приёмки (11Б.7); внешний выпуск не проверен. 12.1 принят локально: доступность оболочки/клавиатура/health в описанных сценариях. 12.2.1 принят локально: strict BGP catalog/partial/nullable counters. 12.2.2 принят локально: strict traffic DTO и агрегация без выдуманных точек. 12.2.3 принят локально: observations для server traffic от backend до dashboard. 12.2.4 принят локально: strict servers/probes и unknown server status. 12.2.5 принят локально: реальные ping samples/unknown/ось RTT/Recharts. 12.2.6 принят локально: strict GRE/WireGuard/VXLAN и device failures. 12.2.7 принят локально: strict Internet path snapshot/fallback. 12.2.8 принят локально: подтверждение полного backend сбора. 12.2.9 принят локально: метрики участков и наблюдаемый WAN без эвристической подмены. 12.3.1 принят локально:1000 серверов/штатная пагинация. 12.3.2 принят локально: пагинация CompactDataGrid/1000 строк статистики. 12.3.3 принят локально: порционный DOM очереди проблем. 12.3.4 принят локально: большой BGP каталог/страница при обновлении. Production build и123 профильных browser приняты локально на3978976. Следующий блок12.3.5: сохранение страницы CompactDataGrid при повторном опросе, затем uptime ресурсы/speed/schedule и остальные grids;12.4 общая регрессия ещё не завершена. См. docs/ux-ui-stage-12.md. Внешние ограничения 11Б сохраняются. Реальные pg_dump/pg_restore, PG rollback и остановка UDP worker требуют внешней приёмки. Датированные продолжения ниже — история; точный следующий шаг также указан в начале [журнала](ux-ui-progress.md). diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md index d05ce609..4fab9527 100644 --- a/docs/ux-ui-progress.md +++ b/docs/ux-ui-progress.md @@ -36,6 +36,14 @@ +## Промежуточная регрессия12.2–12.3 (2026-10-04) + +Frontend production/contracts build на3978976 прошёл:34 страницы.123 browser после build прошли:20 accessibility shell, GRE/WireGuard/VXLAN/uptime links и операции/права/ошибки,3 больших каталога. Штатные fixtures теперь содержат sessions/failures, BGP catalog, collectionComplete и реальные ping observations; speed fixtures имеют полный nullable metadata. Не ослаблялась проверка DTO ради тестов. Regenerated monitor screenshots восстановлены до прежних проверенных bytes, случайные визуальные diff не включены. + +Измерения и точный список27 оставшихся manualPagination grids сохранены в [ux-ui-performance.md](ux-ui-performance.md); это карта последующей приёмки, не объявление всех таблиц исправными. Typecheck/ESLint fixtures прошли.20 dashboard unit и backend pure/DI подтверждены предыдущими блоками; реальные PG/RouterOS не запускались.12.3/12.4/12.5 ещё в работе. + +Далее12.3.5: проверка сохранения страницы общего CompactDataGrid при повторном dashboard polling (100 проб), затем uptime ресурсы/speed/schedule большие fixtures. Build должен быть повторён после новых изменений общей основы. + ## 12.3.4 — большой каталог BGP и контекст страницы (2026-10-04) BGP использует штатную client pagination50. При обновлении того же каталога страница сохраняется (autoResetPageIndex:false); при уменьшении результатов индекс ограничивается последней существующей страницей. Сессия из URL открывает соответствующую страницу по pre-paginated row model; изменение сортировки/page size пересчитывает её положение. Client фильтры/сортировка и раскрытие работают по всем данным, права/сетевые операции неизменны. diff --git a/docs/ux-ui-stage-12.md b/docs/ux-ui-stage-12.md index 0114e4cb..dbca4abe 100644 --- a/docs/ux-ui-stage-12.md +++ b/docs/ux-ui-stage-12.md @@ -147,3 +147,11 @@ flowchart LR ``` Этап12.3 ещё в работе: остальные27 manualPagination grids/широкие pivot не проверены на1000 строк. Следующий шаг: production build накопленных изменений, профильная регрессия переходов дашборда; затем12.3.5 остальные grids, отдельно Firewall порядок/drag и server-paged traffic без слепой client миграции. Итоговая12.4 и внешняя12.5 не приняты. + +## Промежуточная регрессия12.2–12.3 (2026-10-04) + +Frontend production/contracts build на3978976 прошёл:34 страницы.123 browser после build прошли:20 accessibility shell, GRE/WireGuard/VXLAN/uptime links и операции/права/ошибки,3 больших каталога. Штатные fixtures теперь содержат sessions/failures, BGP catalog, collectionComplete и реальные ping observations; speed fixtures имеют полный nullable metadata. Не ослаблялась проверка DTO ради тестов. Regenerated monitor screenshots восстановлены до прежних проверенных bytes, случайные визуальные diff не включены. + +Измерения и точный список27 оставшихся manualPagination grids сохранены в [ux-ui-performance.md](ux-ui-performance.md); это карта последующей приёмки, не объявление всех таблиц исправными. Typecheck/ESLint fixtures прошли.20 dashboard unit и backend pure/DI подтверждены предыдущими блоками; реальные PG/RouterOS не запускались.12.3/12.4/12.5 ещё в работе. + +Далее12.3.5: проверка сохранения страницы общего CompactDataGrid при повторном dashboard polling (100 проб), затем uptime ресурсы/speed/schedule большие fixtures. Build должен быть повторён после новых изменений общей основы. diff --git a/tests/e2e/gre-links.spec.ts b/tests/e2e/gre-links.spec.ts index 3c45c296..6f65347a 100644 --- a/tests/e2e/gre-links.spec.ts +++ b/tests/e2e/gre-links.spec.ts @@ -2,7 +2,7 @@ import { test, expect, type Page } from "@playwright/test" async function setup(page: Page, url: string, failed = 0) { const control = { partial: false, failed, posts: [] as { path: string; body: unknown }[] } - const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", wanUplinks: [] }] + const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", sessions:0, wanUplinks: [] }] const tunnels = ["1", "2"].flatMap(serverId => ["*/2", "other"].map(id => ({ id, serverId, name: "gre-same", localAddress: "192.0.2.1", remoteAddress: "192.0.2." + (serverId === "1" ? "11" : "22"), localInnerIp: "10.0.0.1/30", remoteInnerIp: "10.0.0.2/30", poolId: "live", ipsec: null, mtu: 1400, keepaliveInterval: 10, keepaliveRetries: 3, dscp: "inherit", clampTcpMss: true, allowFastPath: true, comment: "", enabled: true, status: "down" }))); servers.push({ ...servers[0], id: 2, name: "Второй сервер", host: "192.0.2.2" }); const probes = ["p1", "p/2"].map(id => ({ id, srcServerId: "1", name: "Проверка сети", target: "192.0.2.10", filter: "main", rtt: null, loss: 100, status: "down", series: [0], enabled: true, showOnDashboard: false })) @@ -15,16 +15,16 @@ async function setup(page: Page, url: string, failed = 0) { const json = path === "/api/auth/config" ? { required: false } : path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false } : path === "/api/servers" ? servers - : path === "/api/uptime/overview" ? { probes, resources: [] } + : path === "/api/uptime/overview" ? { probes:probes.map(p=>({...p,observations:{samples:[{sampledAt:"2026-09-20T00:00:00Z",rtt:null,loss:100,status:"down"}]}})),rangeStartAt:"2026-09-19T23:00:00Z",rangeEndAt:"2026-09-20T00:00:00Z",resources: [] } : path === "/api/uptime/speed-probes" ? { probes: [] } : path === "/api/uptime/speed-test/runs" ? { runs: [] } - : path === "/api/bgp/sessions" ? [] + : path === "/api/bgp/catalog" ? {sessions:[],failures:[]} : path === "/api/gre/tunnels" || path === "/api/filters/gre-tunnels" ? { tunnels: control.partial ? tunnels.filter(t => t.serverId !== "2") : tunnels, failures: control.partial ? [{ serverId: "2", error: "Unavailable" }] : [] } - : path === "/api/vxlan" ? { tunnels: [] } - : path === "/api/wireguard" ? { interfaces: [], peers: [] } + : path === "/api/vxlan" ? { tunnels: [],failures:[] } + : path === "/api/wireguard" ? { interfaces: [], peers: [],failures:[] } : path === "/api/traffic/servers" ? { servers: [] } : path === "/api/events" ? { events: [] } - : path === "/api/internet-path/latest" ? { snapshot: { sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } + : path === "/api/internet-path/latest" ? { snapshot: { collectionComplete:true,sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } : {} return route.fulfill({ json }) }) diff --git a/tests/e2e/uptime-links.spec.ts b/tests/e2e/uptime-links.spec.ts index a91ac3c6..e43c16c2 100644 --- a/tests/e2e/uptime-links.spec.ts +++ b/tests/e2e/uptime-links.spec.ts @@ -2,7 +2,7 @@ import { test, expect, type Page } from "@playwright/test" async function setup(page: Page, url: string, failed = 0, longNames = false, permission?: string, isAdmin = false) { const control = { writes: [] as { method: string; path: string; body: unknown }[], failed, posts: [] as { path: string; body: unknown }[] } - const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", wanUplinks: [] }] + const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", sessions:0, wanUplinks: [] }] const probes = ["p1", "p/2"].map(id => ({ id, srcServerId: "1", name: "Проверка сети", target: "192.0.2.10", filter: "main", rtt: null, loss: 100, status: "down", series: [0], enabled: true, showOnDashboard: false })) if (permission) { await page.addInitScript(token => localStorage.setItem("mmapp_token", token), uptimeToken(permission, isAdmin)) @@ -22,15 +22,15 @@ async function setup(page: Page, url: string, failed = 0, longNames = false, per const json = path === "/api/auth/config" ? { required: Boolean(permission) } : path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false } : path === "/api/servers" ? servers - : path === "/api/uptime/overview" ? { probes, resources: [] } - : path === "/api/uptime/speed-probes" ? { probes: permission ? [{ id: "s1", srcServerId: "1", dstServerId: "2", srcInterface: "", dstInterface: "", protocol: "tcp", direction: "both", durationSec: "10", enabled: true }] : [] } + : path === "/api/uptime/overview" ? { probes:probes.map(p=>({...p,observations:{samples:[{sampledAt:"2026-09-20T00:00:00Z",rtt:null,loss:100,status:"down"}]}})),rangeStartAt:"2026-09-19T23:00:00Z",rangeEndAt:"2026-09-20T00:00:00Z",resources: [] } + : path === "/api/uptime/speed-probes" ? { probes: permission ? [{ id: "s1", srcServerId: "1", dstServerId: "2", srcInterface: "", dstInterface: "", protocol: "tcp", direction: "both", durationSec: "10", enabled: true,lastRunAt:null,lastTxAvgMbps:null,lastRxAvgMbps:null,lastStatus:null,lastError:null,lastPingRttMs:null,lastPingLossPct:null,lastPingAt:null,lastPingError:null }] : [] } : path === "/api/uptime/speed-test/runs" ? { runs: [] } - : path === "/api/bgp/sessions" ? [] - : path === "/api/filters/gre-tunnels" || path === "/api/vxlan" ? { tunnels: [] } - : path === "/api/wireguard" ? { interfaces: [], peers: [] } + : path === "/api/bgp/catalog" ? {sessions:[],failures:[]} + : path === "/api/filters/gre-tunnels" || path === "/api/vxlan" ? { tunnels: [],failures:[] } + : path === "/api/wireguard" ? { interfaces: [], peers: [],failures:[] } : path === "/api/traffic/servers" ? { servers: [] } : path === "/api/events" ? { events: [] } - : path === "/api/internet-path/latest" ? { snapshot: { sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } + : path === "/api/internet-path/latest" ? { snapshot: { collectionComplete:true,sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } : {} return route.fulfill({ json }) }) diff --git a/tests/e2e/vxlan-links.spec.ts b/tests/e2e/vxlan-links.spec.ts index 20d9b72d..032f9684 100644 --- a/tests/e2e/vxlan-links.spec.ts +++ b/tests/e2e/vxlan-links.spec.ts @@ -2,7 +2,7 @@ import { test, expect, type Page } from "@playwright/test" async function setup(page: Page, url: string, failed = 0) { const control = { payload: undefined as unknown, malformed: false, partial: false, failed, posts: [] as { path: string; body: unknown }[] } - const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", wanUplinks: [] }] + const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", sessions:0, wanUplinks: [] }] const tunnels = ["1", "2"].flatMap(serverId => ["*/2", "other"].map(id => ({ id, serverId, name: "vx-same", vni: Number(serverId) * 100 + (id === "other" ? 1 : 0), port: 0, dstPort: 8472, vtepIp: "192.0.2.1", remoteVteps: ["192.0.2.22"], l2mtu: 1500, arpProxy: false, macLearning: true, comment: "", enabled: true, status: "down" }))) servers.push({ ...servers[0], id: 2, name: "Второй сервер", host: "192.0.2.2" }); const probes = ["p1", "p/2"].map(id => ({ id, srcServerId: "1", name: "Проверка сети", target: "192.0.2.10", filter: "main", rtt: null, loss: 100, status: "down", series: [0], enabled: true, showOnDashboard: false })) @@ -17,16 +17,16 @@ async function setup(page: Page, url: string, failed = 0) { const json = path === "/api/auth/config" ? { required: false } : path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false } : path === "/api/servers" ? servers - : path === "/api/uptime/overview" ? { probes, resources: [] } + : path === "/api/uptime/overview" ? { probes:probes.map(p=>({...p,observations:{samples:[{sampledAt:"2026-09-20T00:00:00Z",rtt:null,loss:100,status:"down"}]}})),rangeStartAt:"2026-09-19T23:00:00Z",rangeEndAt:"2026-09-20T00:00:00Z",resources: [] } : path === "/api/uptime/speed-probes" ? { probes: [] } : path === "/api/uptime/speed-test/runs" ? { runs: [] } - : path === "/api/bgp/sessions" ? [] + : path === "/api/bgp/catalog" ? {sessions:[],failures:[]} : path === "/api/vxlan" ? { tunnels: control.partial ? tunnels.filter(t => t.serverId === "1") : tunnels, failures: control.partial ? [{ serverId: "2", serverName: "Второй сервер", error: "offline" }] : [] } - : path === "/api/filters/gre-tunnels" ? { tunnels: [] } - : path === "/api/wireguard" ? { interfaces: [], peers: [] } + : path === "/api/filters/gre-tunnels" ? { tunnels: [],failures:[] } + : path === "/api/wireguard" ? { interfaces: [], peers: [],failures:[] } : path === "/api/traffic/servers" ? { servers: [] } : path === "/api/events" ? { events: [] } - : path === "/api/internet-path/latest" ? { snapshot: { sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } + : path === "/api/internet-path/latest" ? { snapshot: { collectionComplete:true,sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } : {} return route.fulfill({ json }) }) @@ -196,7 +196,7 @@ for (const oldFails of [false, true]) { let attempts = 0 await page.route("**/api/vxlan", async route => { attempts++ - if (attempts === 1) { await oldGate; return route.fulfill(oldFails ? { status: 500, json: { error: "Поздняя ошибка тест" } } : { json: { tunnels: [] } }) } + if (attempts === 1) { await oldGate; return route.fulfill(oldFails ? { status: 500, json: { error: "Поздняя ошибка тест" } } : { json: { tunnels: [],failures:[] } }) } await newGate return route.fallback() }) diff --git a/tests/e2e/wireguard-links.spec.ts b/tests/e2e/wireguard-links.spec.ts index c92b080a..479c0fb5 100644 --- a/tests/e2e/wireguard-links.spec.ts +++ b/tests/e2e/wireguard-links.spec.ts @@ -3,7 +3,7 @@ import { wgListResponseSchema } from "../../packages/contracts/src/wireguard" async function setup(page: Page, url: string, failed = 0) { const control = { partial: false, failed, posts: [] as { path: string; body: unknown }[] } - const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", wanUplinks: [] }] + const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", sessions:0, wanUplinks: [] }] const interfaces = wgListResponseSchema.parse({ interfaces: ["1", "2"].flatMap(serverId => ["*/2", "other"].map(id => ({ id, rosId: id, serverId, serverName: serverId === "1" ? "Источник" : "Второй сервер", name: "wg-same", address: "192.0.2." + (serverId === "1" ? "11" : "22"), listenPort: 13231, mtu: 1420, comment: "", enabled: true, status: "down", peers: [{ id: "peer", rosId: "*P", publicKey: "fixture-key", allowedIps: [serverId === "1" ? "10.0.1.1/32" : "10.0.2.1/32"] }] }))) }).interfaces servers.push({ ...servers[0], id: 2, name: "Второй сервер", host: "192.0.2.2" }); const probes = ["p1", "p/2"].map(id => ({ id, srcServerId: "1", name: "Проверка сети", target: "192.0.2.10", filter: "main", rtt: null, loss: 100, status: "down", series: [0], enabled: true, showOnDashboard: false })) @@ -16,16 +16,16 @@ async function setup(page: Page, url: string, failed = 0) { const json = path === "/api/auth/config" ? { required: false } : path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false } : path === "/api/servers" ? servers - : path === "/api/uptime/overview" ? { probes, resources: [] } + : path === "/api/uptime/overview" ? { probes:probes.map(p=>({...p,observations:{samples:[{sampledAt:"2026-09-20T00:00:00Z",rtt:null,loss:100,status:"down"}]}})),rangeStartAt:"2026-09-19T23:00:00Z",rangeEndAt:"2026-09-20T00:00:00Z",resources: [] } : path === "/api/uptime/speed-probes" ? { probes: [] } : path === "/api/uptime/speed-test/runs" ? { runs: [] } - : path === "/api/bgp/sessions" ? [] + : path === "/api/bgp/catalog" ? {sessions:[],failures:[]} : path === "/api/wireguard" ? { interfaces: control.partial ? interfaces.filter(t => t.serverId !== "2") : interfaces, failures: control.partial ? [{ serverId: "2", error: "Unavailable" }] : [] } - : path === "/api/filters/gre-tunnels" ? { tunnels: [] } - : path === "/api/vxlan" ? { tunnels: [] } + : path === "/api/filters/gre-tunnels" ? { tunnels: [],failures:[] } + : path === "/api/vxlan" ? { tunnels: [],failures:[] } : path === "/api/traffic/servers" ? { servers: [] } : path === "/api/events" ? { events: [] } - : path === "/api/internet-path/latest" ? { snapshot: { sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } + : path === "/api/internet-path/latest" ? { snapshot: { collectionComplete:true,sampledAt: "2026-09-20T00:00:00Z", servers, greTunnels: [], filtersRulesets: [], speedProbes: [], routeLookupByServerId: {}, wanRuntimeByHomeId: {} } } : {} return route.fulfill({ json }) })