- 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.
152 lines
6.4 KiB
JavaScript
152 lines
6.4 KiB
JavaScript
import { expect, test } from "@playwright/test";
|
|
import { mockApi, seedAuthenticatedState } from "./support/network.js";
|
|
|
|
async function suppressVueDevtoolsOverlay(page) {
|
|
await page.addInitScript(() => {
|
|
const STYLE_ID = "__e2e-hide-vue-devtools";
|
|
|
|
const apply = () => {
|
|
if (!document.getElementById(STYLE_ID)) {
|
|
const style = document.createElement("style");
|
|
style.id = STYLE_ID;
|
|
style.textContent =
|
|
"#__vue-devtools-container__, .vue-devtools__anchor-btn, .vue-devtools__panel-content { display: none !important; visibility: hidden !important; pointer-events: none !important; }";
|
|
(document.head || document.documentElement).appendChild(style);
|
|
}
|
|
|
|
const container = document.getElementById("__vue-devtools-container__");
|
|
if (container) {
|
|
container.style.display = "none";
|
|
container.style.pointerEvents = "none";
|
|
}
|
|
};
|
|
|
|
apply();
|
|
const observer = new MutationObserver(apply);
|
|
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
});
|
|
}
|
|
|
|
async function primeSuperuserSession(page) {
|
|
const token = "superuser-e2e-token";
|
|
await seedAuthenticatedState(page, token);
|
|
await page.goto("/login");
|
|
await page.evaluate(async (sessionToken) => {
|
|
const sessionModule = await import("/src/components/session/token/SessionUser.vue");
|
|
window.localStorage.setItem("token", sessionToken);
|
|
sessionModule.SessionUser.token.value = sessionToken;
|
|
sessionModule.SessionUser.authenticated.value = true;
|
|
sessionModule.SessionUser.permissions.value = ["superuser", "user"];
|
|
sessionModule.SessionUser.initiated.value = true;
|
|
}, token);
|
|
}
|
|
|
|
test.describe("Invoice distribution smoke", () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await suppressVueDevtoolsOverlay(page);
|
|
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "user"],
|
|
invoiceDistribution: true,
|
|
});
|
|
await primeSuperuserSession(page);
|
|
});
|
|
|
|
test("@smoke overview loads and quick-open month action works", async ({ page }) => {
|
|
await page.goto("/superuser/invoices?activeTab=distribution");
|
|
|
|
await expect(page.getByTestId("distribution-overview-page")).toBeVisible();
|
|
await expect(page.locator('[data-testid="distribution-overview-page"] h2').first()).toBeVisible();
|
|
const openMonthButton = page.getByTestId("distribution-overview-open-month").first();
|
|
await expect(openMonthButton).toBeVisible({ timeout: 15_000 });
|
|
|
|
const popupPromise = page.waitForEvent("popup", { timeout: 3000 }).catch(() => null);
|
|
await openMonthButton.click();
|
|
const popup = await popupPromise;
|
|
|
|
if (popup) {
|
|
await expect(popup).toHaveURL(/\/superuser\/invoices\/distribution\/\d+\/\d+/);
|
|
return;
|
|
}
|
|
|
|
await expect(page).toHaveURL(/\/superuser\/invoices\/distribution\/\d+\/\d+/);
|
|
});
|
|
|
|
test("@smoke monthly tabs keep URL query-state in sync", async ({ page }) => {
|
|
await page.goto(
|
|
"/superuser/invoices/distribution/2026/3/customers?customerSearch=acme&customerSource=fixed_pricing&customerDepartment=Copenhagen&compareMode=line_by_line"
|
|
);
|
|
|
|
await expect(page.getByTestId("distribution-month-tabs")).toBeVisible();
|
|
await expect(page).toHaveURL(/customerSearch=acme/);
|
|
await expect(page).toHaveURL(/customerSource=fixed_pricing/);
|
|
|
|
await page.getByRole("tab", { name: /Departments|Afdelinger/i }).click();
|
|
await page.getByTestId("distribution-department-search").fill("Odense");
|
|
await expect(page).toHaveURL(/departmentSearch=Odense/);
|
|
|
|
await page.getByRole("tab", { name: /Customers|Kunder/i }).click();
|
|
await page.getByTestId("distribution-customer-search").fill("Nordic");
|
|
await expect(page).toHaveURL(/customerSearch=Nordic/);
|
|
|
|
await page.getByRole("tab", { name: /Compare|Sammenlign/i }).click();
|
|
await expect(page).toHaveURL(/\/compare/);
|
|
await expect(page).toHaveURL(/compareMode=line_by_line/);
|
|
});
|
|
|
|
test("@smoke compare flow shows progress and mismatch-first results", async ({ page }) => {
|
|
await page.goto("/superuser/invoices/distribution/2026/3/compare?compareMode=line_by_line");
|
|
|
|
await page.getByTestId("distribution-compare-submit").click();
|
|
const compareTable = page.getByTestId("distribution-compare-table");
|
|
const progress = page.locator(".compare-progress");
|
|
|
|
await Promise.race([
|
|
progress.waitFor({ state: "visible", timeout: 6_000 }).catch(() => null),
|
|
compareTable.waitFor({ state: "visible", timeout: 10_000 }),
|
|
]);
|
|
|
|
await expect(compareTable).toBeVisible();
|
|
await expect(compareTable.getByText("#101")).toBeVisible();
|
|
await expect(compareTable.getByText("#102")).toBeVisible();
|
|
|
|
const firstDataRow = compareTable.locator("tbody tr").first();
|
|
await expect(firstDataRow).toContainText("#101");
|
|
});
|
|
|
|
test("@smoke mobile layout sanity keeps primary controls visible", async ({ page }) => {
|
|
await page.goto("/superuser/invoices/distribution/2026/3/overview");
|
|
|
|
await expect(page.getByTestId("distribution-month-toolbar")).toBeVisible();
|
|
await expect(page.getByTestId("distribution-month-prev")).toBeVisible();
|
|
await expect(page.getByTestId("distribution-month-next")).toBeVisible();
|
|
await expect(page.locator(".summary-ribbon:visible").first()).toBeVisible();
|
|
await page.getByRole("tab", { name: /Departments|Afdelinger/i }).click();
|
|
await expect(page.locator(".table-container--scroll:visible").first()).toBeVisible();
|
|
});
|
|
|
|
test("@smoke fallback mode keeps results and surfaces warning banners", async ({ page }) => {
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "user"],
|
|
invoiceDistribution: true,
|
|
invoiceDistributionForceLegacyFallback: true,
|
|
invoiceDistributionForceCompareFallback: true,
|
|
});
|
|
await primeSuperuserSession(page);
|
|
|
|
await page.goto("/superuser/invoices?activeTab=distribution");
|
|
await expect(page.locator(".message.is-warning").filter({ hasText: /v2/i }).first()).toBeVisible({
|
|
timeout: 15_000,
|
|
});
|
|
|
|
await page.goto("/superuser/invoices/distribution/2026/3/compare?compareMode=line_by_line");
|
|
await expect(page.locator(".message.is-warning").filter({ hasText: /v2/i }).first()).toBeVisible();
|
|
|
|
await page.getByTestId("distribution-compare-submit").click();
|
|
await expect(page.getByTestId("distribution-compare-table")).toBeVisible();
|
|
await expect(page.locator(".message.is-warning").filter({ hasText: /v2/i }).first()).toBeVisible();
|
|
});
|
|
});
|