- Introduced `.prettierrc.json` to enforce consistent code formatting across the project. - Updated unit and e2e test files to address formatting issues, improve readability, and ensure alignment with the new Prettier configuration.
890 lines
41 KiB
TypeScript
890 lines
41 KiB
TypeScript
import { test, expect, Page } from "@playwright/test";
|
|
import { createPosFixture, mockApi, seedAuthenticatedState } from "./support/network.js";
|
|
|
|
const POS_PERMISSIONS = [
|
|
"admin",
|
|
"department_access_12",
|
|
"delete_order",
|
|
"edit_order_items",
|
|
"get_user",
|
|
"list_customer_notes",
|
|
"list_customer_attributes",
|
|
"get_custom_prices_other",
|
|
];
|
|
|
|
async function primeOperatorSession(page: Page, token = "pos-orders-token", _permissions = POS_PERMISSIONS) {
|
|
await seedAuthenticatedState(page, token);
|
|
const sessionRequest = page.waitForResponse((response) => {
|
|
return response.request().method() === "GET" && response.url().includes("/auth/session");
|
|
});
|
|
await page.goto("/login");
|
|
await sessionRequest;
|
|
}
|
|
|
|
async function createDisposableOrder(page: Page) {
|
|
const uniqueSuffix = Date.now().toString().slice(-6);
|
|
const reg1 = `PW${uniqueSuffix}`;
|
|
const reference = `E2E-${uniqueSuffix}`;
|
|
|
|
await page.goto("/admin/12/modules/pos?step=1");
|
|
await expect(page.getByTestId("pos-step-1")).toBeVisible();
|
|
|
|
await page.locator("#reg_1").fill(reg1);
|
|
await page.locator("#reference").fill(reference);
|
|
await page.locator("#pos_select_customer_input").fill("12345679");
|
|
await expect(page.locator(".customer-drop-down-select").first()).toBeVisible();
|
|
await page.locator(".customer-drop-down-select").first().click();
|
|
await expect(page.locator(".field.has-addons input[disabled]").last()).toHaveValue(
|
|
/\(TEST\) Pleno Vognmandsforretning/
|
|
);
|
|
|
|
await page.getByTestId("pos-step-1").getByTestId("pos-next-step").click();
|
|
await expect(page).toHaveURL(/\/admin\/12\/modules\/pos\?id=\d+&customer_id=12345679&step=2/);
|
|
|
|
const url = new URL(page.url());
|
|
const orderId = Number(url.searchParams.get("id"));
|
|
expect(orderId).toBeGreaterThan(0);
|
|
|
|
return {
|
|
orderId,
|
|
reg1,
|
|
reference,
|
|
};
|
|
}
|
|
|
|
async function clickVisibleTestId(page: Page, testId: string) {
|
|
const locator = page.getByTestId(testId);
|
|
const count = await locator.count();
|
|
|
|
for (let index = 0; index < count; index += 1) {
|
|
const candidate = locator.nth(index);
|
|
if (await candidate.isVisible()) {
|
|
await candidate.click();
|
|
return;
|
|
}
|
|
}
|
|
|
|
throw new Error(`No visible element found for test id "${testId}"`);
|
|
}
|
|
|
|
async function openOrderSettings(page: Page, orderId: number) {
|
|
await page.goto(`/admin/12/modules/pos/orders/${orderId}`);
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await clickVisibleTestId(page, "pos-order-tab-settings");
|
|
await expect(page.getByTestId("pos-order-panel-settings")).toBeVisible();
|
|
}
|
|
|
|
async function reloadOrderSettings(page: Page, orderId: number) {
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await clickVisibleTestId(page, "pos-order-tab-settings");
|
|
await expect(page.getByTestId("pos-order-panel-settings")).toBeVisible();
|
|
}
|
|
|
|
function getCreatedAtInput(page: Page) {
|
|
return page.getByTestId("pos-order-settings-created-at").locator("input").first();
|
|
}
|
|
|
|
async function openOrderDetail(page: Page, orderId = 54518) {
|
|
await page.goto(`/admin/12/modules/pos/orders/${orderId}`);
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
}
|
|
|
|
async function openOrderAttachments(page: Page, orderId = 54518) {
|
|
await openOrderDetail(page, orderId);
|
|
await clickVisibleTestId(page, "pos-order-tab-attachments");
|
|
await expect(page.getByTestId("pos-order-panel-attachments")).toBeVisible();
|
|
}
|
|
|
|
async function openAddAttachmentCard(page: Page) {
|
|
const addAttachmentCard = getVisibleTestId(page, "pos-order-attachments-add-card");
|
|
const attachWashCertificateButton = page.getByTestId("pos-order-attachments-attach-wash-certificate");
|
|
|
|
await expect(addAttachmentCard).toBeVisible();
|
|
if ((await attachWashCertificateButton.count()) === 0) {
|
|
await addAttachmentCard.locator(".card-header").click();
|
|
}
|
|
|
|
await expect(attachWashCertificateButton).toBeVisible();
|
|
}
|
|
|
|
async function openAddItemsPanel(page: Page) {
|
|
const addItemsPanel = page.locator('[data-testid="pos-order-add-items-panel"]:visible').first();
|
|
const addItemsBackButton = page.locator('[data-testid="pos-order-add-items-back"]:visible').first();
|
|
await page.getByTestId("pos-order-add-item").click();
|
|
await expect(addItemsPanel).toBeVisible();
|
|
await expect(addItemsBackButton).toBeVisible();
|
|
}
|
|
|
|
function getVisibleTestId(page: Page, testId: string) {
|
|
return page.locator(`[data-testid="${testId}"]:visible`).first();
|
|
}
|
|
|
|
async function expectOrderTotal(page: Page, total: number) {
|
|
await expect(page.getByTestId("pos-order-total").first()).toHaveText(`${total} DKK`);
|
|
}
|
|
|
|
async function openOrderItemEditModal(page: Page, orderItemId: number) {
|
|
await page.getByTestId(`pos-order-item-edit-${orderItemId}`).click();
|
|
await expect(page.getByTestId("pos-order-item-edit-modal")).toBeVisible();
|
|
}
|
|
|
|
async function waitForOrderItemMutation(page: Page, method: "POST" | "PUT" | "DELETE", match: RegExp | string) {
|
|
return page.waitForRequest((request) => {
|
|
if (request.method() !== method || !request.url().includes("/order/items")) {
|
|
return false;
|
|
}
|
|
|
|
return typeof match === "string" ? request.url().includes(match) : match.test(request.url());
|
|
});
|
|
}
|
|
|
|
test.describe("Admin POS Orders - desktop settings", () => {
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
test.skip(!testInfo.project.name.includes("desktop"), "Desktop-only order settings coverage");
|
|
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: POS_PERMISSIONS,
|
|
edgeGateways: false,
|
|
pos: createPosFixture(),
|
|
});
|
|
await primeOperatorSession(page);
|
|
});
|
|
|
|
test("loads order detail metadata without order_id prop/setup errors on first render", async ({ page }) => {
|
|
const consoleMessages: string[] = [];
|
|
const pageErrors: string[] = [];
|
|
|
|
page.on("console", (message) => {
|
|
if (message.type() === "warning" || message.type() === "error") {
|
|
consoleMessages.push(message.text());
|
|
}
|
|
});
|
|
page.on("pageerror", (error) => {
|
|
pageErrors.push(String(error));
|
|
});
|
|
|
|
await openOrderDetail(page);
|
|
await expect(page.getByTestId("pos-order-registration-1")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-metadata-reference")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-metadata-note")).toBeVisible();
|
|
|
|
const combinedMessages = [...consoleMessages, ...pageErrors].join("\n");
|
|
expect(combinedMessages).not.toContain("Missing required prop: order_id");
|
|
expect(combinedMessages).not.toContain('Invalid prop: type check failed for prop "order_id"');
|
|
expect(combinedMessages).not.toContain("Unhandled error during execution of setup function");
|
|
});
|
|
|
|
test("renders order detail metadata and item actions without the Excel export affordance", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
await expect(page.getByTestId("pos-order-header-export-actions")).toHaveCount(0);
|
|
await expect(page.locator('[data-auto-excel-export-button="1"]')).toHaveCount(0);
|
|
|
|
const inlineDepartment = page.getByTestId("pos-order-inline-department");
|
|
const inlineCreated = page.getByTestId("pos-order-inline-created");
|
|
|
|
await expect(inlineDepartment).toBeVisible();
|
|
await expect(inlineCreated).toBeVisible();
|
|
await expect(inlineDepartment).toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
|
|
await expect(inlineCreated).toHaveCSS("background-color", "rgba(0, 0, 0, 0)");
|
|
await expect(inlineDepartment).toHaveCSS("padding-left", "0px");
|
|
await expect(inlineCreated).toHaveCSS("padding-left", "0px");
|
|
const transactionLabel = page.getByTestId("pos-order-transaction-label");
|
|
await expect(transactionLabel).toBeVisible();
|
|
|
|
const priceHeader = page.getByTestId("pos-order-price-header");
|
|
const actionsHeader = page.getByTestId("pos-order-actions-header");
|
|
await expect(priceHeader).toContainText("Pris (DKK)");
|
|
await expect(actionsHeader).toContainText("Handlinger");
|
|
await expect(actionsHeader).not.toContainText("table.actions");
|
|
|
|
const [transactionFontSize, inlineDepartmentFontSize, inlineCreatedFontSize] = await Promise.all([
|
|
transactionLabel.evaluate((element) => window.getComputedStyle(element).fontSize),
|
|
inlineDepartment.evaluate((element) => window.getComputedStyle(element).fontSize),
|
|
inlineCreated.evaluate((element) => window.getComputedStyle(element).fontSize),
|
|
]);
|
|
expect(inlineDepartmentFontSize).toBe(transactionFontSize);
|
|
expect(inlineCreatedFontSize).toBe(transactionFontSize);
|
|
|
|
const [priceHeaderStyles, actionsHeaderStyles] = await Promise.all([
|
|
priceHeader.evaluate((element) => {
|
|
const target = element.querySelector(".th-wrap") || element;
|
|
const styles = window.getComputedStyle(target);
|
|
return {
|
|
justifyContent: styles.justifyContent,
|
|
textAlign: styles.textAlign,
|
|
};
|
|
}),
|
|
actionsHeader.evaluate((element) => {
|
|
const target = element.querySelector(".th-wrap") || element;
|
|
const styles = window.getComputedStyle(target);
|
|
return {
|
|
justifyContent: styles.justifyContent,
|
|
textAlign: styles.textAlign,
|
|
};
|
|
}),
|
|
]);
|
|
expect(priceHeaderStyles.justifyContent).toBe("flex-end");
|
|
expect(priceHeaderStyles.textAlign).toBe("right");
|
|
expect(actionsHeaderStyles.justifyContent).toBe("flex-end");
|
|
expect(actionsHeaderStyles.textAlign).toBe("right");
|
|
await expect(page.getByTestId("pos-order-item-price-9101")).toHaveCSS("text-align", "right");
|
|
|
|
const licensePlatesSection = page.getByTestId("pos-order-metadata-license-plates");
|
|
const referenceSection = page.getByTestId("pos-order-metadata-reference");
|
|
const noteSection = page.getByTestId("pos-order-metadata-note");
|
|
const metadataSections = [licensePlatesSection, referenceSection, noteSection];
|
|
|
|
for (const section of metadataSections) {
|
|
await expect(section).toBeVisible();
|
|
const box = await section.boundingBox();
|
|
expect(box).not.toBeNull();
|
|
expect(box?.width ?? 0).toBeGreaterThan(120);
|
|
expect(box?.height ?? 0).toBeGreaterThan(70);
|
|
}
|
|
|
|
await expect(licensePlatesSection.locator(".skeleton-lines")).toHaveCount(0);
|
|
const reg1 = page.getByTestId("pos-order-registration-1");
|
|
const reg2Add = page.getByTestId("pos-order-registration-add-2");
|
|
const reg3Add = page.getByTestId("pos-order-registration-add-3");
|
|
await expect(reg1).toBeVisible();
|
|
await expect(reg2Add).toBeVisible();
|
|
await expect(reg3Add).toBeVisible();
|
|
const noteEmptyState = page.getByTestId("pos-order-note-empty-state");
|
|
await expect(noteEmptyState).toBeVisible();
|
|
await expect(noteEmptyState.locator(".pos-order-field__empty-pill")).toHaveText(/^\+\s+\S+/);
|
|
await expect(noteEmptyState).not.toContainText(/Ingen data/i);
|
|
await expect(noteEmptyState.locator(".pos-order-note-editor__empty-copy")).toHaveCount(0);
|
|
|
|
const reg1Box = await reg1.boundingBox();
|
|
const reg2AddBox = await reg2Add.boundingBox();
|
|
const licensePlatesBox = await licensePlatesSection.boundingBox();
|
|
const referenceSectionBox = await referenceSection.boundingBox();
|
|
const noteSectionBox = await noteSection.boundingBox();
|
|
expect(reg1Box).not.toBeNull();
|
|
expect(reg2AddBox).not.toBeNull();
|
|
expect(licensePlatesBox).not.toBeNull();
|
|
expect(referenceSectionBox).not.toBeNull();
|
|
expect(noteSectionBox).not.toBeNull();
|
|
expect(Math.abs((reg1Box?.height ?? 0) - (reg2AddBox?.height ?? 0))).toBeLessThanOrEqual(2);
|
|
expect(Math.abs((licensePlatesBox?.height ?? 0) - (referenceSectionBox?.height ?? 0))).toBeLessThanOrEqual(2);
|
|
expect(referenceSectionBox?.x ?? 0).toBeGreaterThan(licensePlatesBox?.x ?? 0);
|
|
expect(noteSectionBox?.y ?? 0).toBeGreaterThan(referenceSectionBox?.y ?? 0);
|
|
expect(Math.abs((licensePlatesBox?.x ?? 0) - (noteSectionBox?.x ?? 0))).toBeLessThanOrEqual(2);
|
|
expect(noteSectionBox?.width ?? 0).toBeGreaterThan(referenceSectionBox?.width ?? 0);
|
|
|
|
const referenceControlBox = await referenceSection.locator(".pos-order-field__control").boundingBox();
|
|
const noteControlBox = await noteSection.locator(".pos-order-field__control").boundingBox();
|
|
expect(referenceControlBox).not.toBeNull();
|
|
expect(noteControlBox).not.toBeNull();
|
|
expect(referenceControlBox?.height ?? 0).toBeLessThan(65);
|
|
expect(noteControlBox?.height ?? 0).toBeLessThan(100);
|
|
await expect(noteEmptyState).not.toContainText("pos.add_note_placeholder");
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-9101")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-delete-9101")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-add-item")).toBeVisible();
|
|
await expectOrderTotal(page, 1372);
|
|
await page.getByTestId("pos-order-add-item").click();
|
|
await expect(page.getByTestId("pos-order-add-items-panel").first()).toBeVisible();
|
|
await expect(page.getByTestId("pos-product-card-53").first()).toBeVisible();
|
|
});
|
|
|
|
test("keeps a readable split layout in add-items mode and restores the normal shell after backing out", async ({
|
|
page,
|
|
}) => {
|
|
await openOrderDetail(page);
|
|
|
|
const main = getVisibleTestId(page, "pos-order-main");
|
|
const beforeMainBox = await main.boundingBox();
|
|
const beforeRailBox = await getVisibleTestId(page, "pos-order-rail").boundingBox();
|
|
expect(beforeMainBox).not.toBeNull();
|
|
expect(beforeRailBox).not.toBeNull();
|
|
|
|
await openAddItemsPanel(page);
|
|
await expect(page.locator('[data-testid="pos-order-rail"]:visible')).toHaveCount(0);
|
|
|
|
const workspace = getVisibleTestId(page, "pos-order-workspace");
|
|
const productPanel = page.locator('[data-testid="pos-order-add-items-panel"]:visible').first();
|
|
const cartPanel = page.locator('[data-testid="pos-order-panel-cart"]:visible').first();
|
|
const afterMainBox = await main.boundingBox();
|
|
const workspaceBox = await workspace.boundingBox();
|
|
const productPanelBox = await productPanel.boundingBox();
|
|
const cartPanelBox = await cartPanel.boundingBox();
|
|
expect(afterMainBox).not.toBeNull();
|
|
expect(workspaceBox).not.toBeNull();
|
|
expect(productPanelBox).not.toBeNull();
|
|
expect(cartPanelBox).not.toBeNull();
|
|
expect((afterMainBox?.width ?? 0) - (beforeMainBox?.width ?? 0)).toBeGreaterThan(200);
|
|
expect(workspaceBox?.width ?? 0).toBeGreaterThan(800);
|
|
const productPanelWidth = productPanelBox?.width ?? 0;
|
|
const cartPanelWidth = cartPanelBox?.width ?? 0;
|
|
const workspaceWidth = workspaceBox?.width ?? 0;
|
|
expect(productPanelWidth).toBeGreaterThan(470);
|
|
expect(cartPanelWidth).toBeGreaterThan(300);
|
|
expect(cartPanelWidth).toBeLessThan(420);
|
|
expect(productPanelWidth).toBeGreaterThan(cartPanelWidth);
|
|
expect(productPanelWidth / workspaceWidth).toBeGreaterThan(0.55);
|
|
expect(cartPanelWidth / workspaceWidth).toBeLessThan(0.42);
|
|
expect(productPanelBox?.x ?? 0).toBeLessThan(cartPanelBox?.x ?? 0);
|
|
|
|
await expect(getVisibleTestId(page, "pos-order-total")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-item-edit-9101")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-registration-1")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-metadata-reference")).toBeVisible();
|
|
|
|
const categoryTabs = productPanel.locator(".tabs li");
|
|
await expect(categoryTabs).toHaveCount(3);
|
|
await categoryTabs.nth(2).click();
|
|
await expect(productPanel.getByTestId("pos-product-card-64")).toBeVisible();
|
|
await expect(productPanel.getByTestId("pos-product-card-53")).toHaveCount(0);
|
|
|
|
await productPanel.getByTestId("pos-product-card-64").click();
|
|
const addRequest = waitForOrderItemMutation(page, "POST", "/order/items");
|
|
await productPanel.getByTestId("pos-add-to-cart-64").click();
|
|
await addRequest;
|
|
|
|
await expect(getVisibleTestId(page, "pos-order-item-edit-9200")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-item-name-9200")).toContainText("Vaskecertifikat");
|
|
await expectOrderTotal(page, 1397);
|
|
|
|
await page.locator('[data-testid="pos-order-add-items-back"]:visible').first().click();
|
|
await expect(page.locator('[data-testid="pos-order-add-items-panel"]:visible')).toHaveCount(0);
|
|
await expect(getVisibleTestId(page, "pos-order-rail")).toBeVisible();
|
|
|
|
const restoredMainBox = await main.boundingBox();
|
|
const restoredRailBox = await getVisibleTestId(page, "pos-order-rail").boundingBox();
|
|
expect(restoredMainBox).not.toBeNull();
|
|
expect(restoredRailBox).not.toBeNull();
|
|
expect(Math.abs((restoredMainBox?.width ?? 0) - (beforeMainBox?.width ?? 0))).toBeLessThanOrEqual(20);
|
|
expect(Math.abs((beforeRailBox?.width ?? 0) - (restoredRailBox?.width ?? 0))).toBeLessThanOrEqual(20);
|
|
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-item-edit-9200")).toBeVisible();
|
|
await expectOrderTotal(page, 1397);
|
|
});
|
|
|
|
test("loads step 2 customer context after reload and keeps actions below the basket column", async ({ page }) => {
|
|
await page.goto("/admin/12/modules/pos");
|
|
await expect(page.getByTestId("pos-step-1")).toBeVisible();
|
|
await page.locator("#reg_1").fill("EC21235");
|
|
await expect(page.getByTestId("pos-step-1").locator(".pos-card-tabs > .tabs li.is-active")).toContainText("Kunde");
|
|
await page.getByTestId("pos-step-1").getByTestId("pos-next-step").click();
|
|
await expect(page).toHaveURL(/\/admin\/12\/modules\/pos\?id=\d+&customer_id=12345679&step=2/);
|
|
|
|
const stepTwo = page.getByTestId("pos-step-2");
|
|
const cartPanel = stepTwo.getByTestId("pos-order-panel-cart");
|
|
const actions = stepTwo.getByTestId("pos-step-2-actions");
|
|
const customerName = page.locator('[data-testid="pos-order-customer-name"]:visible').first();
|
|
const licensePlatesCard = stepTwo.getByTestId("pos-order-metadata-license-plates");
|
|
const referenceCard = stepTwo.getByTestId("pos-order-metadata-reference");
|
|
|
|
await expect(stepTwo).toBeVisible();
|
|
await expect(customerName).toHaveText(/\(TEST\) Pleno Vognmandsforretning/);
|
|
await expect(actions.getByTestId("pos-next-step")).toBeVisible();
|
|
await expect(licensePlatesCard).toBeVisible();
|
|
await expect(referenceCard).toBeVisible();
|
|
|
|
const cartPanelBox = await cartPanel.boundingBox();
|
|
const actionPanelBox = await actions.boundingBox();
|
|
const licensePlatesCardBox = await licensePlatesCard.boundingBox();
|
|
const referenceCardBox = await referenceCard.boundingBox();
|
|
expect(cartPanelBox).not.toBeNull();
|
|
expect(actionPanelBox).not.toBeNull();
|
|
expect(licensePlatesCardBox).not.toBeNull();
|
|
expect(referenceCardBox).not.toBeNull();
|
|
expect(actionPanelBox?.y ?? 0).toBeGreaterThan((cartPanelBox?.y ?? 0) + (cartPanelBox?.height ?? 0) - 2);
|
|
expect(Math.abs((actionPanelBox?.x ?? 0) - (cartPanelBox?.x ?? 0))).toBeLessThanOrEqual(2);
|
|
expect(Math.abs((actionPanelBox?.width ?? 0) - (cartPanelBox?.width ?? 0))).toBeLessThanOrEqual(2);
|
|
expect(referenceCardBox?.y ?? 0).toBeGreaterThan(
|
|
(licensePlatesCardBox?.y ?? 0) + (licensePlatesCardBox?.height ?? 0) - 2
|
|
);
|
|
expect(Math.abs((referenceCardBox?.x ?? 0) - (licensePlatesCardBox?.x ?? 0))).toBeLessThanOrEqual(2);
|
|
|
|
await page.reload();
|
|
await expect(stepTwo).toBeVisible();
|
|
await expect(customerName).toHaveText(/\(TEST\) Pleno Vognmandsforretning/);
|
|
await expect(stepTwo.getByTestId("pos-next-step")).toBeVisible();
|
|
});
|
|
|
|
test("edits a primary order item in the Buefy modal and persists after reload", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
await expectOrderTotal(page, 1372);
|
|
|
|
await openOrderItemEditModal(page, 9101);
|
|
await page.getByTestId("pos-order-item-edit-price").fill("700");
|
|
await page.getByTestId("pos-order-item-edit-quantity").fill("2");
|
|
await page.getByTestId("pos-order-item-edit-notes").fill("Primary item note");
|
|
await page.getByTestId("pos-order-item-edit-reference").fill("PRIMARY-REF");
|
|
|
|
const editRequest = waitForOrderItemMutation(page, "PUT", "/order/items");
|
|
await page.getByTestId("pos-order-item-edit-save").click();
|
|
await editRequest;
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-modal")).toBeHidden();
|
|
await expect(page.getByTestId("pos-order-item-note-trigger-9101")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-reference-trigger-9101")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-quantity-9101")).toContainText("2");
|
|
await expect(page.getByTestId("pos-order-item-price-9101")).toContainText("1400");
|
|
await expectOrderTotal(page, 2123);
|
|
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-note-trigger-9101")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-reference-trigger-9101")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-price-9101")).toContainText("1400");
|
|
await expectOrderTotal(page, 2123);
|
|
});
|
|
|
|
test("edits a related addon item and preserves grouped rendering after reload", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
|
|
await openOrderItemEditModal(page, 9102);
|
|
await page.getByTestId("pos-order-item-edit-price").fill("450");
|
|
await page.getByTestId("pos-order-item-edit-notes").fill("Addon note");
|
|
|
|
const editRequest = waitForOrderItemMutation(page, "PUT", "/order/items");
|
|
await page.getByTestId("pos-order-item-edit-save").click();
|
|
await editRequest;
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-modal")).toBeHidden();
|
|
await expect(page.getByTestId("pos-order-item-note-trigger-9102")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-price-9102")).toContainText("450");
|
|
await expect(page.getByTestId("pos-order-item-name-9102")).toContainText("Indvendig vask Forvogn");
|
|
await expectOrderTotal(page, 1423);
|
|
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-note-trigger-9102")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-price-9102")).toContainText("450");
|
|
await expectOrderTotal(page, 1423);
|
|
});
|
|
|
|
test("cancels modal edits without mutating the order item", async ({ page }) => {
|
|
const putRequests: string[] = [];
|
|
page.on("request", (request) => {
|
|
if (request.method() === "PUT" && request.url().includes("/order/items")) {
|
|
putRequests.push(request.url());
|
|
}
|
|
});
|
|
|
|
await openOrderDetail(page);
|
|
await openOrderItemEditModal(page, 9104);
|
|
|
|
await page.getByTestId("pos-order-item-edit-price").fill("999");
|
|
await page.getByTestId("pos-order-item-edit-notes").fill("Do not save");
|
|
await page.getByTestId("pos-order-item-edit-cancel").click();
|
|
await expect(page.getByTestId("pos-order-item-edit-modal")).toBeHidden();
|
|
await page.waitForTimeout(200);
|
|
|
|
expect(putRequests).toHaveLength(0);
|
|
await expect(page.getByTestId("pos-order-item-price-9104")).toContainText("299");
|
|
await expect(page.getByTestId("pos-order-item-note-trigger-9104")).toHaveCount(0);
|
|
await expectOrderTotal(page, 1372);
|
|
});
|
|
|
|
test("deletes related and primary items and hides orphaned related rows after reload", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
await expectOrderTotal(page, 1372);
|
|
|
|
const deleteRelatedRequest = waitForOrderItemMutation(page, "DELETE", "id=9104");
|
|
await page.getByTestId("pos-order-item-delete-9104").click();
|
|
await deleteRelatedRequest;
|
|
|
|
await expect(page.getByTestId("pos-order-item-delete-9104")).toHaveCount(0);
|
|
await expectOrderTotal(page, 1073);
|
|
|
|
const deletePrimaryRequest = waitForOrderItemMutation(page, "DELETE", "id=9101");
|
|
await page.getByTestId("pos-order-item-delete-9101").click();
|
|
await deletePrimaryRequest;
|
|
|
|
await expect(page.getByTestId("pos-order-empty-state")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-delete-9102")).toHaveCount(0);
|
|
await expect(page.getByTestId("pos-order-item-delete-9103")).toHaveCount(0);
|
|
await expectOrderTotal(page, 0);
|
|
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-empty-state")).toBeVisible();
|
|
await expectOrderTotal(page, 0);
|
|
});
|
|
|
|
test("adds a new product from the side panel and persists the created order item", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
await expectOrderTotal(page, 1372);
|
|
|
|
await page.getByTestId("pos-order-add-item").click();
|
|
await expect(page.getByTestId("pos-order-add-items-panel").first()).toBeVisible();
|
|
await page.getByTestId("pos-product-card-53").first().click();
|
|
await expect(page.getByTestId("pos-add-to-cart-53")).toBeVisible();
|
|
|
|
const addRequest = waitForOrderItemMutation(page, "POST", "/order/items");
|
|
await page.getByTestId("pos-add-to-cart-53").click();
|
|
await addRequest;
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-9200").first()).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-name-9200").first()).toContainText("Forvogn");
|
|
await expectOrderTotal(page, 2021);
|
|
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-item-edit-9200").first()).toBeVisible();
|
|
await expectOrderTotal(page, 2021);
|
|
});
|
|
|
|
test("attaches a wash certificate from the attachments tab and keeps duplicate attempts idempotent", async ({
|
|
page,
|
|
}) => {
|
|
await openOrderAttachments(page);
|
|
await openAddAttachmentCard(page);
|
|
|
|
const attachmentCards = page.locator(".card-header-title").filter({ hasText: /Attachment #|Vedhæftning #/i });
|
|
const attachWashCertificateButton = page.getByTestId("pos-order-attachments-attach-wash-certificate");
|
|
const uploadAction = page.getByTestId("pos-order-attachments-upload-action");
|
|
|
|
await expect(attachmentCards).toHaveCount(1);
|
|
await expect(attachWashCertificateButton).toBeVisible();
|
|
await expect(uploadAction).toHaveText("Upload");
|
|
|
|
const firstRequestPromise = page.waitForRequest((request) => {
|
|
if (request.method() !== "POST" || !request.url().includes("/order/wash-certificate")) {
|
|
return false;
|
|
}
|
|
|
|
const body = request.postDataJSON?.();
|
|
return Number(body?.id) === 54518;
|
|
});
|
|
|
|
await attachWashCertificateButton.click();
|
|
await expect(page.locator(".swal2-popup")).toBeVisible();
|
|
await page.locator(".swal2-input").fill("12345");
|
|
await page.locator(".swal2-confirm").click();
|
|
|
|
const firstRequest = await firstRequestPromise;
|
|
expect(firstRequest.postDataJSON()).toMatchObject({
|
|
id: 54518,
|
|
safety_seal: "12345",
|
|
});
|
|
|
|
await expect(page.getByText(/(Attachment|Vedhæftning) #400/i)).toBeVisible();
|
|
await expect(attachmentCards).toHaveCount(2);
|
|
await expect(page.locator(".swal2-popup")).toContainText(/generated and attached|genereret og vedhæftet/i);
|
|
await expect(page.locator(".swal2-popup")).toBeHidden({ timeout: 3000 });
|
|
await getVisibleTestId(page, "pos-order-attachment-card-400").locator(".card-header").click();
|
|
await expect(page.getByTestId("pos-order-attachment-download-400")).toHaveText("Download");
|
|
|
|
const secondRequestPromise = page.waitForRequest((request) => {
|
|
if (request.method() !== "POST" || !request.url().includes("/order/wash-certificate")) {
|
|
return false;
|
|
}
|
|
|
|
const body = request.postDataJSON?.();
|
|
return Number(body?.id) === 54518;
|
|
});
|
|
|
|
await attachWashCertificateButton.click();
|
|
await expect(page.locator(".swal2-popup")).toBeVisible();
|
|
await page.locator(".swal2-input").fill("99999");
|
|
await page.locator(".swal2-confirm").click();
|
|
|
|
const secondRequest = await secondRequestPromise;
|
|
expect(secondRequest.postDataJSON()).toMatchObject({
|
|
id: 54518,
|
|
safety_seal: "99999",
|
|
});
|
|
|
|
await expect(page.locator(".swal2-popup")).toContainText(/already attached|allerede vedhæftet/i);
|
|
await expect(attachmentCards).toHaveCount(2);
|
|
await expect(page.locator(".swal2-popup")).toBeHidden({ timeout: 3000 });
|
|
});
|
|
|
|
test("renders the settings surface and keeps destructive actions available", async ({ page }) => {
|
|
const { orderId } = await createDisposableOrder(page);
|
|
await openOrderSettings(page, orderId);
|
|
|
|
await expect(page.getByTestId("pos-order-settings-department")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-created-at")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-include-in-invoice")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-include-helper")).not.toHaveText(/^\s*$/);
|
|
await expect(page.getByTestId("pos-order-settings-reset")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-delete")).toBeVisible();
|
|
});
|
|
|
|
test("persists department changes and shows department names in read-only details", async ({ page }) => {
|
|
const { orderId } = await createDisposableOrder(page);
|
|
await openOrderSettings(page, orderId);
|
|
|
|
await page.getByTestId("pos-order-settings-department").selectOption("1");
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeEnabled();
|
|
await page.getByTestId("pos-order-settings-save").click();
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeDisabled();
|
|
|
|
await reloadOrderSettings(page, orderId);
|
|
await expect(page.getByTestId("pos-order-settings-department")).toHaveValue("1");
|
|
|
|
await clickVisibleTestId(page, "pos-order-tab-details");
|
|
const detailInputs = page.getByTestId("pos-order-panel-details").locator("input");
|
|
await expect(detailInputs.first()).toHaveValue("Taastrup");
|
|
});
|
|
|
|
test("persists created_at updates and shows the Buefy datetime display after reload", async ({ page }) => {
|
|
const { orderId } = await createDisposableOrder(page);
|
|
const updatedCreatedAt = "09/04/2026 13.37";
|
|
|
|
await openOrderSettings(page, orderId);
|
|
await getCreatedAtInput(page).fill(updatedCreatedAt);
|
|
await getCreatedAtInput(page).press("Tab");
|
|
await page.getByTestId("pos-order-settings-save").click();
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeDisabled();
|
|
|
|
await reloadOrderSettings(page, orderId);
|
|
await expect(getCreatedAtInput(page)).toHaveValue(updatedCreatedAt);
|
|
|
|
await clickVisibleTestId(page, "pos-order-tab-details");
|
|
const detailInputs = page.getByTestId("pos-order-panel-details").locator("input");
|
|
await expect(detailInputs.nth(1)).toHaveValue("2026-04-09 13:37:00");
|
|
});
|
|
|
|
test("supports invoice inclusion override across inherited, excluded, and included states", async ({ page }) => {
|
|
const { orderId } = await createDisposableOrder(page);
|
|
|
|
await openOrderSettings(page, orderId);
|
|
const helper = page.getByTestId("pos-order-settings-include-helper");
|
|
const initialHelper = ((await helper.textContent()) || "").trim();
|
|
expect(initialHelper).not.toBe("");
|
|
await expect(page.getByTestId("pos-order-settings-include-in-invoice")).toHaveValue("use_department");
|
|
|
|
await page.getByTestId("pos-order-settings-include-in-invoice").selectOption("exclude");
|
|
await page.getByTestId("pos-order-settings-save").click();
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeDisabled();
|
|
|
|
await reloadOrderSettings(page, orderId);
|
|
await expect(page.getByTestId("pos-order-settings-include-in-invoice")).toHaveValue("exclude");
|
|
const excludedHelper = ((await helper.textContent()) || "").trim();
|
|
expect(excludedHelper).not.toBe("");
|
|
expect(excludedHelper).not.toBe(initialHelper);
|
|
|
|
await page.getByTestId("pos-order-settings-include-in-invoice").selectOption("include");
|
|
await page.getByTestId("pos-order-settings-save").click();
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeDisabled();
|
|
|
|
await reloadOrderSettings(page, orderId);
|
|
await expect(page.getByTestId("pos-order-settings-include-in-invoice")).toHaveValue("include");
|
|
const includedHelper = ((await helper.textContent()) || "").trim();
|
|
expect(includedHelper).not.toBe("");
|
|
expect(includedHelper).not.toBe(excludedHelper);
|
|
|
|
await page.getByTestId("pos-order-settings-department").selectOption("1");
|
|
await page.getByTestId("pos-order-settings-include-in-invoice").selectOption("use_department");
|
|
await page.getByTestId("pos-order-settings-save").click();
|
|
await expect(page.getByTestId("pos-order-settings-save")).toBeDisabled();
|
|
|
|
await reloadOrderSettings(page, orderId);
|
|
await expect(page.getByTestId("pos-order-settings-department")).toHaveValue("1");
|
|
await expect(page.getByTestId("pos-order-settings-include-in-invoice")).toHaveValue("use_department");
|
|
const inheritedExcludedHelper = ((await helper.textContent()) || "").trim();
|
|
expect(inheritedExcludedHelper).not.toBe("");
|
|
expect(inheritedExcludedHelper).not.toBe(includedHelper);
|
|
});
|
|
});
|
|
|
|
test.describe("Admin POS Orders - desktop locked states", () => {
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
test.skip(!testInfo.project.name.includes("desktop"), "Desktop-only order lock coverage");
|
|
});
|
|
|
|
test("hides item mutation controls when edit permission is missing", async ({ page }) => {
|
|
const limitedPermissions = POS_PERMISSIONS.filter((permission) => permission !== "edit_order_items");
|
|
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: limitedPermissions,
|
|
edgeGateways: false,
|
|
pos: createPosFixture(),
|
|
});
|
|
await primeOperatorSession(page, "pos-orders-no-edit-token", limitedPermissions);
|
|
await openOrderDetail(page);
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-9101")).toHaveCount(0);
|
|
await expect(page.getByTestId("pos-order-item-delete-9101")).toHaveCount(0);
|
|
await expect(page.getByTestId("pos-order-add-item")).toHaveCount(0);
|
|
await expectOrderTotal(page, 1372);
|
|
});
|
|
|
|
test("hides item mutation controls when the order is already invoiced", async ({ page }) => {
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: POS_PERMISSIONS,
|
|
edgeGateways: false,
|
|
pos: createPosFixture({
|
|
economicModuleOrdersByOrderId: {
|
|
54518: {
|
|
invoice_id: 99101,
|
|
invoice_draft_id: null,
|
|
},
|
|
},
|
|
}),
|
|
});
|
|
await primeOperatorSession(page, "pos-orders-invoiced-token");
|
|
await openOrderDetail(page);
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-9101")).toHaveCount(0);
|
|
await expect(page.getByTestId("pos-order-item-delete-9101")).toHaveCount(0);
|
|
await expect(page.getByTestId("pos-order-add-item")).toHaveCount(0);
|
|
await expectOrderTotal(page, 1372);
|
|
});
|
|
});
|
|
|
|
test.describe("Admin POS Orders - mobile smoke", () => {
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
test.skip(!testInfo.project.name.toLowerCase().includes("mobile"), "Mobile-only order settings smoke");
|
|
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: POS_PERMISSIONS,
|
|
edgeGateways: false,
|
|
pos: createPosFixture(),
|
|
});
|
|
await primeOperatorSession(page, "pos-orders-mobile-token");
|
|
});
|
|
|
|
test("opens the settings tab and renders the new controls", async ({ page }) => {
|
|
await page.goto("/admin/12/modules/pos/orders/54518");
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
|
|
await clickVisibleTestId(page, "pos-order-tab-settings");
|
|
await expect(page.getByTestId("pos-order-panel-settings")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-department")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-created-at")).toBeVisible();
|
|
await expect(page.getByTestId("pos-order-settings-include-in-invoice")).toBeVisible();
|
|
});
|
|
|
|
test("shows the wash certificate action in the attachments tab", async ({ page }) => {
|
|
await openOrderAttachments(page);
|
|
await openAddAttachmentCard(page);
|
|
});
|
|
|
|
test("keeps horizontal gutters around the mobile order tabs", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
|
|
const noteEmptyState = page.getByTestId("pos-order-note-empty-state");
|
|
await expect(noteEmptyState).toBeVisible();
|
|
await expect(noteEmptyState.locator(".pos-order-field__empty-pill")).toHaveText(/^\+\s+\S+/);
|
|
|
|
const tabsContainer = getVisibleTestId(page, "pos-order-mobile-tabs");
|
|
const cartTab = getVisibleTestId(page, "pos-order-tab-cart");
|
|
const containerBox = await tabsContainer.boundingBox();
|
|
const cartTabBox = await cartTab.boundingBox();
|
|
|
|
expect(containerBox).not.toBeNull();
|
|
expect(cartTabBox).not.toBeNull();
|
|
expect(cartTabBox!.x - containerBox!.x).toBeGreaterThanOrEqual(10);
|
|
expect(containerBox!.x + containerBox!.width - (cartTabBox!.x + cartTabBox!.width)).toBeGreaterThanOrEqual(10);
|
|
});
|
|
|
|
test("supports mobile item edit, add-panel access, and delete control visibility", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
await expectOrderTotal(page, 1372);
|
|
|
|
await openOrderItemEditModal(page, 9101);
|
|
await page.getByTestId("pos-order-item-edit-quantity").fill("2");
|
|
|
|
const editRequest = waitForOrderItemMutation(page, "PUT", "/order/items");
|
|
await page.getByTestId("pos-order-item-edit-save").click();
|
|
await editRequest;
|
|
|
|
await expect(page.getByTestId("pos-order-item-edit-modal")).toBeHidden();
|
|
await expectOrderTotal(page, 2021);
|
|
|
|
await page.getByTestId("pos-order-add-item").click();
|
|
await expect(page.getByTestId("pos-order-add-items-panel").first()).toBeVisible();
|
|
await page.getByTestId("pos-order-item-delete-9101").first().scrollIntoViewIfNeeded();
|
|
await expect(page.getByTestId("pos-order-item-delete-9101").first()).toBeVisible();
|
|
});
|
|
|
|
test("keeps the mobile search and reload controls inline and shows a clear card boundary", async ({ page }) => {
|
|
await page.goto("/admin/12/modules/pos/orders");
|
|
|
|
const searchInput = page.getByTestId("pagination-search-input");
|
|
const reloadActions = page.getByTestId("pagination-reload-actions");
|
|
const orderCard = page.getByTestId("pos-order-list-card-54518");
|
|
|
|
await expect(searchInput).toBeVisible();
|
|
await expect(reloadActions).toBeVisible();
|
|
await expect(orderCard).toBeVisible();
|
|
|
|
const searchBox = await searchInput.boundingBox();
|
|
const reloadBox = await reloadActions.boundingBox();
|
|
|
|
expect(searchBox).not.toBeNull();
|
|
expect(reloadBox).not.toBeNull();
|
|
const searchCenterY = (searchBox?.y ?? 0) + (searchBox?.height ?? 0) / 2;
|
|
const reloadCenterY = (reloadBox?.y ?? 0) + (reloadBox?.height ?? 0) / 2;
|
|
expect(Math.abs(searchCenterY - reloadCenterY)).toBeLessThanOrEqual(4);
|
|
expect(searchBox?.x ?? 0).toBeLessThan(reloadBox?.x ?? 0);
|
|
expect((searchBox?.x ?? 0) + (searchBox?.width ?? 0) - (reloadBox?.x ?? 0)).toBeLessThanOrEqual(4);
|
|
expect(searchBox?.width ?? 0).toBeGreaterThan(reloadBox?.width ?? 0);
|
|
|
|
await expect(orderCard).toHaveCSS("border-top-width", "1px");
|
|
await expect(orderCard).toHaveCSS("border-right-width", "1px");
|
|
await expect(orderCard).toHaveCSS("border-bottom-width", "1px");
|
|
await expect(orderCard).toHaveCSS("border-left-width", "1px");
|
|
});
|
|
|
|
test("stacks the add-items workspace on mobile and still lets the user add products", async ({ page }) => {
|
|
await openOrderDetail(page);
|
|
|
|
const main = getVisibleTestId(page, "pos-order-main");
|
|
const beforeMainBox = await main.boundingBox();
|
|
const beforeRailBox = await getVisibleTestId(page, "pos-order-rail").boundingBox();
|
|
expect(beforeMainBox).not.toBeNull();
|
|
expect(beforeRailBox).not.toBeNull();
|
|
|
|
await openAddItemsPanel(page);
|
|
await expect(page.locator('[data-testid="pos-order-rail"]:visible')).toHaveCount(0);
|
|
|
|
const productPanel = page.locator('[data-testid="pos-order-add-items-panel"]:visible').first();
|
|
const cartPanel = page.locator('[data-testid="pos-order-panel-cart"]:visible').first();
|
|
const workspace = getVisibleTestId(page, "pos-order-workspace");
|
|
const productPanelBox = await productPanel.boundingBox();
|
|
const cartPanelBox = await cartPanel.boundingBox();
|
|
const workspaceBox = await workspace.boundingBox();
|
|
expect(productPanelBox).not.toBeNull();
|
|
expect(cartPanelBox).not.toBeNull();
|
|
expect(workspaceBox).not.toBeNull();
|
|
expect(workspaceBox?.width ?? 0).toBeGreaterThan(300);
|
|
expect(Math.abs((productPanelBox?.x ?? 0) - (cartPanelBox?.x ?? 0))).toBeLessThanOrEqual(12);
|
|
expect(Math.abs((productPanelBox?.width ?? 0) - (cartPanelBox?.width ?? 0))).toBeLessThanOrEqual(24);
|
|
expect(cartPanelBox?.y ?? 0).toBeGreaterThan((productPanelBox?.y ?? 0) + 100);
|
|
|
|
await productPanel.locator("select").first().selectOption("8");
|
|
await expect(productPanel.getByTestId("pos-product-card-64")).toBeVisible();
|
|
await expect(productPanel.getByTestId("pos-product-card-53")).toHaveCount(0);
|
|
|
|
await productPanel.getByTestId("pos-product-card-64").click();
|
|
const addRequest = waitForOrderItemMutation(page, "POST", "/order/items");
|
|
await productPanel.getByTestId("pos-add-to-cart-64").click();
|
|
await addRequest;
|
|
|
|
await expect(getVisibleTestId(page, "pos-order-item-edit-9200")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-item-name-9200")).toContainText("Vaskecertifikat");
|
|
await expectOrderTotal(page, 1397);
|
|
|
|
await page.locator('[data-testid="pos-order-add-items-back"]:visible').first().click();
|
|
await expect(page.locator('[data-testid="pos-order-add-items-panel"]:visible')).toHaveCount(0);
|
|
await expect(getVisibleTestId(page, "pos-order-rail")).toBeVisible();
|
|
|
|
const restoredMainBox = await main.boundingBox();
|
|
expect(restoredMainBox).not.toBeNull();
|
|
expect(Math.abs((restoredMainBox?.width ?? 0) - (beforeMainBox?.width ?? 0))).toBeLessThanOrEqual(20);
|
|
|
|
await page.reload();
|
|
await expect(page.getByTestId("pos-order-detail")).toBeVisible();
|
|
await expect(getVisibleTestId(page, "pos-order-item-edit-9200")).toBeVisible();
|
|
await expectOrderTotal(page, 1397);
|
|
});
|
|
});
|