c901b1135d
* feat: flip routing — customer portal at /, admin at /admin Move all admin dashboard routes under /admin prefix and mount the customer portal at root (/). This gives customers clean, shareable URLs while staff bookmark /admin. - Admin routes: /admin, /admin/clients, /admin/services, etc. - Customer portal: / (root) - Admin nav "Customer Portal" link points to / for staff preview - Updated tests for new route structure and fixed React 19 act compat Closes #56 Co-Authored-By: Paperclip <noreply@paperclip.ing> * fix(e2e): update tests for routing flip — admin at /admin, portal at / All E2E tests now use /admin prefix for admin routes (clients, services, staff, invoices, reports, book). Adds customer portal smoke test at /. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(e2e): use specific locator for customer portal test getByText('Paws & Reflect') matched 3 elements causing strict mode violation. Scope to navigation role for unique match. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Groom Book CTO <cto@groombook.dev> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
|
|
/**
|
|
* Client management E2E tests.
|
|
*
|
|
* API calls are mocked so tests run without a live backend.
|
|
*/
|
|
|
|
const MOCK_CLIENTS = [
|
|
{
|
|
id: "client-1",
|
|
name: "Alice Johnson",
|
|
email: "alice@example.com",
|
|
phone: "555-0101",
|
|
address: null,
|
|
notes: null,
|
|
createdAt: "2026-01-01T00:00:00.000Z",
|
|
updatedAt: "2026-01-01T00:00:00.000Z",
|
|
},
|
|
{
|
|
id: "client-2",
|
|
name: "Bob Williams",
|
|
email: "bob@example.com",
|
|
phone: null,
|
|
address: null,
|
|
notes: null,
|
|
createdAt: "2026-01-02T00:00:00.000Z",
|
|
updatedAt: "2026-01-02T00:00:00.000Z",
|
|
},
|
|
];
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.route("/api/clients**", (route) =>
|
|
route.fulfill({ json: MOCK_CLIENTS })
|
|
);
|
|
// Pets loaded when a client is selected
|
|
await page.route("/api/pets**", (route) =>
|
|
route.fulfill({ json: [] })
|
|
);
|
|
});
|
|
|
|
test("clients page shows client list", async ({ page }) => {
|
|
await page.goto("/admin/clients");
|
|
await expect(page.getByText("Alice Johnson")).toBeVisible();
|
|
await expect(page.getByText("Bob Williams")).toBeVisible();
|
|
});
|
|
|
|
test("clients page shows search input", async ({ page }) => {
|
|
await page.goto("/admin/clients");
|
|
await expect(page.getByPlaceholder(/search/i)).toBeVisible();
|
|
});
|
|
|
|
test("clicking a client shows their details", async ({ page }) => {
|
|
await page.goto("/admin/clients");
|
|
await expect(page.getByText("Alice Johnson")).toBeVisible();
|
|
await page.getByText("Alice Johnson").click();
|
|
// Email appears in both the list row and the detail panel once selected
|
|
await expect(page.getByText("alice@example.com")).toHaveCount(2);
|
|
});
|