chore(test): проверить большую историю со статусами файлов

This commit is contained in:
Denozordec committed 2026-10-14 14:48:58 +07:00
1 parent 026a358ca6
commit 3c3d152c2d
9 files changed
+162 -8

No files matched your search

@@ -0,0 +1,62 @@
import { test, expect } from "@playwright/test"
import { backupItemDtoSchema } from "../../packages/contracts/src/backups"
import { backup, setupBackups } from "./fixtures/backups"
import axe from "axe-core"
import { writeFileSync } from "node:fs"
for (const width of [1440, 320]) test(`Backups1000: смешанные состояния файлов ${width}`, async ({ page }, info) => {
test.setTimeout(90000)
await page.setViewportSize({ width, height: 1000 })
const states = ["missing", "missing", "unknown", "available"] as const
const catalog = Array.from({ length: 1000 }, (_, i) => backupItemDtoSchema.parse({
...backup, id: "backup-" + (i + 1), filename: "state-" + String(i + 1).padStart(4, "0") + ".rsc",
storage: i % 4 === 1 ? "both" : "local", localFileStatus: states[i % 4], sizeBytes: (i + 1) * 1024,
}))
let failed = false, reads = 0, writes = 0
await setupBackups(page)
page.on("request", r => { if (new URL(r.url()).pathname.startsWith("/api/backups") && r.method() !== "GET") writes++ })
await page.route("**/api/backups", r => { reads++; return r.fulfill(failed ? { status: 503, json: { error: "История недоступна" } } : { json: catalog }) })
const start = Date.now(); await page.goto("/backups")
const rows = page.locator("tr[data-row-id]")
await expect(page.getByText("state-0001.rsc", { exact: true })).toBeVisible()
await expect(rows).toHaveCount(50)
const sample = { date: "2026-10-14", block: "12.5.241", width, fixtureRows: 1000, fixtureBytes: Buffer.byteLength(JSON.stringify(catalog)), renderedRows: await rows.count(), domNodes: await page.locator("*").count(), readyMs: Date.now() - start }
expect(sample.domNodes).toBeLessThan(5000)
const search = page.getByPlaceholder("Поиск по файлу, серверу, заметке…")
await search.fill("state-0997"); await expect(rows).toHaveCount(1)
await expect(rows.first()).toHaveAttribute("data-row-id", "backup-997")
await expect(page.getByRole("button", { name: "Скачать state-0997.rsc", exact: true })).toBeDisabled()
await expect(page.getByRole("button", { name: "Восстановить state-0997.rsc", exact: true })).toBeDisabled()
const refresh = page.getByRole("button", { name: "Обновить", exact: true })
failed = true; await refresh.click()
await expect(page.getByRole("alert", { name: "Данные резервных копий: backups", exact: true })).toContainText("Последние данные сохранены")
await expect(rows).toHaveCount(1)
await expect(page.getByRole("button", { name: "Скачать state-0997.rsc", exact: true })).toBeDisabled()
failed = false; const before = reads; await refresh.click(); await expect.poll(() => reads).toBeGreaterThan(before)
await expect(page.getByRole("alert", { name: "Данные резервных копий: backups", exact: true })).toHaveCount(0)
const scroll = page.locator('[data-slot="data-grid"] [data-slot="scroll-area-viewport"]')
if (width === 320) await scroll.evaluate(el => { el.scrollLeft = el.scrollWidth })
const remove = page.getByRole("button", { name: "Удалить state-0997.rsc", exact: true })
await remove.focus(); await page.keyboard.press("Enter")
await expect(page.getByRole("alertdialog")).toContainText("Будет удалена только запись из истории.")
await page.getByRole("alertdialog").getByRole("button", { name: "Отмена", exact: true }).click()
await expect(remove).toBeFocused()
await search.fill("state-0998"); await expect(rows.first()).toHaveAttribute("data-row-id", "backup-998")
await expect(page.getByRole("button", { name: "Скачать state-0998.rsc", exact: true })).toBeEnabled()
await expect(page.getByRole("button", { name: "Восстановить state-0998.rsc", exact: true })).toBeEnabled()
await expect(page.getByText("Локальная копия отсутствует. Файл будет запрошен из S3.", { exact: true })).toBeVisible()
await search.fill("state-0999"); await expect(rows.first()).toHaveAttribute("data-row-id", "backup-999")
await expect(page.getByText("Не удалось проверить локальный файл.", { exact: true })).toBeVisible()
await expect(page.getByRole("button", { name: "Скачать state-0999.rsc", exact: true })).toBeEnabled()
await search.fill(""); await expect(rows).toHaveCount(50)
await page.getByRole("button", { name: "Следующая страница", exact: true }).click()
await expect(rows.first()).toHaveAttribute("data-row-id", "backup-51")
await refresh.click(); await expect(rows.first()).toHaveAttribute("data-row-id", "backup-51")
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true)
await page.addScriptTag({ content: axe.source })
const audit = await page.evaluate(async () => (window as unknown as { axe: typeof axe }).axe.run(document.querySelector('[data-slot="data-grid"]')!, { runOnly: { type: "tag", values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"] } }))
expect(audit.violations).toEqual([]); expect(writes).toBe(0)
const report = { ...sample, globalSearchAllRows: true, lastGoodStatusRetained: true, pagePreservedOnRefresh: true, keyboardCancelFocusRestored: true, scopedAxeViolations: 0, backupWrites: writes }
await info.attach("large-backup-file-states", { body: JSON.stringify(report), contentType: "application/json" })
writeFileSync(`docs/ux-ui/acceptance/backups241-large-${width}.json`, JSON.stringify(report, null, 2) + "\n")
})