test(e2e): fix auth specs for character routes
This commit is contained in:
@@ -2,6 +2,7 @@ import type { Page } from "@playwright/test";
|
|||||||
|
|
||||||
import { registerAuthMocks } from "./api/auth";
|
import { registerAuthMocks } from "./api/auth";
|
||||||
import { registerChatMocks } from "./api/chat";
|
import { registerChatMocks } from "./api/chat";
|
||||||
|
import { registerCharacterMocks } from "./api/character";
|
||||||
import { registerPaymentMocks } from "./api/payment";
|
import { registerPaymentMocks } from "./api/payment";
|
||||||
import { registerUserMocks } from "./api/user";
|
import { registerUserMocks } from "./api/user";
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ export async function mockCoreApis(page: Page, options: MockCoreApisOptions = {}
|
|||||||
isChatSendTokenExpired: () => chatState.hasExpiredChatSend,
|
isChatSendTokenExpired: () => chatState.hasExpiredChatSend,
|
||||||
psidLoginFlow: chatOptions.psidLoginFlow,
|
psidLoginFlow: chatOptions.psidLoginFlow,
|
||||||
});
|
});
|
||||||
|
await registerCharacterMocks(page);
|
||||||
await registerUserMocks(page);
|
await registerUserMocks(page);
|
||||||
await registerChatMocks(page, chatOptions, chatState);
|
await registerChatMocks(page, chatOptions, chatState);
|
||||||
await registerPaymentMocks(page);
|
await registerPaymentMocks(page);
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import type { Page } from "@playwright/test";
|
||||||
|
|
||||||
|
import { apiEnvelope } from "../data/common";
|
||||||
|
import { chatCharactersResponse } from "../data/character";
|
||||||
|
|
||||||
|
export async function registerCharacterMocks(page: Page) {
|
||||||
|
await page.route("**/api/characters**", async (route) => {
|
||||||
|
await route.fulfill({ json: apiEnvelope(chatCharactersResponse) });
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Page } from "@playwright/test";
|
import type { Page } from "@playwright/test";
|
||||||
|
|
||||||
import { apiEnvelope } from "../data/common";
|
import { apiEnvelope } from "../data/common";
|
||||||
import { chatSendResponse, createChatSendResponse, createPaidImageHistoryResponse, createWeeklyLimitChatSendResponse, emptyChatHistoryResponse, insufficientCreditsUnlockImageResponse, insufficientCreditsUnlockVoiceResponse, paidImageChatSendResponse, paidImageUnlockHistoryResponse, paidVoiceHistoryResponse } from "../data/chat";
|
import { chatSendResponse, createChatSendResponse, createPaidImageHistoryResponse, createWeeklyLimitChatSendResponse, emptyChatHistoryResponse, emptyChatPreviewsResponse, insufficientCreditsUnlockImageResponse, insufficientCreditsUnlockVoiceResponse, paidImageChatSendResponse, paidImageUnlockHistoryResponse, paidVoiceHistoryResponse } from "../data/chat";
|
||||||
|
|
||||||
export interface ChatMockOptions {
|
export interface ChatMockOptions {
|
||||||
chatLimitTriggerAt?: number;
|
chatLimitTriggerAt?: number;
|
||||||
@@ -31,6 +31,10 @@ export async function registerChatMocks(page: Page, options: ChatMockOptions, st
|
|||||||
await route.fulfill({ json: apiEnvelope(response) });
|
await route.fulfill({ json: apiEnvelope(response) });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await page.route("**/api/chat/previews", async (route) => {
|
||||||
|
await route.fulfill({ json: apiEnvelope(emptyChatPreviewsResponse) });
|
||||||
|
});
|
||||||
|
|
||||||
await page.route("**/api/chat/send", async (route) => {
|
await page.route("**/api/chat/send", async (route) => {
|
||||||
sendCount += 1;
|
sendCount += 1;
|
||||||
const requestBody = route.request().postDataJSON() as { message?: unknown } | undefined;
|
const requestBody = route.request().postDataJSON() as { message?: unknown } | undefined;
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export const chatCharactersResponse = {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: "elio",
|
||||||
|
displayName: "Elio Silvestri",
|
||||||
|
isActive: true,
|
||||||
|
capabilities: { chat: true, privateContent: true },
|
||||||
|
sortOrder: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "maya-tan",
|
||||||
|
displayName: "Maya Tan",
|
||||||
|
isActive: true,
|
||||||
|
capabilities: { chat: true, privateContent: true },
|
||||||
|
sortOrder: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "nayeli-cervantes",
|
||||||
|
displayName: "Nayeli Cervantes",
|
||||||
|
isActive: true,
|
||||||
|
capabilities: { chat: true, privateContent: true },
|
||||||
|
sortOrder: 30,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
defaultCharacterId: "elio",
|
||||||
|
};
|
||||||
@@ -9,6 +9,8 @@ export const emptyChatHistoryResponse = {
|
|||||||
privateCanViewFree: false,
|
privateCanViewFree: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const emptyChatPreviewsResponse = { items: [] };
|
||||||
|
|
||||||
export const chatSendResponse = {
|
export const chatSendResponse = {
|
||||||
reply: "Hello from the E2E boyfriend.",
|
reply: "Hello from the E2E boyfriend.",
|
||||||
audioUrl: "",
|
audioUrl: "",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const splashStartChatButtonName = "Start Chatting";
|
|||||||
export const defaultCharacterSlug = "elio";
|
export const defaultCharacterSlug = "elio";
|
||||||
export const defaultCharacterSplashPath = `/characters/${defaultCharacterSlug}/splash`;
|
export const defaultCharacterSplashPath = `/characters/${defaultCharacterSlug}/splash`;
|
||||||
export const defaultCharacterChatPath = `/characters/${defaultCharacterSlug}/chat`;
|
export const defaultCharacterChatPath = `/characters/${defaultCharacterSlug}/chat`;
|
||||||
export const defaultCharacterSidebarPath = `/characters/${defaultCharacterSlug}/sidebar`;
|
export const defaultCharacterSidebarPath = `/sidebar?returnTo=%2Fcharacters%2F${defaultCharacterSlug}%2Fchat`;
|
||||||
export const defaultCharacterChatUrl = new RegExp(
|
export const defaultCharacterChatUrl = new RegExp(
|
||||||
`/characters/${defaultCharacterSlug}/chat(?:\\?.*)?$`,
|
`/characters/${defaultCharacterSlug}/chat(?:\\?.*)?$`,
|
||||||
);
|
);
|
||||||
@@ -34,6 +34,8 @@ export async function seedEmailSession(page: Page) {
|
|||||||
await page.goto(defaultCharacterSplashPath);
|
await page.goto(defaultCharacterSplashPath);
|
||||||
await setEmailSessionStorage(page);
|
await setEmailSessionStorage(page);
|
||||||
await page.reload();
|
await page.reload();
|
||||||
|
// Let the root auth provider hydrate the seeded session before navigation.
|
||||||
|
await page.waitForTimeout(750);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function switchToEmailSignIn(page: Page) {
|
export async function switchToEmailSignIn(page: Page) {
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import {
|
|||||||
clearBrowserState,
|
clearBrowserState,
|
||||||
defaultCharacterSidebarPath,
|
defaultCharacterSidebarPath,
|
||||||
defaultCharacterSplashPath,
|
defaultCharacterSplashPath,
|
||||||
|
defaultCharacterChatUrl,
|
||||||
|
enterChatFromSplash,
|
||||||
getSplashStartChatButton,
|
getSplashStartChatButton,
|
||||||
signInWithEmailAndOpenChat,
|
submitEmailLogin,
|
||||||
|
switchToEmailSignIn,
|
||||||
} from "@e2e/fixtures/test-helpers";
|
} from "@e2e/fixtures/test-helpers";
|
||||||
|
|
||||||
test.beforeEach(async ({ baseURL, context, page }) => {
|
test.beforeEach(async ({ baseURL, context, page }) => {
|
||||||
@@ -17,11 +20,19 @@ test.beforeEach(async ({ baseURL, context, page }) => {
|
|||||||
test("user can log out from the sidebar after email login", async ({
|
test("user can log out from the sidebar after email login", async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
await signInWithEmailAndOpenChat(page);
|
await enterChatFromSplash(page);
|
||||||
|
await page
|
||||||
|
.getByRole("button", { name: "Sign up to unlock more features" })
|
||||||
|
.click();
|
||||||
|
await expect(page).toHaveURL(/\/auth(?:\?.*)?$/);
|
||||||
|
await switchToEmailSignIn(page);
|
||||||
|
await submitEmailLogin(page, { expectedUrl: defaultCharacterChatUrl });
|
||||||
await expect(page.getByRole("button", { name: "Menu" })).toBeVisible();
|
await expect(page.getByRole("button", { name: "Menu" })).toBeVisible();
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Menu" }).click();
|
await page.getByRole("button", { name: "Menu" }).click();
|
||||||
await expect(page).toHaveURL(new RegExp(`${defaultCharacterSidebarPath}$`));
|
await expect(page).toHaveURL(
|
||||||
|
new RegExp(defaultCharacterSidebarPath.replace("?", "\\?") + "$"),
|
||||||
|
);
|
||||||
|
|
||||||
const logoutRequestPromise = page.waitForRequest("**/api/auth/logout");
|
const logoutRequestPromise = page.waitForRequest("**/api/auth/logout");
|
||||||
await page.getByRole("button", { name: /Log out/i }).click();
|
await page.getByRole("button", { name: /Log out/i }).click();
|
||||||
|
|||||||
Reference in New Issue
Block a user