first commit
This commit is contained in:
204
e2e/tests/menus.spec.ts
Normal file
204
e2e/tests/menus.spec.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* Menus E2E Tests
|
||||
*
|
||||
* Tests creating, editing, and managing navigation menus.
|
||||
* Runs against an isolated fixture — starts with no menus.
|
||||
*/
|
||||
|
||||
import { test, expect } from "../fixtures";
|
||||
|
||||
test.describe("Menus", () => {
|
||||
test.beforeEach(async ({ admin }) => {
|
||||
await admin.devBypassAuth();
|
||||
});
|
||||
|
||||
test.describe("Menu List", () => {
|
||||
test("displays menus page", async ({ admin }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Should show menus heading
|
||||
await admin.expectPageTitle("Menus");
|
||||
|
||||
// Should have Create Menu button
|
||||
await expect(admin.page.getByRole("button", { name: "Create Menu" }).first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("shows empty state when no menus", async ({ admin }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Should show empty state message
|
||||
await expect(admin.page.locator("text=No menus yet")).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Create Menu", () => {
|
||||
test("opens create menu dialog", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Click create menu button
|
||||
await page.getByRole("button", { name: "Create Menu" }).first().click();
|
||||
|
||||
// Dialog should appear
|
||||
await expect(page.locator('[role="dialog"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test("creates a new menu", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
const menuName = `test-menu-${Date.now()}`;
|
||||
const menuLabel = "E2E Test Menu";
|
||||
|
||||
// Create menu
|
||||
await admin.createMenu(menuName, menuLabel);
|
||||
|
||||
// Should redirect to menu editor
|
||||
await expect(page).toHaveURL(new RegExp(`/menus/${menuName}$`));
|
||||
|
||||
// Should show the menu label
|
||||
await expect(page.locator("h1")).toContainText(menuLabel);
|
||||
});
|
||||
|
||||
test("cancels menu creation", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Open dialog
|
||||
await page.getByRole("button", { name: "Create Menu" }).first().click();
|
||||
|
||||
// Click cancel
|
||||
await page.click('button:has-text("Cancel")');
|
||||
|
||||
// Dialog should close
|
||||
await expect(page.locator('[role="dialog"]')).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Edit Menu", () => {
|
||||
test("shows empty items state for new menu", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Create a new empty menu
|
||||
const menuName = `empty-menu-${Date.now()}`;
|
||||
await admin.createMenu(menuName, "Empty Menu");
|
||||
|
||||
// Should show empty state
|
||||
await expect(page.locator("text=No menu items yet")).toBeVisible();
|
||||
});
|
||||
|
||||
test("adds custom link to menu", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Create a new menu
|
||||
const menuName = `links-menu-${Date.now()}`;
|
||||
await admin.createMenu(menuName, "Links Menu");
|
||||
|
||||
// Add a custom link
|
||||
await admin.addMenuLink("Home", "https://example.com");
|
||||
|
||||
// Should show the new item in the menu editor
|
||||
const main = page.locator("main");
|
||||
await expect(main.locator("text=Home")).toBeVisible();
|
||||
await expect(main.locator("text=https://example.com")).toBeVisible();
|
||||
});
|
||||
|
||||
test("adds multiple menu items", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Create a new menu
|
||||
const menuName = `multi-menu-${Date.now()}`;
|
||||
await admin.createMenu(menuName, "Multi Menu");
|
||||
|
||||
// Add multiple links
|
||||
await admin.addMenuLink("Home", "https://example.com");
|
||||
await admin.addMenuLink("About", "https://example.com/about");
|
||||
await admin.addMenuLink("Contact", "https://example.com/contact");
|
||||
|
||||
// All URLs should be visible (unique to the menu items)
|
||||
await expect(page.locator("text=https://example.com").first()).toBeVisible();
|
||||
await expect(page.locator("text=https://example.com/about")).toBeVisible();
|
||||
await expect(page.locator("text=https://example.com/contact")).toBeVisible();
|
||||
});
|
||||
|
||||
test("deletes menu item", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Create menu with item
|
||||
const menuName = `delete-item-${Date.now()}`;
|
||||
await admin.createMenu(menuName, "Delete Item Menu");
|
||||
await admin.addMenuLink("To Delete", "https://example.com");
|
||||
|
||||
// Verify item exists
|
||||
await expect(page.locator("text=To Delete")).toBeVisible();
|
||||
|
||||
// Click the trash icon button (last button in the menu item row)
|
||||
const itemRow = page.locator(".border.rounded-lg").filter({ hasText: "To Delete" });
|
||||
await itemRow.locator("button").last().click();
|
||||
|
||||
// Item should be removed
|
||||
await admin.waitForLoading();
|
||||
await expect(page.locator("text=To Delete")).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Delete Menu", () => {
|
||||
test("deletes a menu from list", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Create a menu to delete
|
||||
const menuName = `to-delete-${Date.now()}`;
|
||||
const menuLabel = "To Delete Menu";
|
||||
await admin.createMenu(menuName, menuLabel);
|
||||
|
||||
// Go back to list
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Menu should be in list
|
||||
await expect(page.locator(`text=${menuLabel}`).first()).toBeVisible();
|
||||
|
||||
// Click trash icon on the menu card (last button in the card row)
|
||||
const menuCard = page.locator(".rounded-lg").filter({ hasText: menuLabel }).first();
|
||||
await menuCard.getByRole("button").last().click();
|
||||
|
||||
// Confirm deletion in alert dialog
|
||||
await page.getByRole("button", { name: "Delete" }).click();
|
||||
|
||||
// Menu should be removed
|
||||
await admin.waitForLoading();
|
||||
await expect(page.locator(`text=${menuLabel}`)).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("cancel delete keeps menu", async ({ admin, page }) => {
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Create a menu
|
||||
const menuName = `keep-menu-${Date.now()}`;
|
||||
const menuLabel = "Keep This Menu";
|
||||
await admin.createMenu(menuName, menuLabel);
|
||||
|
||||
// Go back to list
|
||||
await admin.goToMenus();
|
||||
await admin.waitForLoading();
|
||||
|
||||
// Click trash icon
|
||||
const menuCard = page.locator(".rounded-lg").filter({ hasText: menuLabel }).first();
|
||||
await menuCard.getByRole("button").last().click();
|
||||
|
||||
// Cancel deletion
|
||||
await page.getByRole("button", { name: "Cancel" }).click();
|
||||
|
||||
// Menu should still be there
|
||||
await expect(page.locator(`text=${menuLabel}`).first()).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user