Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
144 lines
5.1 KiB
TypeScript
144 lines
5.1 KiB
TypeScript
/**
|
|
* Redirects E2E Tests
|
|
*
|
|
* Tests creating, editing, and deleting URL redirects,
|
|
* plus the 404 tracking tab.
|
|
*/
|
|
|
|
import { test, expect } from "../fixtures";
|
|
|
|
test.describe("Redirects", () => {
|
|
test.beforeEach(async ({ admin }) => {
|
|
await admin.devBypassAuth();
|
|
});
|
|
|
|
test.describe("Empty state", () => {
|
|
test("displays redirects page with empty state", async ({ admin, page }) => {
|
|
await admin.goto("/redirects");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Should show the page heading
|
|
await admin.expectPageTitle("Redirects");
|
|
|
|
// Should have the "New Redirect" button
|
|
await expect(page.getByRole("button", { name: "New Redirect" })).toBeVisible();
|
|
|
|
// Should show empty state text
|
|
await expect(page.locator("text=No redirects yet")).toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe("CRUD", () => {
|
|
test("creates a redirect", async ({ admin, page }) => {
|
|
await admin.goto("/redirects");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Open create dialog
|
|
await page.getByRole("button", { name: "New Redirect" }).click();
|
|
await expect(page.locator('[role="dialog"]')).toBeVisible();
|
|
|
|
// Fill form
|
|
const dialog = page.locator('[role="dialog"]');
|
|
await dialog.locator('input[placeholder*="old-page"]').fill("/old-page");
|
|
await dialog.locator('input[placeholder*="new-page"]').fill("/new-page");
|
|
|
|
// Status code defaults to 301 -- leave it
|
|
|
|
// Submit
|
|
await dialog.getByRole("button", { name: "Create" }).click();
|
|
|
|
// Dialog should close
|
|
await expect(page.locator('[role="dialog"]')).not.toBeVisible({ timeout: 10000 });
|
|
|
|
// Redirect should appear in the list
|
|
await expect(page.locator("text=/old-page").first()).toBeVisible();
|
|
await expect(page.locator("text=/new-page").first()).toBeVisible();
|
|
});
|
|
|
|
test("edits a redirect", async ({ admin, page }) => {
|
|
await admin.goto("/redirects");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Create a redirect first
|
|
await page.getByRole("button", { name: "New Redirect" }).click();
|
|
const createDialog = page.locator('[role="dialog"]');
|
|
await createDialog.locator('input[placeholder*="old-page"]').fill("/edit-source");
|
|
await createDialog.locator('input[placeholder*="new-page"]').fill("/edit-dest-original");
|
|
await createDialog.getByRole("button", { name: "Create" }).click();
|
|
await expect(page.locator('[role="dialog"]')).not.toBeVisible({ timeout: 10000 });
|
|
|
|
// Wait for the redirect to appear
|
|
await expect(page.locator("text=/edit-source").first()).toBeVisible();
|
|
|
|
// Click the edit button on that row (use .first() to avoid ancestor div ambiguity)
|
|
await page.locator('button[title="Edit redirect"]').first().click();
|
|
|
|
// Edit dialog should open
|
|
await expect(page.locator('[role="dialog"]')).toBeVisible();
|
|
|
|
// Change the destination
|
|
const editDialog = page.locator('[role="dialog"]');
|
|
const destInput = editDialog.locator('input[placeholder*="new-page"]');
|
|
await destInput.clear();
|
|
await destInput.fill("/edit-dest-updated");
|
|
|
|
// Save
|
|
await editDialog.getByRole("button", { name: "Save" }).click();
|
|
await expect(page.locator('[role="dialog"]')).not.toBeVisible({ timeout: 10000 });
|
|
|
|
// Verify the updated destination is shown
|
|
await expect(page.locator("text=/edit-dest-updated").first()).toBeVisible();
|
|
await expect(page.locator("text=/edit-dest-original")).not.toBeVisible();
|
|
});
|
|
|
|
test("deletes a redirect", async ({ admin, page }) => {
|
|
await admin.goto("/redirects");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Create a redirect to delete
|
|
await page.getByRole("button", { name: "New Redirect" }).click();
|
|
const dialog = page.locator('[role="dialog"]');
|
|
await dialog.locator('input[placeholder*="old-page"]').fill("/to-delete");
|
|
await dialog.locator('input[placeholder*="new-page"]').fill("/deleted-dest");
|
|
await dialog.getByRole("button", { name: "Create" }).click();
|
|
await expect(page.locator('[role="dialog"]')).not.toBeVisible({ timeout: 10000 });
|
|
|
|
// Wait for it to appear
|
|
await expect(page.locator("text=/to-delete").first()).toBeVisible();
|
|
|
|
// Click the delete button on that row (use .first() to avoid ancestor div ambiguity)
|
|
await page.locator('button[title="Delete redirect"]').first().click();
|
|
|
|
// Confirm deletion in the ConfirmDialog
|
|
await expect(page.locator('[role="dialog"]')).toBeVisible();
|
|
await page.getByRole("button", { name: "Delete" }).click();
|
|
|
|
// Dialog should close
|
|
await expect(page.locator('[role="dialog"]')).not.toBeVisible({ timeout: 10000 });
|
|
|
|
// Redirect should be gone
|
|
await expect(page.locator("text=/to-delete")).not.toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe("404 Tracking", () => {
|
|
test("renders the 404 errors tab", async ({ admin, page }) => {
|
|
await admin.goto("/redirects");
|
|
await admin.waitForShell();
|
|
await admin.waitForLoading();
|
|
|
|
// Click the "404 Errors" tab
|
|
await page.locator("button", { hasText: "404 Errors" }).click();
|
|
|
|
// Should show the empty state for 404s
|
|
await expect(page.locator("text=No 404 errors recorded yet")).toBeVisible({
|
|
timeout: 10000,
|
|
});
|
|
});
|
|
});
|
|
});
|