* Fix first-run onboarding UX: naming, locale, voices, Heute route, mobile drawer Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix biome import order and formatting Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix biome formatting on OoStage and E2E specs Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix E2E specs for onboarding name step and Heute reload route Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix German onboarding heading matcher in E2E Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix German signup E2E, Escape menu stacking, and Heute rhythm click Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Make onboarding E2E helpers locale-aware for German UI Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix completeOnboarding language skip for Skip · locale label Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Use language-step Skip · locale button in completeOnboarding Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix German E2E: Nachricht composer, voice loading wait, Heute rhythm Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Stabilize Heute reload URL and German voice E2E assertions Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Fix Heute bootstrap redirect and German onboarding voices When Kokoro lists no locale-matched voices, onboarding now uses offline presets instead of showing English-only options. Shell bootstrap skips bot redirects while the user is on /app/heute. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Relax German voice E2E name matching for voice labels Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Harden Heute route and German voice onboarding E2E Rebased onto main with Expo SDK 57 typecheck fixes. Voice options expose stable test ids; Shell keeps /app/heute across bootstrap and redirects legacy /app/heute bot URLs. Heute coach E2E asserts URL after reload. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> * Format Shell after Heute route helper Co-authored-by: cynarAI <cynarAI@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
88 lines
4.2 KiB
TypeScript
88 lines
4.2 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { completeOnboarding, rpc, signup } from "./helpers";
|
|
|
|
test("onboarding names the first Oo and shows it in chat", async ({ page }) => {
|
|
const stamp = Date.now();
|
|
await signup(page, `name-oo-${stamp}@rakazo.test`, "password12", "Namer");
|
|
await page.waitForURL(/\/onboarding/, { timeout: 20_000 });
|
|
await page.getByRole("button", { name: /^(Continue|Weiter)$/i }).click();
|
|
await expect(page.getByTestId("onboarding-name-step")).toBeVisible();
|
|
await page.getByTestId("onboarding-oo-name-input").fill("Luna");
|
|
await page
|
|
.getByTestId("onboarding-name-step")
|
|
.getByRole("button", { name: /^(Continue|Weiter)$/i })
|
|
.click();
|
|
await page.getByRole("button", { name: /^(Skip|Überspringen ·)/i }).click();
|
|
await page.getByRole("button", { name: /^(Skip|Überspringen)$/i }).click();
|
|
await expect(page).toHaveURL(/\/app\/g\/[^/]+/, { timeout: 30_000 });
|
|
await expect(
|
|
page.getByTestId("bot-settings-trigger").getByText("Luna", { exact: true }),
|
|
).toBeVisible();
|
|
expect((await rpc<{ name: string }>(page, "bots/ensureMain", {})).name).toBe("Luna");
|
|
});
|
|
|
|
test("German UI keeps Deutsch on language skip label", async ({ page }) => {
|
|
await page.addInitScript(() => {
|
|
Object.defineProperty(navigator, "language", { value: "de-DE", configurable: true });
|
|
localStorage.setItem("rakazo.uiLocale", "de");
|
|
});
|
|
const stamp = Date.now();
|
|
await signup(page, `de-skip-${stamp}@rakazo.test`, "password12", "Deutsch");
|
|
await page.getByRole("button", { name: /^(Continue|Weiter)$/i }).click();
|
|
await page.getByRole("button", { name: /^(Skip|Überspringen)$/i }).click();
|
|
await expect(
|
|
page.getByRole("heading", { name: /Wähle deine Sprache|Choose your language/i }),
|
|
).toBeVisible();
|
|
await expect(page.getByRole("button", { name: /Überspringen · Deutsch/i })).toBeVisible();
|
|
});
|
|
|
|
test("German voice step lists German voices after choosing Deutsch", async ({ page }) => {
|
|
await page.addInitScript(() => {
|
|
Object.defineProperty(navigator, "language", { value: "de-DE", configurable: true });
|
|
localStorage.setItem("rakazo.uiLocale", "de");
|
|
});
|
|
const stamp = Date.now();
|
|
await signup(page, `de-voice-${stamp}@rakazo.test`, "password12", "Stimme");
|
|
await page.getByRole("button", { name: /^(Continue|Weiter)$/i }).click();
|
|
await page.getByRole("button", { name: /^(Skip|Überspringen)$/i }).click();
|
|
await page.getByRole("button", { name: "Deutsch", exact: true }).click();
|
|
await expect(page.getByText(/Loading voices|Stimmen werden geladen/i)).toHaveCount(0, {
|
|
timeout: 30_000,
|
|
});
|
|
await expect(page.getByTestId("onboarding-voice-df_eva")).toBeVisible({ timeout: 30_000 });
|
|
await expect(page.getByTestId("onboarding-voice-dm_bernd")).toBeVisible();
|
|
await expect(page.getByTestId("onboarding-voice-af_alloy")).toHaveCount(0);
|
|
await expect(page.getByTestId("onboarding-voice-df_eva")).toHaveAttribute("aria-pressed", "true");
|
|
});
|
|
|
|
test("main conversation does not show a group subtitle for one Oo", async ({ page }) => {
|
|
await page.addInitScript(() => {
|
|
Object.defineProperty(navigator, "language", { value: "de-DE", configurable: true });
|
|
localStorage.setItem("rakazo.uiLocale", "de");
|
|
});
|
|
const stamp = Date.now();
|
|
await signup(page, `main-1-1-${stamp}@rakazo.test`, "password12", "Solo");
|
|
await completeOnboarding(page, undefined, { mainConversation: true });
|
|
await expect(page.getByTestId("bot-settings-trigger")).not.toContainText("Gruppenunterhaltung");
|
|
await expect(page.getByTestId("oo-group-stage")).toContainText(/1:1/i);
|
|
});
|
|
|
|
test.describe("mobile shell", () => {
|
|
test.use({
|
|
hasTouch: true,
|
|
isMobile: true,
|
|
viewport: { width: 390, height: 844 },
|
|
});
|
|
|
|
test("Escape closes the mobile navigation drawer", async ({ page }) => {
|
|
const stamp = Date.now();
|
|
await signup(page, `mobile-esc-${stamp}@rakazo.test`, "password12", "Escape");
|
|
await completeOnboarding(page);
|
|
await page.getByRole("button", { name: "Open navigation" }).click();
|
|
await expect(page.getByRole("button", { name: "Close navigation" })).toBeVisible();
|
|
await page.keyboard.press("Escape");
|
|
await expect(page.getByRole("button", { name: "Close navigation" })).toHaveCount(0);
|
|
await expect(page.getByTestId("open-navigation")).toBeFocused();
|
|
});
|
|
});
|