import { test, expectFixture as expect } from '../helpers/test-fixtures'; const shouldRun = process.env.E2E_TESTING_API === '1'; test.describe('Classic package checkout with PayPal 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, seedTestCoupons, }) => { await clearTestMailbox(); await seedTestCoupons(); const unique = Date.now(); const email = `checkout+${unique}@example.test`; const password = 'Password123!'; 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(); }, }; }, }; `, }); }); let paypalRequestPayload: Record | null = null; await page.route('**/paypal/create-order', async (route) => { paypalRequestPayload = 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) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ status: 'completed', }), }); }); await page.goto('/de/packages'); const standardDetailsButton = page .locator('[data-slot="card"]') .filter({ hasText: /Classic/i }) .getByRole('button', { name: /Details ansehen|Details anzeigen|View 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); const addressInput = page.locator('input[name="address"]'); if (await addressInput.isVisible()) { await addressInput.fill('Teststr. 1, 12345 Berlin'); } const phoneInput = page.locator('input[name="phone"]'); if (await phoneInput.isVisible()) { await phoneInput.fill('+49123456789'); } const usernameInput = page.locator('input[name="username"]'); if (await usernameInput.isVisible()) { await usernameInput.fill(email); } 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 aktiviert|Coupon PERCENT10 applied/i) ).toBeVisible(); const termsCheckbox = page.locator('#checkout-terms-hero'); await expect(termsCheckbox).toBeVisible(); await termsCheckbox.click(); 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 page.evaluate(async () => { await window.__paypalOptions?.onApprove?.({ orderID: 'order_test_123' }); }); await expect(page.getByText(/Marketing-Dashboard/)).toBeVisible(); await expect( page.getByRole('button', { name: /Zum Admin-Bereich|To Admin Area/i }) ).toBeVisible(); if (paypalRequestPayload) { expect(paypalRequestPayload['coupon_code']).toBe('PERCENT10'); } }); }); declare global { interface Window { __paypalOptions?: { createOrder?: () => Promise; onApprove?: (data: { orderID: string }) => Promise; }; } }