chore(test): проверить большую историю со статусами файлов
This commit is contained in:
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")
|
||||
})
|
||||
Reference in new issue
Block a user