import { test, expectFixture as expect } from '../helpers/test-fixtures'; const demoTenantCredentials = { email: process.env.E2E_DEMO_TENANT_EMAIL ?? 'tenant-demo@fotospiel.app', password: process.env.E2E_DEMO_TENANT_PASSWORD ?? 'Demo1234!', }; test.describe('Checkout Payment Step - PayPal flow', () => { test('creates PayPal order and completes capture', async ({ page }) => { let createPayload: Record | null = null; let capturePayload: Record | null = null; await page.route('**/paypal/create-order', async (route) => { createPayload = route.request().postDataJSON() as Record; await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ order_id: 'order_test_123', checkout_session_id: 'session_test_123', }), }); }); await page.route('**/paypal/capture-order', async (route) => { capturePayload = route.request().postDataJSON() as Record; await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ status: 'completed', }), }); }); await page.route('https://www.paypal.com/sdk/js**', async (route) => { await route.fulfill({ status: 200, contentType: 'application/javascript', body: ` window.paypal = { Buttons: function(options) { window.__paypalOptions = options; return { render: function() { return Promise.resolve(); }, }; }, }; `, }); }); await openCheckoutPaymentStep(page, demoTenantCredentials); await acceptCheckoutTerms(page); await expect.poll(async () => { return page.evaluate(() => Boolean(window.__paypalOptions)); }).toBe(true); const orderId = await page.evaluate(async () => { return window.__paypalOptions?.createOrder?.(); }); expect(orderId).toBe('order_test_123'); await expect(page.getByText(/PayPal-Checkout ist bereit|PayPal checkout is ready/i)).toBeVisible(); await page.evaluate(async () => { await window.__paypalOptions?.onApprove?.({ orderID: 'order_test_123' }); }); expect(createPayload?.package_id).toBeDefined(); expect(capturePayload?.order_id).toBe('order_test_123'); }); test('shows error state when PayPal checkout creation fails', async ({ page }) => { await page.route('**/paypal/create-order', async (route) => { await route.fulfill({ status: 500, contentType: 'application/json', body: JSON.stringify({ message: 'test-error' }), }); }); await page.route('https://www.paypal.com/sdk/js**', async (route) => { await route.fulfill({ status: 200, contentType: 'application/javascript', body: ` window.paypal = { Buttons: function(options) { window.__paypalOptions = options; return { render: function() { return Promise.resolve(); }, }; }, }; `, }); }); await openCheckoutPaymentStep(page, demoTenantCredentials); await acceptCheckoutTerms(page); await expect.poll(async () => { return page.evaluate(() => Boolean(window.__paypalOptions)); }).toBe(true); await page.evaluate(async () => { try { await window.__paypalOptions?.createOrder?.(); } catch { // swallow error for assertion below } }); await expect( page.locator('text=/PayPal-Checkout konnte nicht gestartet werden|PayPal checkout could not be started/i') ).toBeVisible(); }); }); async function openCheckoutPaymentStep( page: import('@playwright/test').Page, credentials: { email: string; password: string } ) { await page.goto('/packages'); const detailsButtons = page.getByRole('button', { name: /Details ansehen|Details anzeigen|View details/i, }); await expect(detailsButtons.first()).toBeVisible(); await detailsButtons.first().click(); const dialog = page.getByRole('dialog'); await expect(dialog).toBeVisible(); await dialog.getByRole('link', { name: /Jetzt bestellen|Order now|Jetzt buchen/i }).click(); await expect(page).toHaveURL(/\/(bestellen|checkout)\/\d+/); await page.getByRole('button', { name: /^Weiter$/ }).first().click(); const continueButton = page.getByRole('button', { name: /Weiter zur Zahlung|Continue to Payment/i }); if (await continueButton.isVisible()) { await continueButton.click(); } else { await page.getByRole('button', { name: /^Anmelden$/ }).first().click(); await expect(page.locator('input[name="identifier"]')).toBeVisible(); await page.fill('input[name="identifier"]', credentials.email); await page.fill('input[name="password"]', credentials.password); await page.getByRole('button', { name: /^Anmelden$/ }).last().click(); } await expect(page.getByPlaceholder(/Gutscheincode/i)).toBeVisible(); } async function acceptCheckoutTerms(page: import('@playwright/test').Page) { const termsCheckbox = page.locator('#checkout-terms-hero'); await expect(termsCheckbox).toBeVisible(); await termsCheckbox.click(); } declare global { interface Window { __paypalOptions?: { createOrder?: () => Promise; onApprove?: (data: { orderID: string }) => Promise; }; } }