import { test, expectFixture as expect } from '../helpers/test-fixtures'; const shouldRun = process.env.E2E_TESTING_API === '1'; test.describe('Standard package checkout with Paddle completion', () => { test.skip(!shouldRun, 'Set E2E_TESTING_API=1 to enable checkout tests that use /api/_testing endpoints.'); test('registers, applies coupon, and reaches confirmation', async ({ page, clearTestMailbox, getLatestCheckoutSession, simulatePaddleCompletion, getTestMailbox, }) => { await clearTestMailbox(); const unique = Date.now(); const email = `checkout+${unique}@example.test`; const password = 'Password123!'; const username = `playwright-${unique}`; await page.addInitScript(() => { window.__openedWindows = []; const originalOpen = window.open; window.open = function (...args) { window.__openedWindows.push(args); return originalOpen?.apply(this, args) ?? null; }; }); await page.route('https://cdn.paddle.com/paddle/v2/paddle.js', async (route) => { await route.fulfill({ status: 200, contentType: 'application/javascript', body: ` window.__paddleEventCallback = null; window.__paddleInitOptions = null; window.__paddleCheckoutConfig = null; window.Paddle = { Environment: { set() {} }, Initialize(options) { window.__paddleInitOptions = options; window.__paddleEventCallback = options?.eventCallback || null; }, Checkout: { open(config) { window.__paddleCheckoutConfig = config; }, }, }; `, }); }); let paddleRequestPayload: Record | null = null; await page.route('**/paddle/create-checkout', async (route) => { paddleRequestPayload = route.request().postDataJSON() as Record; await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ checkout_url: 'https://sandbox.paddle.test/checkout/abc123', }), }); }); await page.goto('/de/packages'); const standardDetailsButton = page .getByRole('heading', { name: /^Standard$/ }) .locator('..') .getByRole('button', { name: /Details/i }) .first(); await expect(standardDetailsButton).toBeVisible(); await standardDetailsButton.click(); await expect(page.getByRole('dialog')).toBeVisible(); await page.getByRole('link', { name: /Jetzt bestellen|Order now/i }).click(); await expect(page).toHaveURL(/(bestellen|checkout)/); await page.getByRole('button', { name: /^Weiter$/ }).first().click(); await expect(page.locator('input[name="first_name"]')).toBeVisible(); await page.fill('input[name="first_name"]', 'Playwright'); await page.fill('input[name="last_name"]', 'Tester'); await page.fill('input[name="email"]', email); await page.fill('input[name="phone"]', '+49123456789'); await page.fill('input[name="address"]', 'Teststr. 1, 12345 Berlin'); await page.fill('input[name="username"]', username); await page.fill('input[name="password"]', password); await page.fill('input[name="password_confirmation"]', password); await page.check('input[name="privacy_consent"]'); await page.getByRole('button', { name: /^Registrieren$/ }).last().click(); await expect(page.getByPlaceholder(/Gutscheincode/i)).toBeVisible(); await page.getByPlaceholder(/Gutscheincode/i).fill('PERCENT10'); await page.getByRole('button', { name: /Gutschein anwenden|Apply coupon/i }).click(); await expect(page.getByText(/Gutschein PERCENT10/i)).toBeVisible(); const termsCheckbox = page.locator('#checkout-terms-hero'); await expect(termsCheckbox).toBeVisible(); await termsCheckbox.click(); await page.getByRole('button', { name: /Weiter mit Paddle|Continue with Paddle/i }).first().click(); let checkoutMode: 'inline' | 'hosted' | null = null; for (let i = 0; i < 8; i++) { const state = await page.evaluate(() => ({ inline: Boolean(window.__paddleCheckoutConfig), opened: window.__openedWindows?.length ?? 0, })); if (state.inline) { checkoutMode = 'inline'; break; } if (state.opened > 0) { checkoutMode = 'hosted'; break; } await page.waitForTimeout(300); } expect(checkoutMode).not.toBeNull(); if (checkoutMode === 'hosted') { await expect.poll(async () => { return page.evaluate(() => window.__openedWindows?.[0]?.[0] ?? null); }).toContain('https://sandbox.paddle.test/checkout/abc123'); } await page.evaluate(() => { window.__paddleEventCallback?.({ name: 'checkout.completed' }); }); let session = null; for (let i = 0; i < 6; i++) { session = await getLatestCheckoutSession({ email }); if (session) { break; } await page.waitForTimeout(500); } if (session) { await simulatePaddleCompletion(session.id); for (let i = 0; i < 6; i++) { const refreshed = await getLatestCheckoutSession({ email }); if (refreshed?.status === 'completed') { session = refreshed; break; } await page.waitForTimeout(500); } expect(session?.status).toBe('completed'); } await expect(page.getByText(/Marketing-Dashboard/)).toBeVisible(); await expect( page.getByRole('button', { name: /Zum Admin-Bereich|To Admin Area/i }) ).toBeVisible(); if (paddleRequestPayload) { expect(paddleRequestPayload['coupon_code']).toBe('PERCENT10'); } const messages = await getTestMailbox(); expect(messages.length).toBeGreaterThan(0); }); }); declare global { interface Window { __openedWindows?: unknown[]; __paddleEventCallback?: ((event: { name: string }) => void) | null; __paddleInitOptions?: unknown; __paddleCheckoutConfig?: unknown; } }