The profile had its own settings tab although it is a few rows of personal details. It now sits as one card under Account in General, hides itself while empty, and the separate tab is gone. Claude-Session: https://claude.ai/code/session_017gHYZ4c9Twex73v4ZasmMJ Co-authored-by: Claude <noreply@anthropic.com>
105 lines
4.6 KiB
TypeScript
105 lines
4.6 KiB
TypeScript
/**
|
|
* 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<Array<{ instructions: string }>>(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: [] });
|
|
});
|