95 lines
8.4 KiB
TypeScript
95 lines
8.4 KiB
TypeScript
import { test, expect } from "@playwright/test"
|
|
import { openBackup, backupJob, backupAck } from "./fixtures/backup-job"
|
|
import { backup, setupBackups } from "./fixtures/backups"
|
|
const headers = { "access-control-allow-origin": "*", "access-control-allow-methods": "GET,POST,PUT,DELETE,OPTIONS", "access-control-allow-headers": "Content-Type,Authorization" }
|
|
for (const change of ["backend", "mode"]) for (const fails of [false, true]) test("Бэкапы: позднее чтение/" + change + "/" + fails, async ({ page }) => {
|
|
await setupBackups(page, headers)
|
|
let started = false, completed = false, release!: () => void; const gate = new Promise<void>(r => release = r)
|
|
await page.route("**/api/backups", async r => {
|
|
if (new URL(r.request().url()).port !== "8000") return r.fallback()
|
|
started = true; await gate
|
|
try { await r.fulfill(fails ? { headers, status: 503, json: { error: "СТАРАЯ ОШИБКА БЭКАПА" } } : { headers, json: [{ ...backup, filename: "СТАРЫЙ БЭКАП.rsc" }] }) } catch {} finally { completed = true }
|
|
})
|
|
await page.goto("/backups"); await expect.poll(() => started).toBe(true); await page.goto("/settings")
|
|
if (change === "backend") { const input = page.getByPlaceholder("http://localhost:8000"); await input.fill("http://localhost:8101"); await input.press("Enter") }
|
|
else await page.getByRole("button", { name: "Моковые", exact: true }).click()
|
|
await page.goto("/backups"); release(); await expect.poll(() => completed).toBe(true)
|
|
if (change === "backend") await expect(page.getByText(backup.filename, { exact: true })).toBeVisible()
|
|
else { await expect(page.getByText("Демонстрационные данные. Операции и сохранение недоступны.", { exact: true })).toBeVisible(); await expect(page.getByRole("button", { name: "Новый бэкап", exact: true }).first()).toBeDisabled() }
|
|
await expect(page.getByText("СТАРЫЙ БЭКАП.rsc", { exact: true })).toHaveCount(0)
|
|
await expect(page.getByText(/СТАРАЯ ОШИБКА БЭКАПА/)).toHaveCount(0)
|
|
})
|
|
|
|
for (const kind of ["schedule", "storage"]) for (const fails of [false, true]) test("Бэкапы: позднее сохранение/" + kind + "/" + fails, async ({ page }) => {
|
|
await setupBackups(page, headers)
|
|
let started = false, completed = false, release!: () => void; const gate = new Promise<void>(r => release = r)
|
|
await page.route("**/api/backups/" + kind, async r => {
|
|
if (r.request().method() !== "PUT") return r.fallback()
|
|
started = true; await gate
|
|
try { await r.fulfill(fails ? { headers, status: 503, json: { error: "СТАРОЕ СОХРАНЕНИЕ БЭКАПА" } } : { headers, json: { ...r.request().postDataJSON(), secretConfigured: false, serverIds: ["1"] } }) } catch {} finally { completed = true }
|
|
})
|
|
await page.goto("/backups"); await page.getByRole("tab", { name: "Настройки", exact: true }).click()
|
|
const label = kind === "schedule" ? "Сохранить расписание" : "Сохранить хранилище"
|
|
await page.getByRole("button", { name: label, exact: true }).click(); await expect.poll(() => started).toBe(true)
|
|
await page.goto("/settings"); const input = page.getByPlaceholder("http://localhost:8000"); await input.fill("http://localhost:8101"); await input.press("Enter")
|
|
await page.goto("/backups"); release(); await expect.poll(() => completed).toBe(true)
|
|
await expect(page.getByText(backup.filename, { exact: true })).toBeVisible()
|
|
await expect(page.getByText(/СТАРОЕ СОХРАНЕНИЕ БЭКАПА/)).toHaveCount(0)
|
|
await expect(page.getByText(kind === "schedule" ? "Расписание сохранено" : "Хранилище сохранено", { exact: true })).toHaveCount(0)
|
|
})
|
|
|
|
for (const phase of ["POST", "poll"]) for (const change of ["backend", "mode"]) for (const fails of [false, true]) test("Бэкапы: поздний job/" + phase + "/" + change + "/" + fails, async ({ page }) => {
|
|
await setupBackups(page, headers)
|
|
let id = "", started = false, completed = false, release!: () => void; const gate = new Promise<void>(r => release = r)
|
|
await page.route("**/api/backups/create", async r => {
|
|
id = r.request().postDataJSON().requestId
|
|
if (phase !== "POST") return r.fulfill({ headers, status: 202, json: backupAck(id) })
|
|
started = true; await gate
|
|
try { await r.fulfill(fails ? { headers, status: 503, json: { error: "СТАРЫЙ JOB ОТКАЗ" } } : { headers, status: 202, json: backupAck(id) }) } catch {} finally { completed = true }
|
|
})
|
|
await page.route("**/api/backups/jobs/*", async r => {
|
|
if (phase !== "poll") return r.fulfill({ headers, json: backupJob(id) })
|
|
started = true; await gate
|
|
try { await r.fulfill(fails ? { headers, status: 503, json: { error: "СТАРЫЙ JOB ОТКАЗ" } } : { headers, json: backupJob(id) }) } catch {} finally { completed = true }
|
|
})
|
|
const dialog = await openBackup(page); await dialog.getByRole("button", { name: /Снять бэкап/ }).click(); await expect.poll(() => started).toBe(true)
|
|
await page.goto("/settings")
|
|
if (change === "backend") { const input = page.getByPlaceholder("http://localhost:8000"); await input.fill("http://localhost:8101"); await input.press("Enter") }
|
|
else await page.getByRole("button", { name: "Моковые", exact: true }).click()
|
|
await page.goto("/backups"); release(); await expect.poll(() => completed).toBe(true)
|
|
if (change === "backend") await expect(page.getByText(backup.filename, { exact: true })).toBeVisible()
|
|
else await expect(page.getByText("Демонстрационные данные. Операции и сохранение недоступны.", { exact: true })).toBeVisible()
|
|
await expect(page.getByText(/СТАРЫЙ JOB ОТКАЗ/)).toHaveCount(0)
|
|
await expect(page.getByText("API подтвердил создание всех резервных копий", { exact: true })).toHaveCount(0)
|
|
await expect(page.getByRole("button", { name: "Задача резервного копирования", exact: true })).toHaveCount(0)
|
|
})
|
|
|
|
for (const operation of ["delete", "restore", "download"]) for (const change of ["backend", "mode"]) for (const fails of [false, true]) test("Бэкапы: поздняя операция/" + operation + "/" + change + "/" + fails, async ({ page }) => {
|
|
await setupBackups(page, headers)
|
|
let started = false, completed = false, downloads = 0, release!: () => void; const gate = new Promise<void>(r => release = r)
|
|
page.on("download", () => downloads++)
|
|
const suffix = operation === "delete" ? "" : "/" + operation
|
|
await page.route("**/api/backups/backup-1" + suffix, async r => {
|
|
started = true; await gate
|
|
try {
|
|
if (fails) await r.fulfill({ headers, status: 503, json: { error: "СТАРАЯ ОПЕРАЦИЯ ОТКАЗАЛА" } })
|
|
else if (operation === "delete") await r.fulfill({ headers, status: 204 })
|
|
else if (operation === "restore") await r.fulfill({ headers, json: { backupId: backup.id, serverId: 1, filename: backup.filename, serverName: "СТАРЫЙ РОУТЕР" } })
|
|
else await r.fulfill({ headers, contentType: "text/plain", body: "old config" })
|
|
} catch {} finally { completed = true }
|
|
})
|
|
await page.goto("/backups")
|
|
const label = operation === "delete" ? "Удалить" : operation === "restore" ? "Восстановить" : "Скачать"
|
|
await page.getByRole("button", { name: label + " " + backup.filename, exact: true }).click()
|
|
if (operation !== "download") await page.getByRole("alertdialog").getByRole("button", { name: label, exact: true }).click()
|
|
await expect.poll(() => started).toBe(true); await page.goto("/settings")
|
|
if (change === "backend") { const input = page.getByPlaceholder("http://localhost:8000"); await input.fill("http://localhost:8101"); await input.press("Enter") }
|
|
else await page.getByRole("button", { name: "Моковые", exact: true }).click()
|
|
await page.goto("/backups"); release(); await expect.poll(() => completed).toBe(true)
|
|
if (change === "backend") await expect(page.getByText(backup.filename, { exact: true })).toBeVisible()
|
|
else await expect(page.getByText("Демонстрационные данные. Операции и сохранение недоступны.", { exact: true })).toBeVisible()
|
|
await expect(page.getByText(/СТАРАЯ ОПЕРАЦИЯ ОТКАЗАЛА|СТАРЫЙ РОУТЕР/)).toHaveCount(0)
|
|
await expect(page.getByText("API подтвердил удаление резервной копии", { exact: true })).toHaveCount(0)
|
|
await expect(page.getByRole("alertdialog")).toHaveCount(0); expect(downloads).toBe(0)
|
|
})
|