evOo-local/apps/web/e2e/onboarding-emoji-first.spec.ts
Ingo Wagner a570e9e71b feat: complete onboarding redesign + major file splits
Onboarding: emoji-first flow with shape/color selection, user preferences,
language setup (9 locales), and bot creation with avatarValue persistence.

executor.ts: split 4928→4159 lines into 8 modules (completion, computer,
effects, model, utils, tools, attachments, types).

pi-runtime.ts: split 1726→561 lines into 2 modules (model-config, tool-utils).

E2E: new onboarding-emoji-first tests + updated completeOnboarding helper.
2026-09-21 22:52:04 +00:00

159 lines
5.2 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
captureScreenshot,
completeOnboarding,
signup,
} from "./helpers";
/**
* E2E test for the new emoji-first onboarding flow:
* 1. Sign up → lands on onboarding
* 2. Design Oo: pick shape + color → live preview
* 3. Tell us about yourself: name, timezone, hobbies, work style, communication
* 4. Choose language
* 5. Skip integrations → bot created → land in chat
*/
test("emoji-first onboarding: shape + color selection with live preview", async ({
page,
}, testInfo) => {
const stamp = Date.now();
await signup(page, `emoji-${stamp}@rakazo.test`, "password12", "TestUser");
// Should land on onboarding page
await page.waitForURL(/\/(onboarding|app)/, { timeout: 20_000 });
// Step 1: Design your Oo
await expect(
page.getByRole("heading", { name: /Design your Oo/i }),
).toBeVisible();
if (testInfo) await captureScreenshot(page, testInfo, "01-design-your-oo");
// Live preview should show a BotAvatar
const preview = page.locator('[data-rakazo-surface="onboarding"]');
await expect(preview).toBeVisible();
// Shape selection grid should have 8 options
const shapeButtons = page.locator('[aria-pressed]');
// Click the 4th shape (index 3)
const shapes = page.locator('[data-testid*="shape"] , button:has(svg)');
if (await shapes.count()) {
await shapes.nth(3).click();
}
// Color selection: click the 3rd color swatch
const colorSwatches = page.locator("button[aria-label^=Color]");
if (await colorSwatches.count()) {
await colorSwatches.nth(2).click();
}
// Verify the preview updated (the BotAvatar should reflect the new color)
const botAvatar = page.locator('[data-rakazo-surface="onboarding"] svg');
await expect(botAvatar).toBeVisible();
if (testInfo) await captureScreenshot(page, testInfo, "02-shape-color-preview");
// Click Continue → goes to preferences step
await page.getByRole("button", { name: /Continue/i }).first().click();
// Step 2: Tell us about yourself
await expect(
page.getByRole("heading", { name: /Tell us about yourself/i }),
).toBeVisible();
if (testInfo) await captureScreenshot(page, testInfo, "03-user-preferences");
// Fill in name
await page.getByPlaceholder(/Your name/i).fill("Alice");
// Fill in timezone
await page.getByPlaceholder(/Timezone/i).fill("Europe/Vienna");
// Select a hobby
const hobbyButtons = page.locator("button[aria-pressed]");
if (await hobbyButtons.count()) {
await hobbyButtons.first().click(); // toggle first hobby
}
// Select work style
const workStyleButtons = page.locator('button[aria-pressed]:visible');
if (await workStyleButtons.count() >= 2) {
await workStyleButtons.nth(0).click();
}
// Select communication style
const commButtons = page.locator('button[aria-pressed]:visible');
if (await commButtons.count() >= 2) {
await commButtons.nth(0).click();
}
if (testInfo) await captureScreenshot(page, testInfo, "04-preferences-filled");
// Click Continue → goes to language step
await page.getByRole("button", { name: /Continue/i }).first().click();
// Step 3: Language selection
await expect(
page.getByRole("heading", { name: /Choose your language/i }),
).toBeVisible();
if (testInfo) await captureScreenshot(page, testInfo, "05-language-step");
// Select Deutsch
await page.getByRole("button", { name: /Deutsch/ }).click();
// Should go to integrations or bot creation
// Either skip integrations or go directly to bot creation
const chief = page.getByText("Chief").first();
const integrationsHeading = page.getByRole("heading", {
name: /Server integrations/i,
});
await integrationsHeading.or(chief).or(
page.getByText("Opening chat…"),
).waitFor({ timeout: 20_000 });
if (testInfo) await captureScreenshot(page, testInfo, "06-integrations-or-bot");
// If integrations shown, skip
if (await integrationsHeading.isVisible().catch(() => false)) {
await page.getByRole("button", { name: "Skip", exact: true }).click();
}
await page.waitForURL(/\/app\//, { timeout: 20_000 });
await expect(chief).toBeVisible();
if (testInfo) await captureScreenshot(page, testInfo, "07-onboarding-complete");
});
test("onboarding: skip language defaults to English", async ({
page,
}, testInfo) => {
const stamp = Date.now();
await signup(page, `lang-skip-${stamp}@rakazo.test`, "password12", "Skipper");
await page.waitForURL(/\/(onboarding|app)/, { timeout: 20_000 });
// Go through emoji step quickly (just click continue)
await expect(
page.getByRole("heading", { name: /Design your Oo/i }),
).toBeVisible();
await page.getByRole("button", { name: /Continue/i }).first().click();
// Preferences step — just continue
await expect(
page.getByRole("heading", { name: /Tell us about yourself/i }),
).toBeVisible();
await page.getByRole("button", { name: /Continue/i }).first().click();
// Language step — click Skip
await expect(
page.getByRole("heading", { name: /Choose your language/i }),
).toBeVisible();
await page.getByRole("button", { name: /Skip/i }).click();
// Should land in bot chat
await page.waitForURL(/\/app\//, { timeout: 20_000 });
await expect(page.getByText("Chief").first()).toBeVisible();
});