import { expect, test } from "@playwright/test"; import { mockCoreApis } from "../../fixtures/api-mocks"; const mockedLimitTriggerAt = 5; const maxManualTestMessages = 51; test.beforeEach(async ({ context, page }) => { await context.clearCookies(); await mockCoreApis(page, { chatLimitTriggerAt: mockedLimitTriggerAt, }); }); test("guest hits the chat quantity limit and can continue to login and subscription", async ({ page, }) => { await page.goto("/splash"); await page.getByRole("button", { name: "Skip" }).click(); await expect(page).toHaveURL(/\/chat$/); await dismissChatInterruptions(page); const messageInput = page.getByRole("textbox", { name: "Message" }); const quantityLimitBanner = page.getByTestId("chat-quota-exhausted-banner"); 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(messageInput).toHaveCount(0); const unlockButton = page.getByRole("button", { name: "Unlock your membership to continue", }); await expect(unlockButton).toBeVisible(); await unlockButton.click(); await expect(page).toHaveURL(/\/auth\?redirect=/); expect(new URL(page.url()).searchParams.get("redirect")).toBe( "/subscription?type=vip&returnTo=chat", ); await page.getByRole("button", { name: /Other Sign In Options/i }).click(); await expect( page.getByRole("dialog", { name: /Other sign-in options/i }), ).toBeVisible(); await page.getByRole("button", { name: "Email Sign In" }).click(); await expect(page.getByPlaceholder("Email")).toHaveValue( "chanwillian0@gmail.com", ); await expect(page.getByPlaceholder("Password")).toHaveValue("12345678"); await page.getByRole("button", { name: "Login" }).click(); await expect(page).toHaveURL(/\/subscription\?type=vip&returnTo=chat$/); const createOrderRequestPromise = page.waitForRequest( "**/api/payment/create-order", ); const orderStatusRequestPromise = page.waitForRequest( "**/api/payment/order-status**", ); await page.getByRole("button", { name: /Pay and Activ/i }).click(); const createOrderRequest = await createOrderRequestPromise; expect(createOrderRequest.postDataJSON()).toMatchObject({ planId: "vip_monthly", payChannel: "stripe", }); await orderStatusRequestPromise; const paymentSuccessDialog = page.getByRole("alertdialog", { name: "Payment successful", }); await expect(paymentSuccessDialog).toBeVisible(); await paymentSuccessDialog.getByRole("button", { name: "OK" }).click(); 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; } } async function dismissChatInterruptions(page: import("@playwright/test").Page) { const laterButton = page.getByRole("button", { name: "Later" }); if (await laterButton.isVisible().catch(() => false)) { await laterButton.click(); } const cancelButton = page.getByRole("button", { name: "Cancel" }); if (await cancelButton.isVisible().catch(() => false)) { await cancelButton.click(); } const okButton = page.getByRole("button", { name: "OK" }); if (await okButton.isVisible().catch(() => false)) { await okButton.click(); } }