test(ui): cover redesigned journeys and responsive shell
This commit is contained in:
@@ -20,14 +20,14 @@ test("five-minute demo script end to end", async ({ page, request }) => {
|
||||
|
||||
await test.step("1. login as Operations Manager", async () => {
|
||||
await page.goto("/login");
|
||||
await expect(page.getByText("Synthetic demo environment")).toBeVisible();
|
||||
await expect(page.getByText(/Synthetic proof of concept/)).toBeVisible();
|
||||
await page.getByRole("button", { name: "Open as Operations Manager" }).click();
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
});
|
||||
|
||||
await test.step("2. verify dashboard metrics are loaded", async () => {
|
||||
await expect(page.getByRole("heading", { name: "Operational metrics" })).toBeVisible();
|
||||
const metricValues = page.locator(".metric-value");
|
||||
await expect(page.getByRole("heading", { name: "Fleet readiness" })).toBeVisible();
|
||||
const metricValues = page.locator(".metric-cell dd");
|
||||
await expect(metricValues.first()).toBeVisible();
|
||||
const values = await metricValues.allTextContents();
|
||||
expect(values.length).toBeGreaterThan(0);
|
||||
@@ -50,7 +50,9 @@ test("five-minute demo script end to end", async ({ page, request }) => {
|
||||
|
||||
await page.getByLabel("End odometer (km)").fill(String(lowReading));
|
||||
await page.getByLabel("Fuel level (%)").fill("55");
|
||||
await page.getByRole("button", { name: "Register return" }).click();
|
||||
await page.getByRole("button", { name: "Review return" }).click();
|
||||
await expect(page.getByRole("heading", { name: "Review return impact" })).toBeVisible();
|
||||
await page.getByRole("button", { name: "Confirm return" }).click();
|
||||
|
||||
await expect(page.getByRole("heading", { name: "Return registered" })).toBeVisible();
|
||||
});
|
||||
@@ -83,14 +85,14 @@ test("five-minute demo script end to end", async ({ page, request }) => {
|
||||
await page.goto("/audit");
|
||||
await page.getByLabel("Action").fill("return_registered");
|
||||
await expect(page.locator(".data-table tbody tr").first()).toBeVisible();
|
||||
await expect(page.getByText("return_registered").first()).toBeVisible();
|
||||
await expect(page.getByText("return registered").first()).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step("9. verify responsive navigation at mobile width", async () => {
|
||||
await page.setViewportSize({ width: 360, height: 800 });
|
||||
await page.goto("/dashboard");
|
||||
await expect(page.getByText("Synthetic demo environment")).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "Dashboard" })).toBeVisible();
|
||||
await expect(page.getByText(/Synthetic demo data/).first()).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "Overview" }).first()).toBeVisible();
|
||||
const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth);
|
||||
const clientWidth = await page.evaluate(() => document.documentElement.clientWidth);
|
||||
expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 1);
|
||||
|
||||
@@ -17,16 +17,17 @@ test.beforeEach(async ({ page }) => {
|
||||
|
||||
test("all seven nav items navigate correctly", async ({ page }) => {
|
||||
const items: [string, RegExp][] = [
|
||||
["Dashboard", /\/dashboard$/],
|
||||
["Vehicles", /\/vehicles$/],
|
||||
["Overview", /\/dashboard$/],
|
||||
["Fleet", /\/vehicles$/],
|
||||
["Bookings", /\/bookings$/],
|
||||
["Data Quality", /\/data-quality$/],
|
||||
["Data quality", /\/data-quality$/],
|
||||
["Knowledge", /\/knowledge$/],
|
||||
["Automation", /\/automation$/],
|
||||
["Audit", /\/audit$/],
|
||||
["Integrations", /\/automation$/],
|
||||
["Audit trail", /\/audit$/],
|
||||
];
|
||||
const primaryNavigation = page.getByRole("navigation", { name: "Primary navigation" });
|
||||
for (const [label, urlPattern] of items) {
|
||||
await page.getByRole("link", { name: label }).click();
|
||||
await primaryNavigation.getByRole("link", { name: label, exact: true }).click();
|
||||
await expect(page).toHaveURL(urlPattern);
|
||||
}
|
||||
});
|
||||
@@ -123,7 +124,7 @@ test("audit page: action filter works", async ({ page }) => {
|
||||
await page.getByLabel("Action").fill("demo_login");
|
||||
await expect(page.locator(".data-table tbody tr").first()).toBeVisible();
|
||||
const actions = await page.locator(".data-table tbody tr td:nth-child(3)").allTextContents();
|
||||
expect(actions.every((a) => a.includes("demo_login"))).toBeTruthy();
|
||||
expect(actions.every((a) => a.includes("demo login"))).toBeTruthy();
|
||||
});
|
||||
|
||||
test("knowledge page: form submits and clears input", async ({ page }) => {
|
||||
@@ -146,7 +147,7 @@ test("rental employee role sees restricted automation page and cannot access res
|
||||
await page.getByRole("button", { name: "Switch role" }).click();
|
||||
await page.getByRole("button", { name: "Open as Rental Employee" }).click();
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
await page.getByRole("link", { name: "Automation" }).click();
|
||||
await page.getByRole("link", { name: "Integrations" }).click();
|
||||
await expect(
|
||||
page.getByText("Automation delivery status is visible to Operations Managers only."),
|
||||
).toBeVisible();
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { expect, test, type APIRequestContext } from "@playwright/test";
|
||||
|
||||
const API_BASE = process.env.MOBILITYOPS_API_URL ?? "http://localhost:8128";
|
||||
|
||||
async function resetDemoData(request: APIRequestContext) {
|
||||
await request.post(`${API_BASE}/api/v1/demo/login`, { data: { role: "operations_manager" } });
|
||||
await request.post(`${API_BASE}/api/v1/demo/reset`);
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page, request }) => {
|
||||
await resetDemoData(request);
|
||||
await page.goto("/login");
|
||||
await page.getByRole("button", { name: "Open as Operations Manager" }).click();
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
});
|
||||
|
||||
test("control-centre shell exposes landmarks, persisted readiness and active navigation", async ({ page }) => {
|
||||
await expect(page.getByRole("navigation", { name: "Primary navigation" })).toBeVisible();
|
||||
await expect(page.getByRole("main")).toBeVisible();
|
||||
await expect(page.getByRole("heading", { name: "Fleet readiness" })).toBeVisible();
|
||||
await expect(page.locator(".metric-cell dd").first()).not.toHaveText("");
|
||||
await expect(page.getByRole("link", { name: "Overview" }).first()).toHaveAttribute("aria-current", "page");
|
||||
});
|
||||
|
||||
test("return review separates capture from irreversible commit", async ({ page }) => {
|
||||
await page.goto("/bookings/BK-DEMO-RETURN");
|
||||
await page.getByLabel("End odometer (km)").fill("60000");
|
||||
await page.getByLabel("Fuel level (%)").fill("65");
|
||||
|
||||
let returnRequests = 0;
|
||||
page.on("request", (request) => {
|
||||
if (request.url().includes("/return") && request.method() === "POST") returnRequests += 1;
|
||||
});
|
||||
|
||||
await page.getByRole("button", { name: "Review return" }).click();
|
||||
expect(returnRequests).toBe(0);
|
||||
await expect(page.getByText("Expected fleet state")).toBeVisible();
|
||||
await expect(page.getByText("Queue n8n delivery after the local commit")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Edit details" }).click();
|
||||
await expect(page.getByLabel("End odometer (km)")).toHaveValue("60000");
|
||||
});
|
||||
|
||||
for (const width of [390, 768, 1280, 1440]) {
|
||||
test(`responsive shell has no horizontal overflow at ${width}px`, async ({ page }) => {
|
||||
await page.setViewportSize({ width, height: width < 700 ? 844 : 900 });
|
||||
await page.goto("/dashboard");
|
||||
await expect(page.getByRole("heading", { name: "Attention queue" })).toBeVisible();
|
||||
const dimensions = await page.evaluate(() => ({ scroll: document.documentElement.scrollWidth, client: document.documentElement.clientWidth }));
|
||||
expect(dimensions.scroll).toBeLessThanOrEqual(dimensions.client + 1);
|
||||
if (width < 960) await expect(page.getByRole("navigation", { name: "Mobile navigation" })).toBeVisible();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user