mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-30 01:06:11 +00:00
test(ui): cover overview locale startup selection
This commit is contained in:
@@ -102,6 +102,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Control UI/model switching: preserve the selected provider prefix when switching models from the chat dropdown, so multi-provider setups no longer send `anthropic/gpt-5.2`-style mismatches when the user picked `openai/gpt-5.2`. (#47581) Thanks @chrishham.
|
||||
- Control UI/storage: scope persisted settings keys by gateway base path, with migration from the legacy shared key, so multiple gateways under one domain stop overwriting each other's dashboard preferences. (#47932) Thanks @bobBot-claw.
|
||||
- Agents/usage tracking: stop forcing `supportsUsageInStreaming: false` on non-native OpenAI-completions providers so compatible backends report token usage and cost again instead of showing all zeros. (#46500) Fixes #46142. Thanks @ademczuk.
|
||||
- Control UI/overview: keep the language dropdown aligned with the persisted locale during dashboard startup so refreshing the page does not fall back to English before locale hydration completes. (#48019) Thanks @git-jxj.
|
||||
|
||||
## 2026.3.13
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { render } from "lit";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { i18n } from "../../i18n/index.ts";
|
||||
import { getSafeLocalStorage } from "../../local-storage.ts";
|
||||
import { renderChatSessionSelect } from "../app-render.helpers.ts";
|
||||
import type { AppViewState } from "../app-view-state.ts";
|
||||
@@ -9,6 +10,7 @@ import type { GatewayBrowserClient } from "../gateway.ts";
|
||||
import type { ModelCatalogEntry } from "../types.ts";
|
||||
import type { SessionsListResult } from "../types.ts";
|
||||
import { renderChat, type ChatProps } from "./chat.ts";
|
||||
import { renderOverview, type OverviewProps } from "./overview.ts";
|
||||
|
||||
function createSessions(): SessionsListResult {
|
||||
return {
|
||||
@@ -195,6 +197,57 @@ function createProps(overrides: Partial<ChatProps> = {}): ChatProps {
|
||||
};
|
||||
}
|
||||
|
||||
function createOverviewProps(overrides: Partial<OverviewProps> = {}): OverviewProps {
|
||||
return {
|
||||
connected: false,
|
||||
hello: null,
|
||||
settings: {
|
||||
gatewayUrl: "",
|
||||
token: "",
|
||||
sessionKey: "main",
|
||||
lastActiveSessionKey: "main",
|
||||
theme: "claw",
|
||||
themeMode: "system",
|
||||
chatFocusMode: false,
|
||||
chatShowThinking: true,
|
||||
chatShowToolCalls: true,
|
||||
splitRatio: 0.6,
|
||||
navCollapsed: false,
|
||||
navWidth: 220,
|
||||
navGroupsCollapsed: {},
|
||||
locale: "en",
|
||||
},
|
||||
password: "",
|
||||
lastError: null,
|
||||
lastErrorCode: null,
|
||||
presenceCount: 0,
|
||||
sessionsCount: null,
|
||||
cronEnabled: null,
|
||||
cronNext: null,
|
||||
lastChannelsRefresh: null,
|
||||
usageResult: null,
|
||||
sessionsResult: null,
|
||||
skillsReport: null,
|
||||
cronJobs: [],
|
||||
cronStatus: null,
|
||||
attentionItems: [],
|
||||
eventLog: [],
|
||||
overviewLogLines: [],
|
||||
showGatewayToken: false,
|
||||
showGatewayPassword: false,
|
||||
onSettingsChange: () => undefined,
|
||||
onPasswordChange: () => undefined,
|
||||
onSessionKeyChange: () => undefined,
|
||||
onToggleGatewayTokenVisibility: () => undefined,
|
||||
onToggleGatewayPasswordVisibility: () => undefined,
|
||||
onConnect: () => undefined,
|
||||
onRefresh: () => undefined,
|
||||
onNavigate: () => undefined,
|
||||
onRefreshLogs: () => undefined,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("chat view", () => {
|
||||
it("uses the assistant avatar URL for the welcome state when the identity avatar is only initials", () => {
|
||||
const container = document.createElement("div");
|
||||
@@ -285,6 +338,41 @@ describe("chat view", () => {
|
||||
expect(groupedLogo?.getAttribute("src")).toBe("/openclaw/favicon.svg");
|
||||
});
|
||||
|
||||
it("keeps the persisted overview locale selected before i18n hydration finishes", async () => {
|
||||
const container = document.createElement("div");
|
||||
const props = createOverviewProps({
|
||||
settings: {
|
||||
...createOverviewProps().settings,
|
||||
locale: "zh-CN",
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
localStorage.clear();
|
||||
} catch {
|
||||
/* noop */
|
||||
}
|
||||
await i18n.setLocale("en");
|
||||
|
||||
render(renderOverview(props), container);
|
||||
await Promise.resolve();
|
||||
|
||||
let select = container.querySelector<HTMLSelectElement>("select");
|
||||
expect(i18n.getLocale()).toBe("en");
|
||||
expect(select?.value).toBe("zh-CN");
|
||||
expect(select?.selectedOptions[0]?.textContent?.trim()).toBe("简体中文 (Simplified Chinese)");
|
||||
|
||||
await i18n.setLocale("zh-CN");
|
||||
render(renderOverview(props), container);
|
||||
await Promise.resolve();
|
||||
|
||||
select = container.querySelector<HTMLSelectElement>("select");
|
||||
expect(select?.value).toBe("zh-CN");
|
||||
expect(select?.selectedOptions[0]?.textContent?.trim()).toBe("简体中文 (简体中文)");
|
||||
|
||||
await i18n.setLocale("en");
|
||||
});
|
||||
|
||||
it("renders compacting indicator as a badge", () => {
|
||||
const container = document.createElement("div");
|
||||
render(
|
||||
|
||||
Reference in New Issue
Block a user