806 lines
24 KiB
TypeScript
806 lines
24 KiB
TypeScript
import { expect, Locator, test } from "@playwright/test";
|
|
import { apiPathPattern, 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),
|
|
});
|
|
|
|
async function triggerMenuHover(locator: Locator) {
|
|
await locator.dispatchEvent("mouseenter");
|
|
await locator.dispatchEvent("mouseover");
|
|
}
|
|
|
|
test.describe("Admin POS drafts", () => {
|
|
test("assigns a draft order to a customer, invoice collection, and recalculated pricing", async ({
|
|
page,
|
|
}, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const pageErrors: string[] = [];
|
|
const navigationRenderErrors: string[] = [];
|
|
|
|
page.on("pageerror", (error) => {
|
|
pageErrors.push(error.stack || error.message);
|
|
});
|
|
|
|
page.on("console", (message) => {
|
|
const text = message.text();
|
|
|
|
if (
|
|
message.type() === "error" ||
|
|
text.includes("Unhandled error during execution of render function") ||
|
|
text.includes("DesktopNavigationBuefy")
|
|
) {
|
|
navigationRenderErrors.push(`${message.type()}: ${text}`);
|
|
}
|
|
});
|
|
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: [
|
|
"admin",
|
|
"department_access_1",
|
|
"add_order",
|
|
"edit_order",
|
|
"list_orders",
|
|
"list_order_items",
|
|
"edit_order_items",
|
|
"list_products",
|
|
],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const currentOrder = {
|
|
id: 56625,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 5,
|
|
cashier_name: "Jeppe",
|
|
department_id: 1,
|
|
reg_1: "EC21233",
|
|
reg_2: null,
|
|
reg_3: null,
|
|
reference: "reff",
|
|
notes: "",
|
|
po: "po00",
|
|
total_net_amount: 111700,
|
|
created_at: "2026-04-20 13:20:57",
|
|
invoice_collection_id: 7001,
|
|
invoice_collection: {
|
|
id: 7001,
|
|
customer_number: 6001,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
},
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: null,
|
|
safety_seal: null,
|
|
};
|
|
const foreignDepartmentDraft = {
|
|
...currentOrder,
|
|
id: 56626,
|
|
department_id: 2,
|
|
reg_1: "ZZ99999",
|
|
reference: "foreign-draft",
|
|
};
|
|
|
|
const orderPutPayloads: Array<Record<string, unknown>> = [];
|
|
const orderItemsPutPayloads: Array<Record<string, unknown>> = [];
|
|
const productPriceRequests: Array<Record<string, string>> = [];
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 1, name: "Demo", visible: true }],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const request = route.request();
|
|
|
|
if (request.method() === "PUT") {
|
|
const payload = request.postDataJSON();
|
|
orderPutPayloads.push(payload);
|
|
|
|
if (payload.customer_id) {
|
|
currentOrder.customer_id = Number(payload.customer_id);
|
|
currentOrder.customer_name = "Acme Logistics";
|
|
}
|
|
|
|
if (payload.invoice_collection_id) {
|
|
currentOrder.invoice_collection_id = Number(payload.invoice_collection_id);
|
|
currentOrder.invoice_collection = {
|
|
id: Number(payload.invoice_collection_id),
|
|
customer_number: currentOrder.customer_id,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
};
|
|
}
|
|
|
|
await route.fulfill(json({ success: true, data: { message: "Order updated successfully" } }));
|
|
return;
|
|
}
|
|
|
|
const url = new URL(request.url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const includesDraftCustomer = filters.includes("customer_id:6001");
|
|
const includesDepartmentOne = filters.includes("department_id:1");
|
|
|
|
if (includesDraftCustomer && !includesDepartmentOne) {
|
|
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
await route.fulfill(
|
|
json({
|
|
data: [foreignDepartmentDraft],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: 1,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
return;
|
|
}
|
|
|
|
const includesDraftOrder = currentOrder.customer_id === 6001 && includesDraftCustomer && includesDepartmentOne;
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: includesDraftOrder ? [currentOrder] : [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: includesDraftOrder ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/customers"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
customerNumber: 424242,
|
|
name: "Acme Logistics",
|
|
city: "Roskilde",
|
|
},
|
|
],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: 1,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/collected-invoices"), async (route) => {
|
|
const request = route.request();
|
|
if (request.method() !== "GET") {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
const url = new URL(request.url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
if (!filters.includes("customer_number:424242")) {
|
|
await route.fulfill(json({ data: [], meta: { pagination: { page: 1, per_page: 100, total: 0 } } }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
id: 9001,
|
|
customer_number: 424242,
|
|
customer_name: "Acme Logistics",
|
|
created_at: "2026-04-18 09:00:00",
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
total_net_amount: 100000,
|
|
},
|
|
{
|
|
id: 9002,
|
|
customer_number: 424242,
|
|
customer_name: "Acme Logistics",
|
|
created_at: "2026-04-16 09:00:00",
|
|
closed_at: "2026-04-17 00:00:00",
|
|
booked_invoice_id: null,
|
|
total_net_amount: 250000,
|
|
},
|
|
],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: 2,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/order/items"), async (route) => {
|
|
const request = route.request();
|
|
|
|
if (request.method() === "PUT") {
|
|
orderItemsPutPayloads.push(request.postDataJSON());
|
|
await route.fulfill(json({ success: true, data: { message: "Order item updated" } }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
id: 8001,
|
|
order_id: currentOrder.id,
|
|
product_id: 101,
|
|
reference: "",
|
|
notes: "",
|
|
cashier_id: currentOrder.cashier_id,
|
|
price: 111700,
|
|
quantity: 1,
|
|
related_item_id: 0,
|
|
include_in_invoice: true,
|
|
product: {
|
|
id: 101,
|
|
name: "Truck wash",
|
|
price: 111700,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/products"), async (route) => {
|
|
const url = new URL(route.request().url());
|
|
productPriceRequests.push(Object.fromEntries(url.searchParams.entries()));
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
id: 101,
|
|
name: "Truck wash",
|
|
price: 99900,
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/admin/1/modules/pos/drafts");
|
|
await expect(page).toHaveURL(/\/admin\/1\/modules\/pos\/drafts$/);
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-label")).toBeVisible();
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-label")).toContainText("Kladder");
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-badge")).toBeVisible();
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-badge")).toHaveText("1");
|
|
expect(pageErrors).toEqual([]);
|
|
expect(navigationRenderErrors).toEqual([]);
|
|
await expect(page.getByTestId("draft-order-assign-customer-button-56625")).toBeVisible();
|
|
await page.waitForTimeout(250);
|
|
await expect(page.getByText("ZZ99999")).toHaveCount(0);
|
|
|
|
await page.getByTestId("draft-order-assign-customer-button-56625").click();
|
|
|
|
const modal = page.getByTestId("draft-order-assign-customer-modal");
|
|
await expect(modal).toBeVisible();
|
|
await expect(page.getByTestId("draft-order-recalculate-prices")).toBeChecked();
|
|
|
|
await page.getByTestId("draft-order-assign-customer-search").fill("Acme");
|
|
await page.getByTestId("draft-order-customer-option-424242").click();
|
|
await expect(page.getByTestId("draft-order-invoice-collection-option-9001")).toBeVisible();
|
|
await page.getByTestId("draft-order-invoice-collection-option-9002").click();
|
|
|
|
await page.getByTestId("draft-order-assign-submit").click();
|
|
|
|
await expect(modal).toHaveCount(0);
|
|
await expect(page.getByTestId("draft-order-assign-customer-button-56625")).toHaveCount(0);
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-badge")).toHaveCount(0);
|
|
|
|
expect(orderPutPayloads).toEqual([
|
|
{ id: 56625, customer_id: 424242 },
|
|
{ id: 56625, invoice_collection_id: 9002 },
|
|
]);
|
|
|
|
expect(orderItemsPutPayloads).toHaveLength(1);
|
|
expect(orderItemsPutPayloads[0]).toMatchObject({
|
|
id: 8001,
|
|
price: 99900,
|
|
quantity: 1,
|
|
});
|
|
|
|
expect(productPriceRequests).toHaveLength(1);
|
|
expect(productPriceRequests[0]).toMatchObject({
|
|
id: "101",
|
|
customer_id: "424242",
|
|
department_id: "1",
|
|
final_price: "true",
|
|
});
|
|
});
|
|
|
|
test("accepts a self-serve wash draft from the actions menu", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
test.skip(testInfo.project.name === "firefox-desktop", "Firefox cannot reliably target hover-only POS flyouts.");
|
|
|
|
await page.setViewportSize({ width: 1900, height: 900 });
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: [
|
|
"admin",
|
|
"department_access_1",
|
|
"add_order",
|
|
"edit_order",
|
|
"list_orders",
|
|
"list_order_items",
|
|
"edit_order_items",
|
|
"list_products",
|
|
],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const currentOrder = {
|
|
id: 56630,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 5,
|
|
cashier_name: "Jeppe",
|
|
department_id: 1,
|
|
reg_1: "EC21233",
|
|
reg_2: null,
|
|
reg_3: null,
|
|
reference: "self-serve",
|
|
notes: "",
|
|
po: "",
|
|
total_net_amount: 111700,
|
|
created_at: "2026-04-20 13:20:57",
|
|
invoice_collection_id: 7001,
|
|
invoice_collection: {
|
|
id: 7001,
|
|
customer_number: 6001,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
},
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: 12,
|
|
safety_seal: null,
|
|
};
|
|
const selfServeAttachment = {
|
|
id: 401,
|
|
object_type: "orders",
|
|
object_id: currentOrder.id,
|
|
content: {
|
|
image: null,
|
|
document: null,
|
|
relation: null,
|
|
other: {
|
|
type: "SELF_SERVE_WASH",
|
|
customer_number: 424242,
|
|
draft_customer_number: 6001,
|
|
subuser_id: 77,
|
|
subuser: {
|
|
name: "Driver One",
|
|
username: "driver-one",
|
|
},
|
|
license_plate: "EC21233",
|
|
elapsed_wash_time_seconds: 601,
|
|
},
|
|
src: null,
|
|
},
|
|
created_at: "2026-04-20 13:20:57",
|
|
updated_at: null,
|
|
deleted_at: null,
|
|
};
|
|
|
|
const orderPutPayloads: Array<Record<string, unknown>> = [];
|
|
const orderItemsPutPayloads: Array<Record<string, unknown>> = [];
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 1, name: "Demo", visible: true }],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders/attachments"), async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ success: true, data: [selfServeAttachment] }));
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const request = route.request();
|
|
const url = new URL(request.url());
|
|
|
|
if (!url.pathname.endsWith("/orders")) {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
if (request.method() === "PUT") {
|
|
const payload = request.postDataJSON();
|
|
orderPutPayloads.push(payload);
|
|
|
|
if (payload.customer_id) {
|
|
currentOrder.customer_id = Number(payload.customer_id);
|
|
currentOrder.customer_name = "Acme Logistics";
|
|
}
|
|
|
|
if (payload.invoice_collection_id) {
|
|
currentOrder.invoice_collection_id = Number(payload.invoice_collection_id);
|
|
currentOrder.invoice_collection = {
|
|
id: Number(payload.invoice_collection_id),
|
|
customer_number: currentOrder.customer_id,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
};
|
|
}
|
|
|
|
await route.fulfill(json({ success: true, data: { message: "Order updated successfully" } }));
|
|
return;
|
|
}
|
|
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const includesDraftOrder =
|
|
currentOrder.customer_id === 6001 &&
|
|
filters.includes("customer_id:6001") &&
|
|
filters.includes("department_id:1");
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: includesDraftOrder ? [currentOrder] : [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: Number(url.searchParams.get("limit") || "100"),
|
|
total: includesDraftOrder ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/collected-invoices"), async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
id: 9001,
|
|
customer_number: 424242,
|
|
customer_name: "Acme Logistics",
|
|
created_at: "2026-04-18 09:00:00",
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
total_net_amount: 100000,
|
|
},
|
|
],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: 100,
|
|
total: 1,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/order/items"), async (route) => {
|
|
if (route.request().method() === "PUT") {
|
|
orderItemsPutPayloads.push(route.request().postDataJSON());
|
|
await route.fulfill(json({ success: true, data: { message: "Order item updated" } }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{
|
|
id: 8001,
|
|
order_id: currentOrder.id,
|
|
product_id: 101,
|
|
reference: "",
|
|
notes: "",
|
|
cashier_id: currentOrder.cashier_id,
|
|
price: 111700,
|
|
quantity: 1,
|
|
related_item_id: 0,
|
|
include_in_invoice: true,
|
|
product: {
|
|
id: 101,
|
|
name: "Truck wash",
|
|
price: 111700,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/products"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: {
|
|
id: 101,
|
|
name: "Truck wash",
|
|
price: 99900,
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/admin/1/modules/pos/drafts", { waitUntil: "domcontentloaded" });
|
|
await expect(page.getByTestId("department-pos-drafts-page")).toBeVisible();
|
|
|
|
const settingsRoot = page.getByTestId("pos-order-list-settings-56630");
|
|
await expect(settingsRoot).toBeVisible();
|
|
await settingsRoot.locator(".dropdown-trigger > button").click();
|
|
|
|
await expect(settingsRoot.getByRole("button", { name: /Godkend selvbetjent vask/ })).toBeVisible();
|
|
|
|
await triggerMenuHover(settingsRoot.getByTestId("action-settings-wheel-section-attachments"));
|
|
await triggerMenuHover(settingsRoot.getByTestId("action-settings-wheel-attachment-row-401"));
|
|
await expect(settingsRoot.getByTestId("action-settings-wheel-attachment-panel")).toContainText("Selvbetjent vask");
|
|
await expect(settingsRoot.getByTestId("action-settings-wheel-attachment-panel")).toContainText("#424242");
|
|
await expect(settingsRoot.getByTestId("action-settings-wheel-attachment-panel")).toContainText("Driver One");
|
|
|
|
await triggerMenuHover(settingsRoot.getByTestId("action-settings-wheel-section-order"));
|
|
await settingsRoot.getByRole("button", { name: /Godkend selvbetjent vask/ }).click();
|
|
await expect(page.locator(".swal2-popup")).toBeVisible();
|
|
await page.locator(".swal2-confirm").click();
|
|
|
|
await expect
|
|
.poll(() => orderPutPayloads)
|
|
.toEqual([
|
|
{ id: 56630, customer_id: 424242 },
|
|
{ id: 56630, invoice_collection_id: 9001 },
|
|
]);
|
|
expect(orderItemsPutPayloads).toHaveLength(1);
|
|
expect(orderItemsPutPayloads[0]).toMatchObject({
|
|
id: 8001,
|
|
price: 99900,
|
|
quantity: 1,
|
|
});
|
|
await expect(settingsRoot).toHaveCount(0);
|
|
});
|
|
|
|
test("hides the draft badge when the selected department only has system drafts", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["admin", "department_access_1", "add_order", "list_orders"],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const hiddenSystemDraft = {
|
|
id: 56627,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 1857,
|
|
cashier_name: "System",
|
|
department_id: 1,
|
|
reg_1: "SYSTEM01",
|
|
reg_2: null,
|
|
reg_3: null,
|
|
reference: "system-draft",
|
|
notes: "",
|
|
po: "",
|
|
total_net_amount: 111700,
|
|
created_at: "2026-04-20 13:20:57",
|
|
invoice_collection_id: null,
|
|
invoice_collection: null,
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: null,
|
|
safety_seal: null,
|
|
};
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 1, name: "Taastrup", visible: true }],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const url = new URL(route.request().url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const isDraftRequest = filters.includes("customer_id:6001");
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: isDraftRequest ? [hiddenSystemDraft] : [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: Number(url.searchParams.get("limit") || "100"),
|
|
total: isDraftRequest ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/admin/1/modules/pos/drafts");
|
|
|
|
await expect(page).toHaveURL(/\/admin\/1\/modules\/pos\/drafts$/);
|
|
await expect(page.getByTestId("department-pos-drafts-page")).toBeVisible();
|
|
await expect(page.getByText("Vis 0 vaske")).toBeVisible();
|
|
await expect(page.getByText("SYSTEM01")).toHaveCount(0);
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-badge")).toHaveCount(0);
|
|
});
|
|
|
|
test("keeps the draft actions menu inside the viewport near the bottom edge", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
await page.setViewportSize({ width: 1280, height: 420 });
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "admin", "department_access_1", "list_orders"],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const currentOrder = {
|
|
id: 56625,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 5,
|
|
cashier_name: "Jeppe",
|
|
department_id: 1,
|
|
reg_1: "EC21233",
|
|
reg_2: "TR12345",
|
|
reg_3: null,
|
|
reference: "reff",
|
|
notes: "",
|
|
po: "po00",
|
|
total_net_amount: 111700,
|
|
created_at: "2026-04-20 13:20:57",
|
|
invoice_collection_id: 7001,
|
|
invoice_collection: {
|
|
id: 7001,
|
|
customer_number: 6001,
|
|
closed_at: null,
|
|
booked_invoice_id: null,
|
|
},
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: null,
|
|
safety_seal: null,
|
|
};
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
const url = new URL(route.request().url());
|
|
if (!url.pathname.endsWith("/departments")) {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [{ id: 1, name: "Demo", visible: true }],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const request = route.request();
|
|
const url = new URL(request.url());
|
|
|
|
if (!url.pathname.endsWith("/orders") || request.method() !== "GET") {
|
|
await route.fallback();
|
|
return;
|
|
}
|
|
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const isDraftRequest = filters.includes("customer_id:6001") && filters.includes("department_id:1");
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: isDraftRequest ? [currentOrder] : [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: Number(url.searchParams.get("limit") || "100"),
|
|
total: isDraftRequest ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/admin/1/modules/pos/drafts");
|
|
|
|
const settingsRoot = page.getByTestId("pos-order-list-settings-56625");
|
|
const settingsTrigger = settingsRoot.locator(".dropdown-trigger > button");
|
|
const menu = settingsRoot.locator(".dropdown-content");
|
|
|
|
await expect(settingsTrigger).toBeVisible();
|
|
await settingsTrigger.click();
|
|
await expect(menu).toBeVisible();
|
|
|
|
const viewport = page.viewportSize();
|
|
const menuBox = await menu.boundingBox();
|
|
|
|
expect(viewport).not.toBeNull();
|
|
expect(menuBox).not.toBeNull();
|
|
expect(menuBox?.y ?? -1).toBeGreaterThanOrEqual(0);
|
|
expect((menuBox?.y ?? 0) + (menuBox?.height ?? 0)).toBeLessThanOrEqual((viewport?.height ?? 0) + 1);
|
|
});
|
|
});
|