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

172 lines
5.4 KiB
TypeScript

/**
* Content CRUD E2E Tests
*
* Tests creating, reading, updating, and deleting content items.
* Runs against an isolated fixture with seeded posts and pages.
*
* Seed data:
* - posts: "First Post" (published), "Second Post" (published), "Draft Post" (draft)
* - pages: "About" (published), "Contact" (draft)
*/
import { test, expect } from "../fixtures";
// Regex patterns
// Edit-route navigation preserves the entry's locale as a `?locale=` search
// param (see #1242), so the URL may carry a query string after the ULID.
const CONTENT_EDIT_URL_PATTERN = /\/content\/posts\/[A-Z0-9]+(?:\?.*)?$/;
const CONTENT_ID_PATTERN = /\/content\/posts\/[A-Z0-9]+(?:\?.*)?$/;
const NEW_CONTENT_URL_PATTERN = /\/content\/posts\/new(?:[?#].*)?$/;
test.describe("Content CRUD", () => {
test.beforeEach(async ({ admin }) => {
await admin.devBypassAuth();
});
test.describe("Content List", () => {
test("displays content list with seeded items", async ({ admin }) => {
await admin.goToContent("posts");
await admin.waitForLoading();
// Should show the posts heading
await admin.expectPageTitle("Posts");
// Should have a table with content
await expect(admin.page.locator("table")).toBeVisible();
// Should show seeded posts
await expect(admin.page.getByRole("link", { name: "First Post", exact: true })).toBeVisible();
await expect(
admin.page.getByRole("link", { name: "Second Post", exact: true }),
).toBeVisible();
await expect(admin.page.getByRole("link", { name: "Draft Post", exact: true })).toBeVisible();
// Should have "Add New" link
await expect(admin.page.getByRole("link", { name: "Add New" })).toBeVisible();
});
test("clicking Add New navigates to content editor", async ({ admin }) => {
await admin.goToContent("posts");
await admin.waitForLoading();
// Click Add New
await admin.page.getByRole("link", { name: "Add New" }).click();
// Should navigate to new content page
await expect(admin.page).toHaveURL(NEW_CONTENT_URL_PATTERN, {
timeout: 10000,
});
});
});
test.describe("Create Content", () => {
test("creates new post with title", async ({ admin }) => {
await admin.goToNewContent("posts");
await admin.waitForLoading();
// Fill in title
await admin.fillField("title", "E2E Test Post");
// Save
await admin.clickSave();
// Should redirect to edit page with new ID (ULID)
await expect(admin.page).toHaveURL(CONTENT_EDIT_URL_PATTERN, {
timeout: 10000,
});
});
test("auto-generates slug from title", async ({ admin }) => {
await admin.goToNewContent("posts");
await admin.waitForLoading();
// Fill in title — slug should auto-generate
await admin.fillField("title", "My Amazing Blog Post");
// Check that slug field was auto-populated
const slugInput = admin.page.getByLabel("Slug");
await expect(slugInput).toHaveValue("my-amazing-blog-post");
});
});
test.describe("Edit Content", () => {
test("loads existing content for editing", async ({ admin }) => {
// Go to content list
await admin.goToContent("posts");
await admin.waitForLoading();
// Click on first content item to edit
await admin.page.getByRole("link", { name: "First Post", exact: true }).click();
// Should be on edit page
await expect(admin.page).toHaveURL(CONTENT_ID_PATTERN);
// Title field should be populated
await expect(admin.page.locator("#field-title")).toHaveValue("First Post");
});
test("saves updated content", async ({ admin }) => {
// Navigate to existing content
await admin.goToContent("posts");
await admin.waitForLoading();
// Click first item to edit
await admin.page.getByRole("link", { name: "First Post", exact: true }).click();
await admin.waitForLoading();
// Update title
const newTitle = `Updated Post ${Date.now()}`;
await admin.fillField("title", newTitle);
// Save
await admin.clickSave();
await admin.waitForSaveComplete();
// Verify the update persisted by reloading
await admin.page.reload();
await admin.waitForShell();
await admin.waitForLoading();
await expect(admin.page.locator("#field-title")).toHaveValue(newTitle);
});
});
test.describe("Content Status", () => {
test("displays content status badges", async ({ admin }) => {
await admin.goToContent("posts");
await admin.waitForLoading();
// Should show status badges (published and draft)
const statusBadges = admin.page.locator("span.inline-flex");
const count = await statusBadges.count();
expect(count).toBeGreaterThan(0);
});
test("publish action changes status", async ({ admin }) => {
// Create a new draft post first
await admin.goToNewContent("posts");
await admin.waitForLoading();
await admin.fillField("title", "Draft to Publish Test");
await admin.clickSave();
// Wait for redirect to edit page (confirms save succeeded)
await expect(admin.page).toHaveURL(CONTENT_EDIT_URL_PATTERN, {
timeout: 10000,
});
// Publish the draft
const publishButton = admin.page.getByRole("button", { name: "Publish", exact: true });
await expect(publishButton).toBeVisible();
await publishButton.click();
await admin.waitForLoading();
// Once live with no pending changes, the action flips to "Unpublish",
// confirming the status actually changed.
await expect(admin.page.getByRole("button", { name: "Unpublish" })).toBeVisible({
timeout: 10000,
});
});
});
});