Files
cfw-autumn/server/tests/utils/browserPool/playwright/invoiceConfirmation.ts
2026-02-22 15:50:32 +00:00

65 lines
1.8 KiB
TypeScript

import type { Page } from "playwright-core";
/**
* Self-contained Playwright function for completing a Stripe 3DS Invoice Confirmation.
* NO external imports — this function must be serializable via fn.toString()
* for Kernel Playwright Execution. (type imports are fine — Bun strips them)
*/
export const invoiceConfirmation = async ({
page,
url,
}: {
page: Page;
url: string;
}) => {
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
console.log("[invoiceConfirmation] Page loaded");
// Find and click the "Confirm payment" button
const confirmBtn = page
.locator("button")
.filter({ hasText: /confirm payment/i })
.first();
await confirmBtn.waitFor({ timeout: 15000 });
await confirmBtn.click();
console.log("[invoiceConfirmation] Confirm payment clicked");
// Wait for the 3DS challenge iframe to appear
await page.waitForTimeout(3000);
let authorizeClicked = false;
// Poll for the 3DS challenge frame
for (let i = 0; i < 20; i++) {
await page.waitForTimeout(2000);
// Try the direct #test-source-authorize-3ds button in any frame
for (const frame of page.frames()) {
try {
const btn = frame.locator("#test-source-authorize-3ds");
if ((await btn.count()) > 0) {
await btn.click({ timeout: 3000 });
console.log(
`[invoiceConfirmation] 3DS authorize clicked in frame: ${frame.url().substring(0, 60)}`,
);
authorizeClicked = true;
break;
}
} catch {
// Frame may not be ready yet
}
}
if (authorizeClicked) break;
}
if (!authorizeClicked) {
throw new Error(
"Could not find or click #test-source-authorize-3ds in any frame",
);
}
// Wait for 3DS authentication to complete + webhook processing
await page.waitForTimeout(10000);
console.log("[invoiceConfirmation] 3DS confirmation complete");
};