import { expect, test } from '@playwright/test'; const shouldRun = process.env.E2E_PAYPAL_SANDBOX === '1' || process.env.E2E_LEMONSQUEEZY_SANDBOX === '1' || process.env.E2E_PADDLE_SANDBOX === '1'; const base = process.env.E2E_BASE_URL ?? 'https://test-y0k0.fotospiel.app'; const locale = process.env.E2E_LOCALE ?? 'de'; const checkoutSlug = locale === 'en' ? 'checkout' : 'bestellen'; const tenantEmail = process.env.E2E_TENANT_EMAIL ?? null; const tenantPassword = process.env.E2E_TENANT_PASSWORD ?? null; test.describe('PayPal sandbox checkout (staging)', () => { test.skip(!shouldRun, 'Set E2E_PAYPAL_SANDBOX=1 to run sandbox checkout on staging.'); test.skip(!tenantEmail || !tenantPassword, 'Set E2E_TENANT_EMAIL and E2E_TENANT_PASSWORD for sandbox flow.'); test('creates PayPal order from the checkout wizard', async ({ page }) => { 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 page.route('**/paypal/create-order', async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ order_id: 'order_test_123', checkout_session_id: 'session_test_123', }), }); }); await page.goto(`${base}/${locale}/${checkoutSlug}/2`); await proceedToAccountStep(page); await login(page, { email: tenantEmail!, password: tenantPassword! }); 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'); }); }); async function proceedToAccountStep(page: import('@playwright/test').Page, timeoutMs = 30_000): Promise { const deadline = Date.now() + timeoutMs; while (Date.now() < deadline) { const accountForm = page.locator('input[name="first_name"], input[name="identifier"]'); if (await accountForm.isVisible()) { return; } const continueButton = page.getByRole('button', { name: /Weiter|Continue/i }).first(); if (await continueButton.isVisible()) { if (await continueButton.isEnabled()) { await continueButton.click(); } } await page.waitForTimeout(500); } throw new Error('Account step did not load in time.'); } async function login(page: import('@playwright/test').Page, credentials: { email: string; password: string }) { const identifierInput = page.locator('input[name="identifier"]'); if (!(await identifierInput.isVisible())) { return; } await identifierInput.fill(credentials.email); await page.locator('input[name="password"]').fill(credentials.password); await page.getByRole('button', { name: /^Anmelden$|Login/i }).last().click(); await expect(page.getByPlaceholder(/Gutscheincode|Coupon/i)).toBeVisible({ timeout: 20_000 }); } declare global { interface Window { __paypalOptions?: { createOrder?: () => Promise; }; } }