diff --git a/frontend/__tests__/components/features/home/home-header.test.tsx b/frontend/__tests__/components/features/home/home-header.test.tsx index befb348931..a762b2f150 100644 --- a/frontend/__tests__/components/features/home/home-header.test.tsx +++ b/frontend/__tests__/components/features/home/home-header.test.tsx @@ -8,6 +8,29 @@ import userEvent from "@testing-library/user-event"; import { HomeHeader } from "#/components/features/home/home-header"; import OpenHands from "#/api/open-hands"; +// Mock the translation function +vi.mock("react-i18next", async () => { + const actual = await vi.importActual("react-i18next"); + return { + ...actual, + useTranslation: () => ({ + t: (key: string) => { + // Return a mock translation for the test + const translations: Record = { + "HOME$LETS_START_BUILDING": "Let's start building", + "HOME$LAUNCH_FROM_SCRATCH": "Launch from Scratch", + "HOME$LOADING": "Loading...", + "HOME$OPENHANDS_DESCRIPTION": "OpenHands is an AI software engineer", + "HOME$NOT_SURE_HOW_TO_START": "Not sure how to start?", + "HOME$READ_THIS": "Read this" + }; + return translations[key] || key; + }, + i18n: { language: "en" }, + }), + }; +}); + const renderHomeHeader = () => { const RouterStub = createRoutesStub([ { @@ -38,7 +61,7 @@ describe("HomeHeader", () => { renderHomeHeader(); const launchButton = screen.getByRole("button", { - name: /launch from scratch/i, + name: /Launch from Scratch/i, }); await userEvent.click(launchButton); @@ -60,11 +83,11 @@ describe("HomeHeader", () => { renderHomeHeader(); const launchButton = screen.getByRole("button", { - name: /launch from scratch/i, + name: /Launch from Scratch/i, }); await userEvent.click(launchButton); - expect(launchButton).toHaveTextContent(/Loading/i); + expect(launchButton).toHaveTextContent(/Loading.../i); expect(launchButton).toBeDisabled(); }); }); diff --git a/frontend/__tests__/utils/check-hardcoded-strings.test.tsx b/frontend/__tests__/utils/check-hardcoded-strings.test.tsx index 4889281bfd..33995c0ddb 100644 --- a/frontend/__tests__/utils/check-hardcoded-strings.test.tsx +++ b/frontend/__tests__/utils/check-hardcoded-strings.test.tsx @@ -19,7 +19,11 @@ describe("Check for hardcoded English strings", () => { const text = container.textContent; // List of English strings that should be translated - const hardcodedStrings = ["What do you want to build?"]; + const hardcodedStrings = [ + "What do you want to build?", + "Launch from Scratch", + "Read this" + ]; // Check each string hardcodedStrings.forEach((str) => { diff --git a/frontend/__tests__/utils/check-home-hardcoded-strings.test.tsx b/frontend/__tests__/utils/check-home-hardcoded-strings.test.tsx new file mode 100644 index 0000000000..a9470fdd2c --- /dev/null +++ b/frontend/__tests__/utils/check-home-hardcoded-strings.test.tsx @@ -0,0 +1,42 @@ +import { render } from "@testing-library/react"; +import { test, expect, describe, vi } from "vitest"; +import { HomeHeader } from "#/components/features/home/home-header"; + +// Mock dependencies +vi.mock("#/hooks/mutation/use-create-conversation", () => ({ + useCreateConversation: () => ({ + mutate: vi.fn(), + isPending: false, + isSuccess: false, + }), +})); + +vi.mock("#/hooks/use-is-creating-conversation", () => ({ + useIsCreatingConversation: () => false, +})); + +vi.mock("react-i18next", () => ({ + useTranslation: () => ({ + t: (key: string) => key, + }), +})); + +describe("Check for hardcoded English strings in Home components", () => { + test("HomeHeader should not have hardcoded English strings", () => { + const { container } = render(); + + // Get all text content + const text = container.textContent; + + // List of English strings that should be translated + const hardcodedStrings = [ + "Launch from Scratch", + "Read this", + ]; + + // Check each string + hardcodedStrings.forEach((str) => { + expect(text).not.toContain(str); + }); + }); +}); \ No newline at end of file diff --git a/frontend/src/components/features/home/home-header.tsx b/frontend/src/components/features/home/home-header.tsx index ea60c65036..176421c9ce 100644 --- a/frontend/src/components/features/home/home-header.tsx +++ b/frontend/src/components/features/home/home-header.tsx @@ -31,7 +31,7 @@ export function HomeHeader() { onClick={() => createConversation({})} isDisabled={isCreatingConversation} > - {!isCreatingConversation && "Launch from Scratch"} + {!isCreatingConversation && t("HOME$LAUNCH_FROM_SCRATCH")} {isCreatingConversation && t("HOME$LOADING")} @@ -48,7 +48,7 @@ export function HomeHeader() { rel="noopener noreferrer" className="underline underline-offset-2" > - Read this + {t("HOME$READ_THIS")}

diff --git a/frontend/src/i18n/translation.json b/frontend/src/i18n/translation.json index f2d01274c5..45ba9821a4 100644 --- a/frontend/src/i18n/translation.json +++ b/frontend/src/i18n/translation.json @@ -1,4 +1,36 @@ { + "HOME$LAUNCH_FROM_SCRATCH": { + "en": "Launch from Scratch", + "ja": "ゼロから始める", + "zh-CN": "从零开始", + "zh-TW": "從零開始", + "ko-KR": "처음부터 시작", + "no": "Start fra bunnen", + "it": "Inizia da zero", + "pt": "Começar do zero", + "es": "Comenzar desde cero", + "ar": "البدء من الصفر", + "fr": "Démarrer de zéro", + "tr": "Sıfırdan başla", + "de": "Von Grund auf starten", + "uk": "Почати з нуля" + }, + "HOME$READ_THIS": { + "en": "Read this", + "ja": "こちらを読む", + "zh-CN": "阅读此内容", + "zh-TW": "閱讀此內容", + "ko-KR": "이것을 읽어보세요", + "no": "Les dette", + "it": "Leggi questo", + "pt": "Leia isto", + "es": "Leer esto", + "ar": "اقرأ هذا", + "fr": "Lire ceci", + "tr": "Bunu oku", + "de": "Lies dies", + "uk": "Прочитайте це" + }, "AUTH$LOGGING_BACK_IN": { "en": "Logging back into OpenHands...", "ja": "OpenHandsに再ログインしています...",