evOo-local/apps/web/e2e/smoke.spec.ts
Claude 8ae07cdf11
fix(web): use English Lingui sources for German UI text
Several web surfaces hard-coded German (the project card, roster and
activity status labels, the sidebar "Heute" label) or used German text as
the Lingui source message (sidebar sections, project timeline, bot picker,
voice entry, group stage, copy and read-aloud buttons). English users saw
German, and because production builds keep only message ids, none of these
strings could be translated per locale.

Convert them to English source messages, keeping the meaning:
- ProjectCreatedCard: Lingui Trans/Plural instead of literals.
- agent-activity: labels go through i18n._ with literal ids so the module
  stays importable from plain unit tests; the extractor still collects them.
- Shell, ProjectSessionTimeline, bot-picker, StageVoiceEntry, OoStage:
  English sources, reusing existing messages where one already fit
  ("just now", "{n}m ago", "Search", "No bots match", "Set up voice",
  "Group conversation", "Transcript").
- The conversation picker matches its create entry against the translated
  label instead of a fixed German string.

The German wording returns through the de catalog in the next commit.
Unit and E2E tests now assert the English labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
2026-10-03 13:22:37 +00:00

50 lines
1.5 KiB
TypeScript

/**
* Smoke test: verify the app loads without React errors.
*
* This test ensures that the Vite build resolves a single React
* instance (no duplicate React versions from pnpm transitive deps).
*/
import { expect, test } from "@playwright/test";
test("app loads without React hook errors", async ({ page }) => {
const consoleErrors: string[] = [];
const pageErrors: string[] = [];
page.on("console", (msg) => {
if (msg.type() === "error") consoleErrors.push(msg.text());
});
page.on("pageerror", (err) => {
pageErrors.push(err.message);
});
await page.goto("/app", { waitUntil: "domcontentloaded", timeout: 10_000 });
await page.waitForTimeout(5000);
// The critical check: no "Invalid hook call" or related React errors
const hookErrors = pageErrors.filter(
(error) =>
error.includes("Invalid hook call") ||
error.includes("useMemo") ||
error.includes("useRef") ||
error.includes("useContext") ||
error.includes("more than one copy of React"),
);
expect(hookErrors).toEqual([]);
// Root element must exist
await expect(page.locator("#root")).toBeAttached();
// Should show either login form or app content (not a blank/dark screen)
const bodyText = await page.evaluate(() => document.body?.innerText || "");
const hasContent =
bodyText.includes("Sign in") ||
bodyText.includes("Anmelden") ||
bodyText.includes("EvOo") ||
bodyText.includes("Projects") ||
bodyText.includes("Today") ||
bodyText.includes("Team");
expect(hasContent).toBe(true);
});