Files
MobilityOps/frontend/e2e/operational-workflows.spec.ts
T

103 lines
5.5 KiB
TypeScript

import { expect, test, type APIRequestContext, type Page } from "@playwright/test";
async function reset(request: APIRequestContext) {
expect((await request.post("/api/v1/demo/login", { data: { role: "operations_manager" } })).ok()).toBeTruthy();
expect((await request.post("/api/v1/demo/reset")).ok()).toBeTruthy();
expect((await request.post("/api/v1/demo/login", { data: { role: "operations_manager" } })).ok()).toBeTruthy();
}
async function login(page: Page) {
await page.goto("/login");
await page.getByRole("button", { name: "Verken als Operationsmanager" }).click();
await expect(page).toHaveURL(/\/dashboard$/);
}
test.describe.configure({ mode: "serial" });
test("operator can create and cancel a booking through the UI", async ({ page, request }) => {
await reset(request);
await login(page);
await page.goto("/bookings/new");
await page.getByLabel("Klant zoeken").fill("CUS-0001");
const customer = page.locator(".booking-create-form select").nth(0);
await expect.poll(() => customer.locator("option").count()).toBeGreaterThan(1);
await customer.selectOption({ index: 1 });
const vehicle = page.locator(".booking-create-form select").nth(1);
await expect.poll(() => vehicle.locator("option").count()).toBeGreaterThan(1);
await vehicle.selectOption({ index: 1 });
await page.getByRole("button", { name: "Boeking aanmaken" }).click();
await expect(page).toHaveURL(/\/bookings\/BK-/);
await expect(page.getByText("gereserveerd", { exact: true })).toBeVisible();
await expect(page.getByRole("heading", { name: "Vereisten controleren" })).toBeVisible();
await expect(page.getByRole("heading", { name: "Voertuig uitchecken" })).toHaveCount(0);
await page.getByLabel("Controlebewijs").fill("Rijbewijs en huurvoorwaarden gecontroleerd");
await page.getByRole("button", { name: "Vereisten bevestigen" }).click();
await expect(page.getByRole("heading", { name: "Voertuig uitchecken" })).toBeVisible();
await page.getByLabel("Reden", { exact: true }).fill("Klant annuleert de geplande rit");
await page.getByRole("button", { name: "Annulering bevestigen" }).click();
await expect(page.getByText("geannuleerd", { exact: true })).toBeVisible();
});
test("manager can create, edit and deactivate an operational user", async ({ page, request }) => {
await reset(request);
await login(page);
await page.goto("/users");
await page.getByLabel("Naam").fill("E2E Planner");
await page.getByLabel("E-mail").fill("e2e.planner@example.test");
await page.getByLabel("Tijdelijk wachtwoord").fill("secure-e2e-password");
await page.getByRole("button", { name: "Gebruiker toevoegen" }).click();
let row = page.getByRole("row", { name: /E2E Planner/ });
await expect(row).toBeVisible();
await row.getByRole("button", { name: "Bewerken" }).click();
const editor = page.locator(".user-edit");
await editor.getByLabel("Naam").fill("E2E Senior Planner");
await editor.getByLabel("Rol").selectOption("operations_manager");
await editor.getByLabel("Nieuw wachtwoord").fill("updated-e2e-password");
await editor.getByRole("button", { name: "Wijzigingen opslaan" }).click();
row = page.getByRole("row", { name: /E2E Senior Planner/ });
await expect(row.getByText("Operationeel beheerder")).toBeVisible();
await row.getByRole("button", { name: "Deactiveren" }).click();
await expect(row.getByText("inactief", { exact: true })).toBeVisible();
});
test("manager can assign data-quality work from the queue", async ({ page, request }) => {
await reset(request);
await login(page);
await page.goto("/data-quality?status=open");
const firstRow = page.locator(".data-table tbody tr").first();
const issueRef = (await firstRow.locator(".row-link").textContent())?.trim() ?? "";
expect(issueRef).not.toBe("");
await firstRow.getByRole("checkbox").check();
const assignee = page.getByLabel("Toewijzen aan");
await assignee.selectOption({ index: 1 });
const selectedLabel = await assignee.locator("option:checked").textContent();
await page.getByRole("button", { name: "Werkvoorraad bijwerken" }).click();
const updatedRow = page.locator(".data-table tbody tr").filter({
has: page.getByRole("link", { name: issueRef, exact: true }),
});
await expect(updatedRow).toContainText(selectedLabel ?? "");
});
test("manager can record maintenance and release a safe vehicle", async ({ page, request }) => {
await reset(request);
const vehicles = await (await request.get("/api/v1/vehicles?status=available")).json();
let selected = vehicles[0];
for (const candidate of vehicles) {
const detail = await (await request.get(`/api/v1/vehicles/${candidate.public_ref}`)).json();
if (!detail.attention && !detail.bookings.some((booking: { status: string }) => booking.status === "active")) {
selected = candidate;
break;
}
}
await login(page);
await page.goto(`/vehicles/${selected.public_ref}`);
await page.getByRole("tab", { name: "Onderhoud" }).click();
await page.getByRole("button", { name: "Onderhoud registreren" }).click();
await page.getByLabel("Uitgevoerd werk").fill("Periodiek onderhoud en veiligheidscontrole voltooid");
await page.getByRole("button", { name: "Onderhoud opslaan" }).click();
await expect(page.getByText("onderhoud", { exact: true }).first()).toBeVisible();
await page.getByLabel("Reden voor vrijgave").fill("Veiligheidscontrole afgerond zonder open punten");
await page.getByRole("button", { name: "Voertuig vrijgeven" }).click();
await expect(page.getByText("beschikbaar", { exact: true }).first()).toBeVisible();
});