Files
wehub-resource-sync b3a7f98e5a
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:23:53 +08:00

147 lines
5.3 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).
// Kumo 2.x renders <Button title> as a Tooltip popup rather than a DOM
// title attribute; aria-label is on the button itself.
await page.locator('button[aria-label^="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).
// See note above re: Kumo 2.x Button title -> Tooltip.
await page.locator('button[aria-label^="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,
});
});
});
});