import { expect, test } from "@playwright/test"; import { mockCoreApis } from "@e2e/fixtures/api-mocks"; import { apiEnvelope } from "@e2e/fixtures/data/common"; import { clearBrowserState, seedEmailSession, } from "@e2e/fixtures/test-helpers"; const facebookAndroidUserAgent = "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 " + "(KHTML, like Gecko) Version/4.0 Chrome/126.0.0.0 Mobile Safari/537.36 " + "[FB_IAB/FB4A;FBAV/566.0.0.48.73;]"; const handoffToken = "checkout-handoff-token-that-is-at-least-32-characters"; test.use({ userAgent: facebookAndroidUserAgent }); test.beforeEach(async ({ baseURL, context, page }) => { await clearBrowserState(context, page, baseURL); }); test("consumes the handoff, removes its token, and does not create an order", async ({ page, }) => { await mockCoreApis(page, { checkoutHandoffFlow: true }); let createOrderRequests = 0; page.on("request", (request) => { if (request.url().includes("/api/payment/create-order")) { createOrderRequests += 1; } }); const consumeRequest = page.waitForRequest( "**/api/auth/handoff/checkout/consume", ); await page.goto( `/external-entry?target=checkout&handoffToken=${encodeURIComponent(handoffToken)}`, ); expect((await consumeRequest).postDataJSON()).toEqual({ handoffToken }); await expect(page).toHaveURL( /\/subscription\?planId=vip_monthly&autoRenew=1&commercialOfferId=.*&payChannel=stripe/, ); expect(page.url()).not.toContain("handoffToken"); await expect.poll(() => createOrderRequests).toBe(0); await expect .poll(() => page.evaluate(() => ({ loginProvider: localStorage.getItem("cozsweet:login_provider"), loginToken: localStorage.getItem("cozsweet:login_token"), })), ) .toEqual({ loginProvider: "email", loginToken: "e2e-checkout-token" }); }); test("offers the Facebook external-browser path before creating a Stripe order", async ({ page, }) => { await mockCoreApis(page); let createOrderRequests = 0; page.on("request", (request) => { if (request.url().includes("/api/payment/create-order")) { createOrderRequests += 1; } }); await page.route("**/api/auth/handoff/checkout", async (route) => { await route.fulfill({ json: apiEnvelope({ externalUrl: "https://cozsweet.com/external-entry?target=checkout&handoffToken=opaque-token", expiresAt: "2026-07-28T16:00:00+00:00", }), }); }); await seedEmailSession(page); await page.goto( "/subscription?type=vip&payChannel=stripe&character=elio", ); await page.getByRole("button", { name: /Monthly,/i }).click(); const externalButton = page.getByRole("button", { name: "Open in browser for more payment methods", }); await expect(externalButton).toBeEnabled(); await expect( page.getByRole("dialog", { name: "Automatic Renewal Confirmation" }), ).toHaveCount(0); const handoffRequest = page.waitForRequest("**/api/auth/handoff/checkout"); await externalButton.click(); expect((await handoffRequest).postDataJSON()).toMatchObject({ planId: "vip_monthly", autoRenew: true, }); expect(createOrderRequests).toBe(0); });