fix(ui): показывать неопределённый исход speed и сверять историю
This commit is contained in:
1 parent
96fa910804
commit
8782054078
8 files changed
+145
-11
No files matched your search
@@ -707,7 +707,7 @@ interface SpeedTestRun {
|
||||
durationSec: number
|
||||
txAvgMbps: number | null
|
||||
rxAvgMbps: number | null
|
||||
status: "running" | "done" | "error"
|
||||
status: "running" | "done" | "error" | "unknown"
|
||||
command: string
|
||||
lines: string[]
|
||||
afterBtPing?: { rttMs: number | null; lossPct: number | null; error: string | null } | null
|
||||
@@ -1077,7 +1077,14 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
const [probeRttChartOpen, setProbeRttChartOpen] = useState<Record<string, boolean>>({})
|
||||
const [speedBusy, setSpeedBusy] = useState(false)
|
||||
const [speedError, setSpeedError] = useState<string | null>(null)
|
||||
const [speedUnknownRunId, setSpeedUnknownRunId] = useState<string | null>(null)
|
||||
const [speedRuns, setSpeedRuns] = useState<SpeedTestRun[]>([])
|
||||
useEffect(() => {
|
||||
if (speedUnknownRunId && speedRuns.some(run => run.id === speedUnknownRunId && (run.status === "done" || run.status === "error"))) {
|
||||
setSpeedUnknownRunId(null)
|
||||
setSpeedError(null)
|
||||
}
|
||||
}, [speedRuns, speedUnknownRunId])
|
||||
const [speedProbes, setSpeedProbes] = useState<SpeedProbeRow[]>([])
|
||||
const speedReadRevision = useRef(0)
|
||||
const [speedReads, setSpeedReads] = useState<Record<"probes" | "history", { receivedAt: number | null; error: string | null }>>({ probes: { receivedAt: null, error: null }, history: { receivedAt: null, error: null } })
|
||||
@@ -1182,7 +1189,10 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
srcInterfaceAddress: r.srcInterfaceAddress ?? null,
|
||||
dstInterfaceAddress: r.dstInterfaceAddress ?? null,
|
||||
}))
|
||||
if (current()) setSpeedRuns(rows)
|
||||
if (current()) setSpeedRuns(previous => [
|
||||
...previous.filter(run => (run.status === "running" || run.status === "unknown") && !rows.some(row => row.id === run.id)),
|
||||
...rows,
|
||||
])
|
||||
}),
|
||||
])
|
||||
}, [apiFetch, liveApi])
|
||||
@@ -1687,6 +1697,7 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
overviewReqRef.current++
|
||||
const context = ++saveContext.current
|
||||
setSpeedError(null)
|
||||
setSpeedUnknownRunId(null)
|
||||
setSpeedBusy(true)
|
||||
const durationSec = Math.max(3, Number.parseInt(probe.durationSec, 10) || 10)
|
||||
const runId = `speed-${Date.now()}`
|
||||
@@ -1806,13 +1817,15 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
} catch (e) {
|
||||
if (context !== saveContext.current) return
|
||||
const message = serverOperationError(e)
|
||||
const persistenceUnknown = isSpeedPersistenceUnknown(e, runId)
|
||||
setSpeedUnknownRunId(persistenceUnknown ? runId : null)
|
||||
setSpeedRuns((prev) => prev.map((r) => r.id === runId ? ({
|
||||
...r,
|
||||
status: "error",
|
||||
lines: [`status: error`, message],
|
||||
status: persistenceUnknown ? "unknown" : "error",
|
||||
lines: [`status: ${persistenceUnknown ? "unknown" : "error"}`, message],
|
||||
}) : r))
|
||||
setSpeedError(message)
|
||||
if (!isSpeedPersistenceUnknown(e, runId)) setSpeedProbes((prev) => prev.map((p) => p.id === probe.id ? ({
|
||||
if (!persistenceUnknown) setSpeedProbes((prev) => prev.map((p) => p.id === probe.id ? ({
|
||||
...p,
|
||||
lastRunAt: new Date().toISOString(),
|
||||
lastStatus: "error",
|
||||
@@ -2107,7 +2120,7 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
{/* ── error ── */}
|
||||
{speedError && (
|
||||
<div className="mx-6 mt-4">
|
||||
<Alert variant="destructive" className="py-2 text-xs">
|
||||
<Alert variant={speedUnknownRunId ? "default" : "destructive"} className="py-2 text-xs">
|
||||
<AlertCircleIcon />
|
||||
<AlertDescription>{speedError}</AlertDescription>
|
||||
</Alert>
|
||||
@@ -2160,7 +2173,7 @@ function UptimePageContent({ selectedProbeId, allProbesHref }: { selectedProbeId
|
||||
const run = speedRuns.find((r) =>
|
||||
sameSpeedMeasurement(r, probe),
|
||||
)
|
||||
const useRun = run && (run.status === "running" || (
|
||||
const useRun = run && run.status !== "unknown" && (run.status === "running" || (
|
||||
probe.lastStatus != null && probe.lastRunAt != null && run.startedAt >= Date.parse(probe.lastRunAt)
|
||||
))
|
||||
const viewStatus = useRun ? run.status : (probe.lastStatus === "error" || probe.lastStatus === "done" ? probe.lastStatus : null)
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface SpeedTestRunRow {
|
||||
durationSec: number
|
||||
txAvgMbps: number | null
|
||||
rxAvgMbps: number | null
|
||||
status: "running" | "done" | "error"
|
||||
status: "running" | "done" | "error" | "unknown"
|
||||
afterBtPing?: { rttMs: number | null; lossPct: number | null; error: string | null } | null
|
||||
srcInterfaceAddress?: string | null
|
||||
dstInterfaceAddress?: string | null
|
||||
@@ -130,6 +130,14 @@ function UptimeSpeedHistoryDataGrid({ runs, servers }: UptimeSpeedHistoryDataGri
|
||||
if (status === "error") {
|
||||
return <span className="text-[var(--status-offline-fg)] text-xs">error</span>
|
||||
}
|
||||
if (status === "unknown") {
|
||||
return (
|
||||
<div className="max-w-64 text-xs text-[var(--status-degraded-fg)]">
|
||||
<span>Сохранение не подтверждено</span>
|
||||
<div className="mt-1 font-mono wrap-anywhere">runId: {row.original.id}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return <span className="text-[var(--status-online-fg)] text-xs">done</span>
|
||||
},
|
||||
meta: { headerTitle: "Статус", headerClassName: DATA_GRID_CELL_PAD, cellClassName: DATA_GRID_CELL_PAD },
|
||||
|
||||
@@ -117,3 +117,11 @@ BGP-prefix evaluator, отдельное live GRE расписание и recove
|
||||
## Локальный snapshot guard — 2026-10-08
|
||||
|
||||
12.5.20 сохраняетlastconfirmedspeed snapshot дляunknown502/совпадающегоrunId.2unit tests/frontendtypecheck passed;browserunknownUX ещёнепроверен,patchнеразвёрнут. Backend4c12c55/frontend673e5ba прежние. Следующий12.5.21 — build/browserunknown/deploymentобоихобразов.
|
||||
|
||||
## Локальный unknown UX — 2026-10-08
|
||||
|
||||
12.5.21: отдельная строка unknown/runId, сохранение snapshot и сверка по идентификатору при чтении истории. 13 браузерных тестов с HTTP-моками/typecheck/ESLint прошли; это не приёмка real browser/PG. Основной backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка и проверка обновлённых образов. Полный 12.5 открыт.
|
||||
|
||||
## Локальный unknown UX — 2026-10-08
|
||||
|
||||
12.5.21: отдельная строка unknown/runId, сохранение snapshot и сверка по идентификатору при чтении истории. 13 браузерных тестов с HTTP-моками/typecheck/ESLint прошли; это не приёмка real browser/PG. Основной backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка и проверка обновлённых образов. Полный 12.5 открыт.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# План реализации UX/UI по пятичасовым окнам
|
||||
|
||||
Актуальное продолжение 2026-10-08:12.5.20 завершёнлокально — unknown502/currentrunId не переписываетподтверждённыйsnapshot пробы.2unit tests/frontendtypecheck passed;временнаястроказапросаещёerror,полныйbrowserunknownUX открыт. Runtimebackend4c12c55/frontend673e5ba прежние. Следующий12.5.21 — build/browserunknownspeed/deploymentобоихобразов.
|
||||
Актуальное продолжение 2026-10-08: 12.5.21 завершён локально — speed unknown отображается отдельно от error, сохраняется при чтении пустой истории и сверяется по runId. Последний подтверждённый snapshot пробы сохранён. 13 браузерных тестов с HTTP-моками, frontend typecheck и ESLint прошли. Основной runtime backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment.
|
||||
|
||||
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-07. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
|
||||
|
||||
|
||||
+17
-1
@@ -1,6 +1,6 @@
|
||||
# UX/UI: журнал реализации
|
||||
|
||||
Актуальное продолжение 2026-10-08:12.5.20 завершёнлокально — unknown502/currentrunId не переписываетподтверждённыйsnapshot пробы.2unit tests/frontendtypecheck passed;временнаястроказапросаещёerror,полныйbrowserunknownUX открыт. Runtimebackend4c12c55/frontend673e5ba прежние. Следующий12.5.21 — build/browserunknownspeed/deploymentобоихобразов.
|
||||
Актуальное продолжение 2026-10-08: 12.5.21 завершён локально — speed unknown отображается отдельно от error, сохраняется при чтении пустой истории и сверяется по runId. Последний подтверждённый snapshot пробы сохранён. 13 браузерных тестов с HTTP-моками, frontend typecheck и ESLint прошли. Основной runtime backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment.
|
||||
|
||||
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
|
||||
|
||||
@@ -34,6 +34,22 @@
|
||||
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
|
||||
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в описанных границах:12.3.83,main1186/1186,context221/221. Этап остаётся в работе: стенд12.5.1–3 развёрнут,bootstrap/smoke проверены;остальные сценарии12.5 не выполнены. |
|
||||
|
||||
## 12.5.21 — неопределённый исход speed-запуска и сверка с историей (2026-10-08)
|
||||
|
||||
В локальной строке запуска введён status unknown: «Сохранение не подтверждено», с видимым runId; это не новый статус серверного DTO (история API по-прежнему принимает только done/error). При обновлении истории незавершённая или неподтверждённая локальная строка сохраняется, если её идентификатора нет в ответе. Подтверждённая строка с тем же runId заменяет локальную, предупреждение снимается. Unknown не подменяет последний подтверждённый snapshot карточки пробы; предупреждение показано без destructive-оформления. Автоматического повторного сетевого теста нет. Ручной новый запуск остаётся доступен; предупреждение просит проверить историю перед повтором. Состояние локальной строки не сохраняется после перезагрузки страницы.
|
||||
|
||||
Проверки: 13/13 Playwright (uptime-speed-data и uptime-speed-unknown) за 27.7s, включая unknown → пустая история → done/error, сохранение TX42, один POST и адаптацию 320px. Это live-ветка UI с HTTP-моками, не real PG/browser proof. Scoped frontend typecheck (tmp/tsconfig-speed-check.json, исключён старый ignored tmp build context) и ESLint изменённых файлов прошли. Существующие null/zero, malformed DTO, свежесть, независимые источники и Ping-состояния сохранены.
|
||||
|
||||
Основной backend4c12c55/frontend673e5ba не изменён. Новые backend/frontend исправления ещё не развёрнуты. Полный 12.5 открыт. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment. Локальный коммит без push.
|
||||
|
||||
## 12.5.21 — неопределённый исход speed-запуска и сверка с историей (2026-10-08)
|
||||
|
||||
В локальной строке запуска введён status unknown: «Сохранение не подтверждено», с видимым runId; это не новый статус серверного DTO (история API по-прежнему принимает только done/error). При обновлении истории незавершённая или неподтверждённая локальная строка сохраняется, если её идентификатора нет в ответе. Подтверждённая строка с тем же runId заменяет локальную, предупреждение снимается. Unknown не подменяет последний подтверждённый snapshot карточки пробы; предупреждение показано без destructive-оформления. Автоматического повторного сетевого теста нет. Ручной новый запуск остаётся доступен; предупреждение просит проверить историю перед повтором. Состояние локальной строки не сохраняется после перезагрузки страницы.
|
||||
|
||||
Проверки: 13/13 Playwright (uptime-speed-data и uptime-speed-unknown) за 27.7s, включая unknown → пустая история → done/error, сохранение TX42, один POST и адаптацию 320px. Это live-ветка UI с HTTP-моками, не real PG/browser proof. Scoped frontend typecheck (tmp/tsconfig-speed-check.json, исключён старый ignored tmp build context) и ESLint изменённых файлов прошли. Существующие null/zero, malformed DTO, свежесть, независимые источники и Ping-состояния сохранены.
|
||||
|
||||
Основной backend4c12c55/frontend673e5ba не изменён. Новые backend/frontend исправления ещё не развёрнуты. Полный 12.5 открыт. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment. Локальный коммит без push.
|
||||
|
||||
## 12.5.20 — сохранение подтверждённого speed snapshot при unknown receipt (2026-10-08)
|
||||
|
||||
Приостатке5%окнавыполненнебольшойлокальныйблокпередdeployment. Frontendcatch раньше ставилlastStatuserror/новыйlastRunAt любойошибкеPOSTspeed-test,включаяunknowncommit. Теперьподтверждённыйsnapshot пробысохраняется,еслиApiClientError502 содержитoutcomeunknown иrunId текущегозапроса. ЧужойrunId/неправильныйpayload/403/обычнаяошибка нераспознаютсякакэтотисход. Существующееservererrorсообщениепоказывается;новыекомпоненты/композицияReUIне менялись. Временнаястрокасамогозапросапо-прежнемуимеетstatuserror; полныйunknown-state/browserUX ещёнужнопроверить.
|
||||
|
||||
+17
-1
@@ -1,6 +1,6 @@
|
||||
# Этап 12: итоговая приёмка UX/UI
|
||||
|
||||
Актуальное продолжение 2026-10-08:12.5.20 завершёнлокально — unknown502/currentrunId не переписываетподтверждённыйsnapshot пробы.2unit tests/frontendtypecheck passed;временнаястроказапросаещёerror,полныйbrowserunknownUX открыт. Runtimebackend4c12c55/frontend673e5ba прежние. Следующий12.5.21 — build/browserunknownspeed/deploymentобоихобразов.
|
||||
Актуальное продолжение 2026-10-08: 12.5.21 завершён локально — speed unknown отображается отдельно от error, сохраняется при чтении пустой истории и сверяется по runId. Последний подтверждённый snapshot пробы сохранён. 13 браузерных тестов с HTTP-моками, frontend typecheck и ESLint прошли. Основной runtime backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment.
|
||||
|
||||
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
|
||||
|
||||
@@ -1154,3 +1154,19 @@ SchedulerSnapshotError раньшеигнорировалruns[].okfalse уuptime
|
||||
Добавленыlib/speed-persistence-outcome.ts и2meaningfultests;подключенguardвuptime/page.tsx. Обаunit tests passed. ПервыйroottscподхватилкопиистарогоCI contextвignoredtmp ивернулисходныеошибкиэтихкопий. Повторныйполныйfrontendtypecheckсвременнымconfig,которыйсохраняетrootoptions/исключения иисключаетtmp,passed; основнойtsconfigне менялся. Diff-check passed. ReUI skillпрочитан: адаптациясуществующегоэкрана,безновойregistryinstallation/редизайна. Browserunknownspeed/productionbuild/deploymentвэтомблокенезапускались.
|
||||
|
||||
Основнойruntimebackend4c12c55/frontend673e5ba сохраняется;backendpatchf408afb иfrontendguardещёнеразвёрнуты. Следующий12.5.21 — собратьобаобновлённыхобраза,проверитьbrowserunknownspeed/историю иразвернутьпослепроверок. Журналобновлён;локальныйкоммитбезpush.
|
||||
|
||||
## 12.5.21 — неопределённый исход speed-запуска и сверка с историей (2026-10-08)
|
||||
|
||||
В локальной строке запуска введён status unknown: «Сохранение не подтверждено», с видимым runId; это не новый статус серверного DTO (история API по-прежнему принимает только done/error). При обновлении истории незавершённая или неподтверждённая локальная строка сохраняется, если её идентификатора нет в ответе. Подтверждённая строка с тем же runId заменяет локальную, предупреждение снимается. Unknown не подменяет последний подтверждённый snapshot карточки пробы; предупреждение показано без destructive-оформления. Автоматического повторного сетевого теста нет. Ручной новый запуск остаётся доступен; предупреждение просит проверить историю перед повтором. Состояние локальной строки не сохраняется после перезагрузки страницы.
|
||||
|
||||
Проверки: 13/13 Playwright (uptime-speed-data и uptime-speed-unknown) за 27.7s, включая unknown → пустая история → done/error, сохранение TX42, один POST и адаптацию 320px. Это live-ветка UI с HTTP-моками, не real PG/browser proof. Scoped frontend typecheck (tmp/tsconfig-speed-check.json, исключён старый ignored tmp build context) и ESLint изменённых файлов прошли. Существующие null/zero, malformed DTO, свежесть, независимые источники и Ping-состояния сохранены.
|
||||
|
||||
Основной backend4c12c55/frontend673e5ba не изменён. Новые backend/frontend исправления ещё не развёрнуты. Полный 12.5 открыт. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment. Локальный коммит без push.
|
||||
|
||||
## 12.5.21 — неопределённый исход speed-запуска и сверка с историей (2026-10-08)
|
||||
|
||||
В локальной строке запуска введён status unknown: «Сохранение не подтверждено», с видимым runId; это не новый статус серверного DTO (история API по-прежнему принимает только done/error). При обновлении истории незавершённая или неподтверждённая локальная строка сохраняется, если её идентификатора нет в ответе. Подтверждённая строка с тем же runId заменяет локальную, предупреждение снимается. Unknown не подменяет последний подтверждённый snapshot карточки пробы; предупреждение показано без destructive-оформления. Автоматического повторного сетевого теста нет. Ручной новый запуск остаётся доступен; предупреждение просит проверить историю перед повтором. Состояние локальной строки не сохраняется после перезагрузки страницы.
|
||||
|
||||
Проверки: 13/13 Playwright (uptime-speed-data и uptime-speed-unknown) за 27.7s, включая unknown → пустая история → done/error, сохранение TX42, один POST и адаптацию 320px. Это live-ветка UI с HTTP-моками, не real PG/browser proof. Scoped frontend typecheck (tmp/tsconfig-speed-check.json, исключён старый ignored tmp build context) и ESLint изменённых файлов прошли. Существующие null/zero, malformed DTO, свежесть, независимые источники и Ping-состояния сохранены.
|
||||
|
||||
Основной backend4c12c55/frontend673e5ba не изменён. Новые backend/frontend исправления ещё не развёрнуты. Полный 12.5 открыт. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment. Локальный коммит без push.
|
||||
@@ -125,3 +125,11 @@ ssh -N -L 3000:127.0.0.1:3000 -L 8000:127.0.0.1:8000 [email protected]
|
||||
## Локальный snapshot guard — 2026-10-08
|
||||
|
||||
12.5.20 сохраняетlastconfirmedspeed snapshot дляunknown502/совпадающегоrunId.2unit tests/frontendtypecheck passed;browserunknownUX ещёнепроверен,patchнеразвёрнут. Backend4c12c55/frontend673e5ba прежние. Следующий12.5.21 — build/browserunknown/deploymentобоихобразов.
|
||||
|
||||
## Локальный unknown UX — 2026-10-08
|
||||
|
||||
12.5.21: отдельная строка unknown/runId, сохранение snapshot и сверка по идентификатору при чтении истории. 13 браузерных тестов с HTTP-моками/typecheck/ESLint прошли; это не приёмка real browser/PG. Основной backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка и проверка обновлённых образов. Полный 12.5 открыт.
|
||||
|
||||
## Локальный unknown UX — 2026-10-08
|
||||
|
||||
12.5.21: отдельная строка unknown/runId, сохранение snapshot и сверка по идентификатору при чтении истории. 13 браузерных тестов с HTTP-моками/typecheck/ESLint прошли; это не приёмка real browser/PG. Основной backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка и проверка обновлённых образов. Полный 12.5 открыт.
|
||||
@@ -0,0 +1,65 @@
|
||||
import { test, expect } from "@playwright/test"
|
||||
import { server } from "./fixtures/users"
|
||||
|
||||
for (const confirmedStatus of ["done", "error"] as const) {
|
||||
test(`Speed: unknown receipt сохраняет snapshot и сверяется по runId/${confirmedStatus}`, async ({ page }) => {
|
||||
let runId = ""
|
||||
let confirmed = false
|
||||
let writes = 0
|
||||
const probe = {
|
||||
id: "probe-unknown", srcServerId: "1", dstServerId: "2",
|
||||
srcInterface: "ether1", dstInterface: "ether1", protocol: "tcp", direction: "transmit",
|
||||
durationSec: "3", enabled: true, lastStatus: "done", lastRunAt: "2026-10-03T00:00:00Z",
|
||||
lastTxAvgMbps: 42, lastRxAvgMbps: null, lastError: null,
|
||||
}
|
||||
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
|
||||
await page.route("**/api/**", route => {
|
||||
const path = new URL(route.request().url()).pathname
|
||||
if (path === "/api/uptime/speed-test" && route.request().method() === "POST") {
|
||||
writes++
|
||||
runId = route.request().postDataJSON().runId
|
||||
return route.fulfill({ status: 502, json: {
|
||||
outcome: "unknown", runId,
|
||||
error: `Сетевой тест завершён, сохранение результата не подтверждено. Проверьте историю по runId ${runId} перед повтором`,
|
||||
} })
|
||||
}
|
||||
return route.fulfill({ json:
|
||||
path === "/api/auth/config" ? { required: false } :
|
||||
path === "/api/servers" ? [server, { ...server, id: 2, name: "Приёмник", host: "192.0.2.2" }] :
|
||||
path === "/api/uptime/overview" ? { probes: [], resources: [] } :
|
||||
path === "/api/uptime/speed-probes" ? { probes: [probe] } :
|
||||
path === "/api/uptime/speed-test/runs" ? { runs: confirmed ? [{
|
||||
id: runId, srcServerId: "1", dstServerId: "2", srcInterface: "ether1", dstInterface: "ether1",
|
||||
protocol: "tcp", direction: "transmit", durationSec: 3, status: confirmedStatus,
|
||||
txAvgMbps: confirmedStatus === "done" ? 84 : null, rxAvgMbps: null,
|
||||
error: confirmedStatus === "error" ? "Подтверждённая ошибка" : null,
|
||||
createdAt: new Date().toISOString(),
|
||||
}] : [] } : {},
|
||||
})
|
||||
})
|
||||
await page.goto("/uptime?tab=speed")
|
||||
await page.getByRole("button", { name: "Пауза", exact: true }).click()
|
||||
const launch = page.getByRole("button", { name: "Запустить", exact: true })
|
||||
const card = launch.locator("xpath=../../..")
|
||||
await expect(card).toContainText("42 Мбит/с")
|
||||
await launch.click()
|
||||
await expect(page.getByText("Сохранение не подтверждено", { exact: true })).toBeVisible()
|
||||
const row = page.locator(`tr[data-row-id="${runId}"]`)
|
||||
await expect(row).toContainText(`runId: ${runId}`)
|
||||
await expect(row).not.toContainText("error")
|
||||
await expect(card).toContainText("42 Мбит/с")
|
||||
await page.setViewportSize({ width: 320, height: 1000 })
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true)
|
||||
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(row).toContainText("Сохранение не подтверждено")
|
||||
await expect(card).toContainText("42 Мбит/с")
|
||||
expect(writes).toBe(1)
|
||||
confirmed = true
|
||||
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect(row).toContainText(confirmedStatus)
|
||||
await expect(page.getByText("Сохранение не подтверждено", { exact: true })).toHaveCount(0)
|
||||
await expect(page.getByText(/Проверьте историю по runId/)).toHaveCount(0)
|
||||
if (confirmedStatus === "done") await expect(row).toContainText("84 Мбит/с")
|
||||
expect(writes).toBe(1)
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user