Files
pleno-vue/tests/e2e/change-invoice-collection.spec.ts
T

181 lines
6.2 KiB
TypeScript

import { expect, test, type Locator, type Page, type Response } from "@playwright/test";
import { bookingTestData } from "./fixtures";
import { mockApi, primeMockSession } from "./support/network.js";
const changeInvoiceCollectionActionRegex =
/Skift fakturasamling|Change invoice collection|Rechnungssammlung|fakturainnsamling|fakturasamling/i;
const mobileOrderCardSelector = "[data-testid^='pos-order-list-card-']";
async function primePrivilegedSession(page: Page) {
const token = "superuser-change-invoice-collection-token";
await mockApi(page, {
authenticated: true,
permissions: ["superuser", "admin", "user"],
});
await primeMockSession(page, { token });
}
const waitForOrdersListLayout = async (page: Page): Promise<"table" | "mobile" | null> => {
const table = page.locator("table");
const mobileCard = page.locator(mobileOrderCardSelector).first();
if (await table.isVisible().catch(() => false)) {
return "table";
}
if (await mobileCard.isVisible().catch(() => false)) {
return "mobile";
}
return Promise.any([
table.waitFor({ state: "visible", timeout: 15000 }).then(() => "table" as const),
mobileCard.waitFor({ state: "visible", timeout: 15000 }).then(() => "mobile" as const),
]).catch(() => null);
};
const findDesktopChangeInvoiceCollectionAction = async (page: Page): Promise<Locator | null> => {
const actionTriggers = page.locator("tbody tr .dropdown-trigger > button");
const triggerCount = await actionTriggers.count();
for (let index = 0; index < triggerCount; index += 1) {
const trigger = actionTriggers.nth(index);
if (!(await trigger.isVisible().catch(() => false))) {
continue;
}
await trigger.click();
const dropdownRoot = trigger.locator("xpath=ancestor::div[contains(@class,'dropdown')][1]");
const changeInvoiceCollectionAction = dropdownRoot.getByRole("button", {
name: changeInvoiceCollectionActionRegex,
});
if ((await changeInvoiceCollectionAction.count()) > 0) {
const visibleAction = changeInvoiceCollectionAction.first();
if (await visibleAction.isVisible().catch(() => false)) {
return visibleAction;
}
}
await page.keyboard.press("Escape");
}
return null;
};
const findMobileChangeInvoiceCollectionAction = async (page: Page): Promise<Locator | null> => {
const cards = page.locator(mobileOrderCardSelector);
const cardCount = await cards.count();
for (let index = 0; index < cardCount; index += 1) {
const card = cards.nth(index);
if (!(await card.isVisible().catch(() => false))) {
continue;
}
const testId = await card.getAttribute("data-testid");
const orderId = testId?.replace("pos-order-list-card-", "");
if (!orderId) {
continue;
}
const actionTrigger = page.getByTestId(`pos-order-list-actions-${orderId}`);
if (!(await actionTrigger.isVisible().catch(() => false))) {
continue;
}
await actionTrigger.click();
const actionsModal = page.getByTestId("pos-order-actions-modal");
await expect(actionsModal).toBeVisible();
const changeInvoiceCollectionAction = actionsModal.getByRole("button", {
name: changeInvoiceCollectionActionRegex,
});
if ((await changeInvoiceCollectionAction.count()) > 0) {
const visibleAction = changeInvoiceCollectionAction.first();
if (await visibleAction.isVisible().catch(() => false)) {
return visibleAction;
}
}
await actionsModal.locator("button.delete").click();
await expect(actionsModal).toBeHidden();
}
return null;
};
const findChangeInvoiceCollectionAction = async (page: Page, layout: "table" | "mobile") =>
layout === "mobile" ? findMobileChangeInvoiceCollectionAction(page) : findDesktopChangeInvoiceCollectionAction(page);
test.describe("POS order actions", () => {
test("change invoice collection opens picker and stays on the same page", async ({ page }) => {
await primePrivilegedSession(page);
const departmentId = bookingTestData.departmentId.toString();
const ordersResponsePromise = page
.waitForResponse(
(response: Response) =>
response.request().method() === "GET" &&
response.url().includes("/orders?") &&
response.url().includes("department_id:"),
{ timeout: 30000 }
)
.catch(() => null);
await page.goto(`/admin/${departmentId}/modules/pos/orders`);
await expect(page).toHaveURL(new RegExp(`/admin/${departmentId}/modules/pos/orders`));
const ordersResponse = await ordersResponsePromise;
test.skip(!ordersResponse, "Orders list request did not complete in time for this environment.");
const listLayout = await waitForOrdersListLayout(page);
test.skip(!listLayout, "Orders list did not render in either table or mobile-card layout.");
await page.waitForTimeout(500);
const changeInvoiceCollectionAction = await findChangeInvoiceCollectionAction(page, listLayout);
test.skip(
!changeInvoiceCollectionAction,
"No order action menu with 'Skift fakturasamling' is available for current test data/permissions."
);
if (!changeInvoiceCollectionAction) {
return;
}
await expect(changeInvoiceCollectionAction).toBeVisible();
const beforeUrl = page.url();
const newTabPromise = page.waitForEvent("popup", { timeout: 2000 }).catch(() => null);
await changeInvoiceCollectionAction.click();
const popup = await newTabPromise;
expect(popup).toBeNull();
await expect(page).toHaveURL(beforeUrl);
const pickerModal = page.locator(".swal2-container .modal-card");
await expect(
pickerModal,
"Expected invoice collection picker modal to open after clicking the action."
).toBeVisible();
const selectCheckboxes = pickerModal.locator('[data-testid^="collected-invoice-selector-"] input[type="checkbox"]');
const selectableCount = await selectCheckboxes.count();
test.skip(selectableCount === 0, "No invoice collections available for selection in test data.");
await selectCheckboxes.first().check();
await expect(page).toHaveURL(beforeUrl);
await expect(page.locator(".swal2-container, .swal2-popup")).toContainText(
/Faktura samling|fakturasamling|invoice collection/i
);
});
});