zerobyte/e2e/0002-backup-restore.spec.ts
Nicolas Meienberger 289832d58b
Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / e2e-tests (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled
e2e: fix flaky tests by adding page readiness chaeck
2026-02-17 20:28:18 +01:00

99 lines
4.8 KiB
TypeScript

import { expect, test } from "@playwright/test";
import path from "node:path";
import fs from "node:fs";
import { gotoAndWaitForAppReady } from "./helpers/page";
test.describe.configure({ mode: "serial" });
test.beforeAll(() => {
const testDataPath = path.join(process.cwd(), "playwright", "temp");
if (fs.existsSync(testDataPath)) {
for (const file of fs.readdirSync(testDataPath)) {
fs.rmSync(path.join(testDataPath, file), { recursive: true, force: true });
}
} else {
fs.mkdirSync(testDataPath, { recursive: true });
}
});
test("can backup & restore a file", async ({ page }) => {
await gotoAndWaitForAppReady(page, "/");
await expect(page).toHaveURL("/volumes");
// 0. Create a test file in /test-data
const testDataPath = path.join(process.cwd(), "playwright", "temp");
const filePath = path.join(testDataPath, "test.json");
fs.writeFileSync(filePath, JSON.stringify({ data: "test file" }));
// 1. Create a local volume on /test-data
await page.getByRole("button", { name: "Create Volume" }).click();
await page.getByRole("textbox", { name: "Name" }).fill("Test Volume");
await page.getByRole("button", { name: "test-data" }).click();
await page.getByRole("button", { name: "Create Volume" }).click();
await expect(page.getByText("Volume created successfully")).toBeVisible();
// 2. Create a local repository on the default location
await page.getByRole("link", { name: "Repositories" }).click();
await page.getByRole("button", { name: "Create repository" }).click();
await page.getByRole("textbox", { name: "Name" }).fill("Test Repo");
await page.getByRole("combobox", { name: "Backend" }).click();
await page.getByRole("option", { name: "Local" }).click();
await page.getByRole("button", { name: "Create repository" }).click();
await expect(page.getByText("Repository created successfully")).toBeVisible();
// 3. Create a backup schedule
await page.getByRole("link", { name: "Backups" }).click();
await page.getByRole("button", { name: "Create a backup job" }).click();
await page.getByRole("combobox").filter({ hasText: "Choose a volume to backup" }).click();
await page.getByRole("option", { name: "Test Volume" }).click();
await page.getByRole("textbox", { name: "Backup name" }).fill("Test Backup");
await page.getByRole("combobox").filter({ hasText: "Select a repository" }).click();
await page.getByRole("option", { name: "Test Repo" }).click();
await page.getByRole("combobox").filter({ hasText: "Select frequency" }).click();
await page.getByRole("option", { name: "Daily" }).click();
await page.getByRole("textbox", { name: "Execution time" }).fill("00:00");
await page.getByRole("button", { name: "Create" }).click();
await expect(page.getByText("Backup job created successfully")).toBeVisible();
// 4. Runs that schedule once
await page.getByRole("button", { name: "Backup now" }).click();
await expect(page.getByText("Backup started successfully")).toBeVisible();
await expect(page.getByText("✓ Success")).toBeVisible({ timeout: 30000 });
// 5. Modify the json file after the backup
fs.writeFileSync(filePath, JSON.stringify({ data: "modified file" }));
// 6. Restores the file from backup
await page.getByRole("button", { name: /20 B/ }).click();
await page.getByRole("link", { name: "Restore" }).click();
await expect(page).toHaveURL(/\/restore/);
await page.getByRole("button", { name: "Restore All" }).click();
await expect(page.getByText("Restore completed")).toBeVisible({ timeout: 30000 });
// 7. Ensures that the file is back to its previous state
const restoredContent = fs.readFileSync(filePath, "utf8");
expect(JSON.parse(restoredContent)).toEqual({ data: "test file" });
});
test("deleting a volume cascades and removes its backup schedule", async ({ page }) => {
await gotoAndWaitForAppReady(page, "/backups");
await page.getByText("Test Backup", { exact: true }).first().click();
const volumeLink = page.locator("main").getByRole("link", { name: "Test Volume", exact: true }).first();
await expect(volumeLink).toBeVisible();
await volumeLink.click();
await expect(page).toHaveURL(/\/volumes\/[^/?#]+/);
await expect(page.getByText("Volume Configuration", { exact: true })).toBeVisible();
await expect(page.getByRole("button", { name: "Delete" })).toBeVisible();
await expect(async () => {
await page.getByRole("button", { name: "Delete" }).click();
await expect(page.getByRole("heading", { name: "Delete volume?" })).toBeVisible();
}).toPass({ timeout: 10000 });
await expect(page.getByText("All backup schedules associated with this volume will also be removed.")).toBeVisible();
await page.getByRole("button", { name: "Delete volume" }).click();
await expect(page.getByText("Volume deleted successfully")).toBeVisible();
await gotoAndWaitForAppReady(page, "/backups");
await expect(page.getByText("Test Backup", { exact: true })).toHaveCount(0);
});