import { expect, test } from "@playwright/test"; import { mockCoreApis } from "@e2e/fixtures/api-mocks"; import { apiEnvelope } from "@e2e/fixtures/data/common"; import { createPaidImageHistoryResponse } from "@e2e/fixtures/data/chat"; import { paidImageDisplayMessageId, paidImageMessageId, } from "@e2e/fixtures/test-data"; import { clearBrowserState, completeVipPayment, defaultCharacterChatPath, dismissChatInterruptions, enterChatFromSplash, expectInsufficientCreditsDialog, expectVipChatSubscriptionUrl, submitEmailLogin, switchToEmailSignIn, } from "@e2e/fixtures/test-helpers"; test.beforeEach(async ({ baseURL, context, page }) => { await clearBrowserState(context, page, baseURL); await mockCoreApis(page, { paidImageFlow: true, }); }); test("guest can unlock a paid image after email login and subscription payment", async ({ page, }) => { await enterChatFromSplash(page); await dismissChatInterruptions(page); const messageInput = page.getByRole("textbox", { name: "Message" }); await expect(messageInput).toBeVisible({ timeout: 10_000 }); await messageInput.fill("给我发图片"); const sendRequestPromise = page.waitForRequest("**/api/chat/send"); await messageInput.press("Enter"); const sendRequest = await sendRequestPromise; expect(sendRequest.postDataJSON()).toMatchObject({ message: "给我发图片", }); const lockedImageCard = page.getByRole("group", { name: "Locked private image", }).last(); await expect(lockedImageCard).toBeVisible(); await expect(lockedImageCard.locator("img")).toHaveCount(0); await lockedImageCard .getByRole("button", { name: "Unlock private image" }) .click(); await expect(page).toHaveURL(/\/auth\?redirect=/); expect(new URL(page.url()).searchParams.get("redirect")).toBe( defaultCharacterChatPath, ); await switchToEmailSignIn(page); const unlockRequestPromise = page.waitForRequest( "**/api/chat/unlock-private", ); await submitEmailLogin(page, { expectedUrl: new RegExp(`${defaultCharacterChatPath}$`), }); const unlockRequest = await unlockRequestPromise; expect(unlockRequest.postDataJSON()).toMatchObject({ messageId: paidImageMessageId, }); const insufficientCreditsDialog = await expectInsufficientCreditsDialog(page); await insufficientCreditsDialog .getByRole("button", { name: "Top up now" }) .click(); await expectVipChatSubscriptionUrl(page); await completeVipPayment(page); await expect(page).toHaveURL( new RegExp( `${defaultCharacterChatPath}(?:\\?image=${encodeURIComponent(paidImageDisplayMessageId)})?$`, ), ); expect(new URL(page.url()).pathname).toBe(defaultCharacterChatPath); await expect(page.getByRole("textbox", { name: "Message" })).toBeVisible(); }); test("fullscreen image closes from its back button, the image, and browser history Back", async ({ page, }) => { await page.route("**/api/chat/history**", async (route) => { await route.fulfill({ json: apiEnvelope(createPaidImageHistoryResponse(true)), }); }); await enterChatFromSplash(page); await dismissChatInterruptions(page); const imageButton = page.getByRole("button", { name: "Open image in fullscreen", }); const imageDialog = page.getByRole("dialog", { name: "Fullscreen image" }); await imageButton.click(); await expect(imageDialog).toBeVisible(); await imageDialog.getByRole("button", { name: "Back" }).click(); await expect(imageDialog).toHaveCount(0); await expect(page).toHaveURL(defaultCharacterChatPath); await imageButton.click(); await expect(imageDialog).toBeVisible(); await imageDialog.locator("img").click(); await expect(imageDialog).toHaveCount(0); await expect(page).toHaveURL(defaultCharacterChatPath); await imageButton.click(); await expect(imageDialog).toBeVisible(); await page.goBack(); await expect(imageDialog).toHaveCount(0); await expect(page).toHaveURL(defaultCharacterChatPath); });