292 lines
8.3 KiB
TypeScript
292 lines
8.3 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import { seedAuthenticatedState } from "./support/network.js";
|
|
import { isDesktopProject } from "./support/projects";
|
|
|
|
const json = (body: unknown, status = 200) => ({
|
|
status,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(body),
|
|
});
|
|
|
|
test.describe("Superuser products layout", () => {
|
|
test("fits a normal desktop viewport and exposes secondary product fields behind details rows", async ({
|
|
page,
|
|
}, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const pageErrors: string[] = [];
|
|
const consoleErrors: string[] = [];
|
|
|
|
page.on("pageerror", (error) => {
|
|
pageErrors.push(error.stack || error.message);
|
|
});
|
|
|
|
page.on("console", (message) => {
|
|
if (message.type() === "error" && !message.text().includes("Invalid version check response")) {
|
|
consoleErrors.push(message.text());
|
|
}
|
|
});
|
|
|
|
const products = [
|
|
{
|
|
id: 1,
|
|
order_priority: 40,
|
|
name: "Trækker",
|
|
description:
|
|
"Trækkende køretøj med en lang beskrivelse der tidligere skubbede hele products-tabellen ud over normale desktopskærme.",
|
|
price: 579,
|
|
subscription_allowed: true,
|
|
category: 8,
|
|
piktogram: "01",
|
|
economic_product_id: 101,
|
|
apply_category_discount: true,
|
|
requires_note: false,
|
|
is_wash: true,
|
|
display_in_booking_form: true,
|
|
},
|
|
{
|
|
id: 2,
|
|
order_priority: 50,
|
|
name: "Trailer",
|
|
description: "Standard trailer-vask.",
|
|
price: 599,
|
|
subscription_allowed: true,
|
|
category: 8,
|
|
piktogram: "02",
|
|
economic_product_id: 102,
|
|
apply_category_discount: true,
|
|
requires_note: false,
|
|
is_wash: true,
|
|
display_in_booking_form: true,
|
|
},
|
|
{
|
|
id: 3,
|
|
order_priority: 60,
|
|
name: "Undervognsskyl pr. enhed",
|
|
description: "Tilvalg til undervognsskyl.",
|
|
price: 89,
|
|
subscription_allowed: false,
|
|
category: 8,
|
|
piktogram: "03",
|
|
economic_product_id: 103,
|
|
apply_category_discount: false,
|
|
requires_note: false,
|
|
is_wash: true,
|
|
display_in_booking_form: false,
|
|
},
|
|
{
|
|
id: 4,
|
|
order_priority: 70,
|
|
name: "Fælg Flex pr. enhed",
|
|
description: "Tilvalg til fælgvask.",
|
|
price: 129,
|
|
subscription_allowed: false,
|
|
category: 8,
|
|
piktogram: "04",
|
|
economic_product_id: 104,
|
|
apply_category_discount: false,
|
|
requires_note: true,
|
|
is_wash: true,
|
|
display_in_booking_form: false,
|
|
},
|
|
];
|
|
const categories = [{ id: 8, name: "Udvendig" }];
|
|
const productOptions = [
|
|
{
|
|
id: 9001,
|
|
product_id: 1,
|
|
option_id: 3,
|
|
name: "Undervognsskyl pr. enhed",
|
|
min: 0,
|
|
max: 1,
|
|
},
|
|
{
|
|
id: 9002,
|
|
product_id: 1,
|
|
option_id: 4,
|
|
name: "Fælg Flex pr. enhed",
|
|
min: 0,
|
|
max: 1,
|
|
},
|
|
];
|
|
const economicProducts = [
|
|
{ id: 101, name: "Trækker (01)" },
|
|
{ id: 102, name: "Trailer (02)" },
|
|
{ id: 103, name: "Undervognsskyl (03)" },
|
|
{ id: 104, name: "Fælg Flex (04)" },
|
|
];
|
|
|
|
await page.setViewportSize({ width: 1280, height: 720 });
|
|
await seedAuthenticatedState(page, "superuser-products-layout-token");
|
|
|
|
await page.route(/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/.*/i, async (route) => {
|
|
const request = route.request();
|
|
const url = new URL(request.url());
|
|
const pathname = url.pathname;
|
|
const method = request.method();
|
|
|
|
if (pathname.endsWith("/auth/session") && method === "GET") {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
id: 1,
|
|
customer_number: 12345,
|
|
group_id: 1,
|
|
email: "e2e@example.com",
|
|
phone: {
|
|
number: "12345678",
|
|
country_code: 45,
|
|
},
|
|
notifications: {
|
|
wash_certificate_email: null,
|
|
email_notifications_enabled: true,
|
|
sms_notifications_enabled: false,
|
|
},
|
|
display_name: "E2E User",
|
|
permissions: ["superuser", "user"],
|
|
economic_customer: [],
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: null,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (
|
|
(pathname.endsWith("/auth/recaptcha/pre-check") || pathname.endsWith("/auth/reCAPTCHA/public")) &&
|
|
method === "GET"
|
|
) {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
recaptcha: {
|
|
enabled: false,
|
|
site_key: "",
|
|
},
|
|
rate_limit: {
|
|
enabled: false,
|
|
limit: 0,
|
|
remaining: 0,
|
|
reset: 0,
|
|
warning: null,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/ping") && method === "GET") {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
ok: true,
|
|
},
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/worker/version") && method === "GET") {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
version: "cc0b238d",
|
|
},
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/departments") && method === "GET") {
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 1, name: "Hvidovre", visible: true }],
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/categories") && method === "GET") {
|
|
await route.fulfill(json({ data: categories }));
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/product/options") && method === "GET") {
|
|
await route.fulfill(json({ data: productOptions }));
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/economic/products") && method === "GET") {
|
|
await route.fulfill(json({ data: economicProducts }));
|
|
return;
|
|
}
|
|
|
|
if (pathname.endsWith("/products") && method === "GET") {
|
|
const perPage = Number(url.searchParams.get("limit") || "100");
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: products,
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: perPage,
|
|
total: products.length,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ data: [] }));
|
|
});
|
|
|
|
await page.goto("/superuser/products");
|
|
|
|
const table = page.getByTestId("superuser-products-table");
|
|
const row = page.getByTestId("products-table-row-1");
|
|
const detailsToggle = page.getByTestId("products-table-row-toggle-1");
|
|
const detailsRow = page.getByTestId("products-table-row-details-1");
|
|
|
|
await expect(table).toBeVisible();
|
|
await expect(row).toContainText("Trækker");
|
|
await expect(row).toContainText("579");
|
|
await expect(row).toContainText("Udvendig");
|
|
await expect(row).toContainText("Ja");
|
|
|
|
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 detailsToggle.click();
|
|
await expect(detailsRow).toBeVisible();
|
|
await expect(detailsRow).toContainText("Trækkende køretøj");
|
|
await expect(detailsRow).toContainText("Trækker (01)");
|
|
await expect(detailsRow).toContainText("Undervognsskyl pr. enhed");
|
|
await expect(detailsRow).toContainText("Fælg Flex pr. enhed");
|
|
|
|
const actionTrigger = row.locator("button.action-settings-wheel-trigger").first();
|
|
await expect(actionTrigger).toBeVisible();
|
|
await actionTrigger.click();
|
|
await expect(page.locator(".dropdown.is-active .dropdown-content")).toContainText(/produkt/i);
|
|
|
|
expect(pageErrors).toEqual([]);
|
|
expect(consoleErrors).toEqual([]);
|
|
});
|
|
});
|