pelagia-portal/App/tests/e2e/mobile/accounts-payments.spec.ts
2026-05-18 23:18:58 +05:30

141 lines
4.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* User stories covered: Feature 18 — Mobile Accounts payment actions
* - ACCOUNTS at 375×812 can load /payments without Desktop Required overlay
* - MGR_APPROVED PO shows "Start Payment Processing" button
* - SENT_FOR_PAYMENT PO shows payment reference input and "Confirm Payment Sent" button
*
* Created: 2026-05-17
*/
import { test, expect, type BrowserContext } from "@playwright/test";
import { login, USERS, submitPo } from "../helpers/login";
const MOBILE_VIEWPORT = { width: 375, height: 812 };
async function createApprovedPo(
page: import("@playwright/test").Page,
context: BrowserContext,
title: string
): Promise<string> {
await login(page, USERS.TECH);
const poUrl = await submitPo(page, title);
await context.clearCookies();
await login(page, USERS.MANAGER);
await page.goto(poUrl);
await page.getByRole("button", { name: /^approve$/i }).click();
await expect(page.getByText(/approved/i)).toBeVisible({ timeout: 10_000 });
return poUrl;
}
test.describe("Feature 18 — Mobile Accounts payment actions", () => {
test("US-18a: ACCOUNTS at mobile viewport — /payments loads with NO Desktop Required overlay", async ({
page,
}) => {
await page.setViewportSize(MOBILE_VIEWPORT);
await login(page, USERS.ACCOUNTS);
await page.goto("/payments");
// Should NOT see the Desktop Required overlay (ACCOUNTS is a mobile-enabled role)
await expect(page.getByText("Desktop Required")).not.toBeVisible();
await expect(
page.getByRole("heading", { name: /payment queue/i })
).toBeVisible();
console.log(
"✓ ACCOUNTS at mobile sees Payment Queue (no Desktop Required overlay)"
);
});
test("US-18a: ACCOUNTS at mobile — /payments page shows payment queue content", async ({
page,
}) => {
await page.setViewportSize(MOBILE_VIEWPORT);
await login(page, USERS.ACCOUNTS);
await page.goto("/payments");
await page.waitForLoadState("networkidle");
// The page shows either a list of PO cards or an empty-state message
const hasQueue =
(await page.locator("[class*='space-y']").count()) > 0 ||
(await page.getByText(/no orders in the payment queue/i).isVisible());
expect(hasQueue).toBeTruthy();
console.log("✓ Payment queue content rendered at mobile viewport");
});
test("US-18b: MGR_APPROVED PO shows Start Payment Processing button at mobile", async ({
page,
context,
}: {
page: import("@playwright/test").Page;
context: BrowserContext;
}) => {
const poUrl = await createApprovedPo(
page,
context,
`E2E_MOBILE_PAY_${Date.now()}`
);
await context.clearCookies();
await page.setViewportSize(MOBILE_VIEWPORT);
await login(page, USERS.ACCOUNTS);
await page.goto(poUrl);
await page.waitForLoadState("networkidle");
const processBtn = page.getByRole("button", {
name: /process payment|start payment/i,
});
await expect(processBtn).toBeVisible({ timeout: 10_000 });
console.log("✓ Start Payment Processing button visible at mobile viewport for MGR_APPROVED PO");
});
test("US-18c: SENT_FOR_PAYMENT PO shows reference input and Confirm button at mobile", async ({
page,
context,
}: {
page: import("@playwright/test").Page;
context: BrowserContext;
}) => {
// Create and move to SENT_FOR_PAYMENT
const poUrl = await createApprovedPo(
page,
context,
`E2E_MOBILE_SENT_${Date.now()}`
);
await context.clearCookies();
await page.setViewportSize(MOBILE_VIEWPORT);
await login(page, USERS.ACCOUNTS);
await page.goto(poUrl);
// Start payment processing
await page.getByRole("button", { name: /process payment|start payment/i }).click();
await expect(page.getByText(/sent for payment/i)).toBeVisible({
timeout: 10_000,
});
// Now we should see payment reference input and confirm button
const refInput = page.getByPlaceholder(/reference|ref/i).first();
await expect(refInput).toBeVisible({ timeout: 5_000 });
const confirmBtn = page.getByRole("button", {
name: /confirm payment|mark.*paid/i,
});
await expect(confirmBtn).toBeVisible();
console.log(
"✓ Payment reference input and Confirm Payment button visible at mobile on SENT_FOR_PAYMENT PO"
);
});
test("US-18a: ACCOUNTS mobile bottom nav is visible on /payments", async ({
page,
}) => {
await page.setViewportSize(MOBILE_VIEWPORT);
await login(page, USERS.ACCOUNTS);
// MobileBottomNav renders for ACCOUNTS — should be visible at mobile
const bottomNav = page.locator("nav.md\\:hidden, nav[class*='md:hidden']");
await expect(bottomNav).toBeVisible();
console.log("✓ Mobile bottom navigation bar visible for ACCOUNTS at mobile viewport");
});
});