249 lines
8.0 KiB
TypeScript
249 lines
8.0 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import { mockApi, seedAuthenticatedState } from "./support/network.js";
|
|
import { isDesktopProject } from "./support/projects";
|
|
|
|
const json = (body: unknown, status = 200) => ({
|
|
status,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(body),
|
|
});
|
|
|
|
const suppressVersionCheck = async (page) => {
|
|
await page.addInitScript(() => {
|
|
window.localStorage.setItem("lastVersionCheck", String(Date.now()));
|
|
});
|
|
};
|
|
|
|
const mockAppShellRequests = async (page) => {
|
|
await page.route(/\/ping(\?.*)?$/i, async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
ok: true,
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(/\/worker\/version(\?.*)?$/i, async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
version: "test-build",
|
|
},
|
|
})
|
|
);
|
|
});
|
|
};
|
|
|
|
test.describe("Superuser department lanes", () => {
|
|
test("edits Shelly relay bindings through a fetched select list", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const lanes = [
|
|
{
|
|
id: 7,
|
|
department: 1,
|
|
name: "7",
|
|
status: "AVAILABLE",
|
|
relay_in_id: "IN-7",
|
|
relay_out_id: "OUT-7",
|
|
relay_machine_id: "M-7",
|
|
relay_machine_program_picker_id: "MPP-7",
|
|
relay_machine_cleaner_id: "MC-7",
|
|
dynamic_image_id: 77,
|
|
machine_type_id: null,
|
|
},
|
|
];
|
|
|
|
let lastUpdatePayload: Record<string, any> | null = null;
|
|
|
|
await seedAuthenticatedState(page, "superuser-department-lanes-token");
|
|
await suppressVersionCheck(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "list_department_lanes", "edit_department_lane"],
|
|
});
|
|
await mockAppShellRequests(page);
|
|
|
|
await page.route(
|
|
/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/department\/selfserve\/machine-types(\?.*)?$/i,
|
|
async (route) => {
|
|
await route.fulfill(json({ data: [] }));
|
|
}
|
|
);
|
|
|
|
await page.route(
|
|
/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/department\/lanes\/relay-options(\?.*)?$/i,
|
|
async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{ id: "shelly-plus-01", name: "Entry Gate (shelly-plus-01)" },
|
|
{ id: "shelly-plus-02", name: "Exit Gate (shelly-plus-02)" },
|
|
],
|
|
})
|
|
);
|
|
}
|
|
);
|
|
|
|
await page.route(/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/department\/lanes(\?.*)?$/i, async (route) => {
|
|
const request = route.request();
|
|
const parsedUrl = new URL(request.url());
|
|
|
|
if (request.method() === "GET") {
|
|
const laneId = parsedUrl.searchParams.get("id");
|
|
if (laneId) {
|
|
await route.fulfill(json({ data: lanes.find((lane) => String(lane.id) === laneId) || null }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ data: lanes }));
|
|
return;
|
|
}
|
|
|
|
if (request.method() === "PUT") {
|
|
lastUpdatePayload = request.postDataJSON() as Record<string, any>;
|
|
lanes[0] = {
|
|
...lanes[0],
|
|
...lastUpdatePayload,
|
|
};
|
|
|
|
await route.fulfill(json({ data: lanes[0] }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ data: lanes }));
|
|
});
|
|
|
|
await page.goto("/superuser/department/lanes", { waitUntil: "domcontentloaded" });
|
|
|
|
await expect(page).toHaveURL(/\/superuser\/department\/lanes$/);
|
|
const row = page.getByTestId("department-lanes-row-7");
|
|
const relayInField = page.getByTestId("department-lanes-row-detail-relay-in-id-7");
|
|
|
|
await expect(row).toContainText("7", { timeout: 15_000 });
|
|
await expect(row).toContainText("Aktiv", { timeout: 15_000 });
|
|
|
|
await page.getByTestId("department-lanes-row-toggle-7").click();
|
|
await expect(page.getByTestId("department-lanes-row-details-7")).toBeVisible();
|
|
await expect(relayInField).toContainText("IN-7");
|
|
|
|
await relayInField.click();
|
|
|
|
const modal = page.locator(".swal2-popup");
|
|
await expect(modal).toBeVisible();
|
|
|
|
const relaySelect = modal.locator("#relay_in_id");
|
|
await expect(relaySelect.locator("option").nth(0)).toHaveText("Ikke konfigureret");
|
|
await expect(relaySelect.locator("option").nth(1)).toHaveText("Entry Gate (shelly-plus-01)");
|
|
await expect(relaySelect.locator("option").nth(2)).toHaveText("Exit Gate (shelly-plus-02)");
|
|
|
|
await relaySelect.selectOption("shelly-plus-01");
|
|
await modal.locator(".swal2-confirm").click();
|
|
|
|
await expect(modal).toBeHidden();
|
|
expect(lastUpdatePayload).toMatchObject({
|
|
id: 7,
|
|
relay_in_id: "shelly-plus-01",
|
|
});
|
|
await expect(relayInField).toContainText("shelly-plus-01", { timeout: 15_000 });
|
|
});
|
|
|
|
test("keeps the advanced lanes table within a normal desktop viewport", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const lanes = [
|
|
{
|
|
id: 1,
|
|
department: 1,
|
|
name: "1",
|
|
status: "MAINTENANCE",
|
|
relay_in_id: "e4b323243f90",
|
|
relay_out_id: "e4b32327a610",
|
|
relay_machine_id: null,
|
|
relay_machine_program_picker_id: null,
|
|
relay_machine_cleaner_id: null,
|
|
dynamic_image_id: null,
|
|
machine_type_id: null,
|
|
},
|
|
{
|
|
id: 3,
|
|
department: 2,
|
|
name: "Roskilde primærbane",
|
|
status: "AVAILABLE",
|
|
relay_in_id: "e4b3231437d0",
|
|
relay_out_id: "e4b3231f6410",
|
|
relay_machine_id: "e4b3231cce40",
|
|
relay_machine_program_picker_id: "e4b063feb380",
|
|
relay_machine_cleaner_id: "dcb4d9cc3798",
|
|
dynamic_image_id: 1,
|
|
machine_type_id: 4,
|
|
},
|
|
];
|
|
|
|
await page.setViewportSize({ width: 1280, height: 720 });
|
|
await seedAuthenticatedState(page, "superuser-department-lanes-layout-token");
|
|
await suppressVersionCheck(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "list_department_lanes", "edit_department_lane"],
|
|
});
|
|
await mockAppShellRequests(page);
|
|
|
|
await page.route(
|
|
/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/department\/selfserve\/machine-types(\?.*)?$/i,
|
|
async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 4, name: "Klar til vask" }],
|
|
})
|
|
);
|
|
}
|
|
);
|
|
|
|
await page.route(/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/department\/lanes(\?.*)?$/i, async (route) => {
|
|
const request = route.request();
|
|
|
|
if (request.method() === "GET") {
|
|
await route.fulfill(json({ data: lanes }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ data: lanes[0] }));
|
|
});
|
|
|
|
await page.goto("/superuser/department/lanes", { waitUntil: "domcontentloaded" });
|
|
|
|
const table = page.getByTestId("department-lanes-table");
|
|
const row = page.getByTestId("department-lanes-row-3");
|
|
const details = page.getByTestId("department-lanes-row-details-3");
|
|
|
|
await expect(table).toBeVisible();
|
|
await expect(row).toContainText("Roskilde primærbane");
|
|
await expect(row).toContainText("Aktiv");
|
|
await expect(row).toContainText("Klar til vask");
|
|
|
|
const pageOverflow = await page.evaluate(() => {
|
|
const doc = document.documentElement;
|
|
return {
|
|
documentScrollWidth: doc.scrollWidth,
|
|
documentClientWidth: doc.clientWidth,
|
|
bodyScrollWidth: document.body.scrollWidth,
|
|
};
|
|
});
|
|
|
|
expect(pageOverflow.documentScrollWidth).toBeLessThanOrEqual(pageOverflow.documentClientWidth + 1);
|
|
expect(pageOverflow.bodyScrollWidth).toBeLessThanOrEqual(pageOverflow.documentClientWidth + 1);
|
|
|
|
await page.getByTestId("department-lanes-row-toggle-3").click();
|
|
await expect(details).toBeVisible();
|
|
await expect(details).toContainText("e4b3231437d0");
|
|
await expect(details).toContainText("e4b3231cce40");
|
|
await expect(details).toContainText("e4b063feb380");
|
|
await expect(page.getByTestId("department-lanes-row-workspace-3")).toBeVisible();
|
|
await expect(row.locator("button.action-settings-wheel-trigger").first()).toBeVisible();
|
|
});
|
|
});
|