import { When } from "@cucumber/cucumber"; import path from "node:path"; import type { ActorSession } from "@pikku/cucumber/browser"; import type { AppWorld } from "../support/world.js"; /** * Project-specific invoice steps. Talk to the Invoices tab on the admin * booking-detail page (Mantine form). Locale-aware: the form uses German * labels by default in this app. */ When( "{actor} create(s) an invoice numbered {string} for {float} €", async function (this: AppWorld, actor: ActorSession, invoiceNumber: string, amountEuro: number) { // The form sits in the "Neue Rechnung" panel — use data-testid hooks so we // are not coupled to localized labels. const numberField = actor.page .getByTestId("invoice-create-form") .locator('input[data-testid="invoice-number"], [data-testid="invoice-number"] input') .first(); await numberField.fill(invoiceNumber); const amount = actor.page .getByTestId("invoice-create-form") .locator('input[data-testid="invoice-amount"], [data-testid="invoice-amount"] input') .first(); await amount.fill(""); await amount.fill(String(amountEuro.toFixed(2))); await actor.page .getByRole("button", { name: /rechnung erstellen|create invoice/i }) .click(); // Wait for the row to appear in the invoices table above the form. await actor.page.getByText(invoiceNumber, { exact: false }).first().waitFor({ state: "visible", }); }, ); When( "{actor} attach(es) invoice PDF {string}", async function (this: AppWorld, actor: ActorSession, filename: string) { const filePath = path.resolve(process.cwd(), "tests", "fixtures", filename); await actor.page.getByTestId("invoice-pdf").setInputFiles(filePath); }, ); When( "{actor} mark(s) invoice {string} as paid on {string}", async function (this: AppWorld, actor: ActorSession, invoiceNumber: string, paidOn: string) { // Stub the prompt before clicking — the UI uses window.prompt to collect // the payment date. await actor.page.evaluate((value) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any (window as any).prompt = () => value; }, paidOn); const row = actor.page.getByRole("row", { name: new RegExp(invoiceNumber) }); await row.getByTestId(`invoice-mark-paid-${invoiceNumber}`).click(); await row.getByText(/bezahlt|paid/i).waitFor({ state: "visible" }); }, );