import { expect, test } from "@playwright/test"; import { mockCoreApis } from "@e2e/fixtures/api-mocks"; import { clearBrowserState, completeVipPayment, dismissChatInterruptions, enterChatFromSplash, expectAuthRedirectToVipChatSubscription, expectVipChatSubscriptionUrl, submitEmailLogin, switchToEmailSignIn, } from "@e2e/fixtures/test-helpers"; const mockedLimitTriggerAt = 5; const maxManualTestMessages = 51; test.setTimeout(90_000); test.beforeEach(async ({ baseURL, context, page }) => { await clearBrowserState(context, page, baseURL); await mockCoreApis(page, { chatLimitTriggerAt: mockedLimitTriggerAt, }); }); test("guest uses the shared chat limit top-up flow", async ({ page }) => { await enterChatFromSplash(page); await dismissChatInterruptions(page); const messageInput = page.getByRole("textbox", { name: "Message" }); const quantityLimitBanner = page .getByRole("status") .filter({ hasText: "Insufficient credits" }); let limitTriggeredAt: number | null = null; let completedSendCount = 0; await expect(messageInput).toBeVisible({ timeout: 10_000 }); for (let index = 1; index <= maxManualTestMessages; index += 1) { const message = `limit test ${String(index).padStart(2, "0")}`; await dismissChatInterruptions(page); if (completedSendCount > 0) { const inputStillVisible = await messageInput.isVisible().catch(() => false); if (!inputStillVisible) { limitTriggeredAt = completedSendCount; break; } } if (await isQuantityLimitVisible(quantityLimitBanner)) { limitTriggeredAt = completedSendCount; break; } await expect(messageInput).toBeVisible(); await messageInput.fill(message); const sendRequestPromise = page.waitForRequest("**/api/chat/send"); await messageInput.press("Enter"); const sendRequest = await sendRequestPromise; expect(sendRequest.postDataJSON()).toMatchObject({ message, }); completedSendCount = index; if (await isQuantityLimitVisible(quantityLimitBanner)) { limitTriggeredAt = index; break; } await page.waitForTimeout(1_000); } expect(limitTriggeredAt).not.toBeNull(); expect(limitTriggeredAt).toBeLessThanOrEqual(maxManualTestMessages); expect(limitTriggeredAt).toBe(mockedLimitTriggerAt); await expect(quantityLimitBanner).toBeVisible(); await expect( quantityLimitBanner.getByText("Free chats refresh every day."), ).toBeVisible(); const topUpButton = quantityLimitBanner.getByRole("button", { name: "Top up credits to continue", }); await expect(topUpButton).toBeVisible(); await topUpButton.click(); await expect(page).toHaveURL(/\/auth\?redirect=/); expectAuthRedirectToVipChatSubscription(page); await switchToEmailSignIn(page); await submitEmailLogin(page); await expectVipChatSubscriptionUrl(page); await completeVipPayment(page); await expect(page).toHaveURL(/\/chat$/); await expect(page.getByRole("textbox", { name: "Message" })).toBeVisible(); }); async function isQuantityLimitVisible( banner: ReturnType, ) { try { await banner.waitFor({ state: "visible", timeout: 500 }); return true; } catch { return false; } }