/** * E2E: onboarding fills the user profile without asking (time zone, locale and language from * the browser) and records the focus answer as a fact; Settings → General → About you shows every fact * with its origin, confirms a pending one, and forgets one or all of them. */ import { expect, test } from "@playwright/test"; import { captureScreenshot, openUserSettings, rpc, signup, waitForChatComposer } from "./helpers"; test.use({ timezoneId: "Europe/Vienna" }); test.beforeEach(async ({ page }) => { // Walk the full emoji-first flow. await page.route("**/rpc/integrationSetup/get", (route) => route.fulfill({ json: { json: { canConfigure: true, needsSetup: false, webUrl: "https://example.test/integrations/setup", providers: [{ id: "composio", configured: true }], }, }, }), ); }); test("onboarding feeds the profile; facts can be confirmed and forgotten", async ({ page, }, testInfo) => { const stamp = Date.now(); await signup(page, `profile-${stamp}@rakazo.test`, "password12", "Profile Tester"); await expect(page.getByRole("heading", { name: /Design your Oo/i })).toBeVisible({ timeout: 30_000, }); await page.getByRole("button", { name: "Continue", exact: true }).click(); await expect(page.getByRole("heading", { name: /Choose your language/i })).toBeVisible(); await page.getByRole("button", { name: "English", exact: true }).click(); await expect(page.getByRole("heading", { name: /Pick a voice/i })).toBeVisible(); await page.getByRole("button", { name: "Skip", exact: true }).click(); await page.waitForURL(/\/app\/g\/[^/]+/, { timeout: 30_000 }); await waitForChatComposer(page); // The main bot asks the rest in the main conversation; the focus answer becomes a fact. await page.getByTestId("focus-choice-day").click(); await expect(page.locator('[data-testid="choice-card"][data-step="goal"]')).toBeVisible(); // The answers no longer overwrite a bot's instructions. const bots = await rpc>(page, "bots/list", null); expect(bots.length).toBeGreaterThan(0); for (const bot of bots) expect(bot.instructions).not.toContain("User Context"); // The account name is used as is; onboarding no longer asks for it again. expect((await rpc<{ name: string }>(page, "me", null)).name).toBe("Profile Tester"); // Sensitive facts from anywhere but the user wait for confirmation. await rpc(page, "profile/update", { addFacts: [{ category: "health", value: "Allergic to peanuts", source: "onboarding" }], }); const settings = await openUserSettings(page); await expect(settings).toHaveAttribute("data-settings-section", "general"); const profile = settings.getByTestId("user-profile-settings"); await expect(profile.getByTestId("profile-field-timeZone")).toContainText("Europe/Vienna"); await expect(profile.getByTestId("profile-field-language")).toContainText("English"); await expect(profile.getByTestId("profile-field-locale")).toContainText("United States"); const focus = profile .getByTestId("user-fact") .filter({ hasText: "Wants help with day-to-day work first" }); await expect(focus).toContainText("Onboarding"); await expect(profile.getByTestId("user-facts-goals")).toContainText( "Wants help with day-to-day work first", ); const allergy = profile.getByTestId("user-fact").filter({ hasText: "Allergic to peanuts" }); await expect(allergy).toHaveAttribute("data-status", "pending"); await captureScreenshot(page, testInfo, "user-profile-pending"); await allergy.getByRole("button", { name: "Confirm" }).click(); await expect(allergy).toHaveAttribute("data-status", "active"); await expect(allergy.getByRole("button", { name: "Confirm" })).toHaveCount(0); await focus.getByRole("button", { name: "Delete" }).click(); await expect(focus).toHaveCount(0); await captureScreenshot(page, testInfo, "user-profile-settings"); const afterDelete = await rpc<{ facts: Array<{ value: string; status: string }> }>( page, "profile/get", null, ); expect(afterDelete.facts).toEqual( expect.not.arrayContaining([ expect.objectContaining({ value: "Wants help with day-to-day work first" }), ]), ); expect(afterDelete.facts).toContainEqual( expect.objectContaining({ value: "Allergic to peanuts", status: "active" }), ); await profile.getByRole("button", { name: "Forget everything" }).click(); await page.getByRole("alertdialog").getByRole("button", { name: "Forget", exact: true }).click(); await expect(profile).toHaveCount(0); expect(await rpc<{ facts: unknown[] }>(page, "profile/get", null)).toMatchObject({ facts: [] }); });