Compare commits

...
Author SHA1 Message Date
paseo-bot[bot] a0ac8aa63a Merge remote-tracking branch 'origin/main' into fix/zh-cn-untranslated-labels-1
# Conflicts:
#	packages/app/src/i18n/resources/zh-CN.ts
2026-10-13 21:43:53 +02:00
paseo-bot[bot] e7b2ec7757 test(app): narrow the composer last so no step races the layout remount
Crossing back from the mobile to the desktop breakpoint replaces the composer
textarea about 200ms later. The next step filled the composer during that
window on a slow CI runner and the new text landed before the old draft.
Narrowing is now the final step, so no action follows the layout switch.
2026-10-07 11:38:24 +02:00
paseo-bot[bot] 41d6e2b2bd chore: keep the Simplified Chinese QA screenshots out of the repository 2026-10-07 11:02:11 +02:00
paseo-bot[bot]andDillon 3926fdeb07 test(app): expect the completed Simplified Chinese labels
Four app tests that check the active language still expected the mixed
English and Chinese strings that #6118 replaced.

Co-authored-by: Dillon <dillonzq@outlook.com>
2026-10-07 11:00:29 +02:00
paseo-bot[bot] e4375f4c6d Merge remote-tracking branch 'origin/main' into fix/zh-cn-untranslated-labels
# Conflicts:
#	packages/app/src/i18n/resources/zh-CN.ts
2026-10-07 10:57:59 +02:00
Dillon 25c559fa6e fix(i18n): polish Chinese connection and pairing copy 2026-10-05 16:29:38 +08:00
Dillon ff99584c76 fix(i18n): distinguish Git stash from staging in Chinese 2026-10-05 16:23:08 +08:00
Dillon 56469934dd Merge branch 'main' into update-zh-i18n-upstream-pr 2026-10-05 16:15:32 +08:00
Dillon eb91f18683 fix(i18n): complete Simplified Chinese UI translations 2026-10-05 16:12:49 +08:00
9 changed files with 745 additions and 631 deletions
@@ -87,19 +87,6 @@ test("blank composer lines remain present and keep their measured height", async
const blankLines = "\n\n\n\n\n";
const collapsedHeight = await composerHeight(page);
await test.step("remeasure the current draft when the window narrows", async () => {
await page.setViewportSize({ width: 1280, height: 1200 });
const text = "A sentence that wraps when the editor becomes narrower. ".repeat(8);
await composer.fill(text);
await expect(composer).toHaveValue(text);
await expect.poll(() => composerHeight(page)).toBeGreaterThan(collapsedHeight);
const wideHeight = await composerHeight(page);
await page.setViewportSize({ width: 480, height: 1200 });
await expect.poll(() => composerHeight(page)).toBeGreaterThan(wideHeight);
await expect(composer).toHaveValue(text);
await page.setViewportSize({ width: 1280, height: 720 });
});
await test.step("grow the composer with blank lines followed by text", async () => {
await composer.fill(`${blankLines}x`);
await expect(composer).toHaveValue(`${blankLines}x`);
@@ -123,6 +110,18 @@ test("blank composer lines remain present and keep their measured height", async
await expect(composer).toHaveValue("alpha\nbeta\nx");
expect(filledTrailingLineHeight).toBe(trailingLineHeight);
});
await test.step("remeasure the current draft when the window narrows", async () => {
await page.setViewportSize({ width: 1280, height: 1200 });
const text = "A sentence that wraps when the editor becomes narrower. ".repeat(8);
await composer.fill(text);
await expect(composer).toHaveValue(text);
await expect.poll(() => composerHeight(page)).toBeGreaterThan(collapsedHeight);
const wideHeight = await composerHeight(page);
await page.setViewportSize({ width: 480, height: 1200 });
await expect.poll(() => composerHeight(page)).toBeGreaterThan(wideHeight);
await expect(composer).toHaveValue(text);
});
} finally {
await agent.cleanup();
}
@@ -15,6 +15,13 @@ test("Settings language selector switches General labels", async ({ page }) => {
await page.getByRole("menuitem", { name: "简体中文 - Simplified Chinese", exact: true }).click();
await expect(page.getByText("默认发送", { exact: true }).first()).toBeVisible();
await expect(page.getByText(/智能体运行时,Enter/).first()).toBeVisible();
const screenshotPath = test.info().outputPath("simplified-chinese-settings.png");
await page.screenshot({ path: screenshotPath, fullPage: true });
await test.info().attach("simplified-chinese-settings", {
path: screenshotPath,
contentType: "image/png",
});
await page.getByRole("button", { name: "简体中文", exact: true }).click();
await page.getByRole("menuitem", { name: "English - 英语", exact: true }).click();
@@ -474,7 +474,7 @@ describe("formatStatusText", () => {
formatVersion,
formatLastCheckedAt,
}),
).toBe("正在检查 app 更新...");
).toBe("正在检查应用更新...");
expect(
formatStatusText({
status: "available",
+4 -4
View File
@@ -755,13 +755,13 @@ describe("git-actions-policy", () => {
expect(actions.primary).toMatchObject({
id: "pull",
label: "Pull",
pendingLabel: "正在 pull...",
successLabel: "已 pull",
label: "拉取",
pendingLabel: "正在拉取...",
successLabel: "已拉取",
});
expect(actions.secondary.find((entry) => entry.id === "pr")).toMatchObject({
label: "创建 PR",
unavailableMessage: "无法创建 PR,因为此分支还没有新的 commit",
unavailableMessage: "无法创建 PR,因为此分支还没有新的提交",
});
});
+49 -1
View File
@@ -168,6 +168,32 @@ describe("translation resources", () => {
expect(countMatchingEnglishStrings(zhCN)).toBeLessThan(maxFallbackStrings);
});
it("limits Chinese English matches to names, identifiers, and command examples", () => {
const englishStrings = flattenStrings(en);
const chineseStrings = flattenStrings(zhCN);
const matchingKeys = Object.entries(englishStrings)
.filter(([key, value]) => chineseStrings[key] === value)
.map(([key]) => key)
.sort();
expect(matchingKeys).toEqual(
[
"sidebar.help.discord",
"sidebar.help.appName",
"desktop.daemon.status.pid",
"settings.general.language.options.en",
"settings.appearance.theme.options.zinc",
"settings.appearance.theme.options.midnight",
"settings.appearance.theme.options.claude",
"settings.appearance.theme.options.ghostty",
"settings.host.appearance.preview.workspaceName",
"settings.host.terminalProfiles.namePlaceholder",
"settings.host.terminalProfiles.commandPlaceholder",
"settings.host.terminalProfiles.argsPlaceholder",
].sort(),
);
});
it("localizes the pull request empty state in every supported language", () => {
for (const resource of [ar, es, fr, ja, ko, ptBR, ru, zhCN]) {
expect(resource.panels.pullRequest.emptyTitle).not.toBe(en.panels.pullRequest.emptyTitle);
@@ -177,6 +203,28 @@ describe("translation resources", () => {
}
});
it("distinguishes Git stashing from staging in Chinese action and restore guidance", () => {
const unavailable = zhCN.workspace.git.actions.unavailable;
const branchSwitcher = zhCN.branchSwitcher;
const stashGuidance = [
unavailable.pullDirty,
unavailable.pullAndPushDirty,
unavailable.mergeDirty,
unavailable.updateDirty,
branchSwitcher.uncommittedMessage,
branchSwitcher.stashAndSwitch,
branchSwitcher.failedToStash,
branchSwitcher.restoreStashTitle,
branchSwitcher.restoreStashMessage,
branchSwitcher.stashRestored,
];
for (const label of stashGuidance) {
expect(label).toContain("贮藏(stash)");
expect(label).not.toContain("暂存");
}
});
it("preserves interpolation placeholders in every language", () => {
expect(findInterpolationMismatches(ar)).toEqual([]);
expect(findInterpolationMismatches(es)).toEqual([]);
@@ -214,7 +262,7 @@ describe("translation resources", () => {
expect(ja.settings.providers.models.many).toBe("{{count}}つのモデル");
expect(ptBR.settings.providers.models.many).toBe("{{count}} modelos");
expect(ru.settings.providers.models.many).toBe("{{count}} моделей");
expect(zhCN.settings.providers.models.many).toBe("{{count}} 个 Model");
expect(zhCN.settings.providers.models.many).toBe("{{count}} 个模型");
});
it("preserves reviewed Korean status labels", () => {
@@ -396,7 +396,15 @@ export const pluginSettings = {
},
},
"zh-CN": {
...shared,
logs: {
action: "日志",
title: "日志:{{id}}",
loading: "正在加载日志…",
refresh: "刷新",
refreshing: "正在刷新…",
errorTitle: "无法加载插件日志",
empty: "暂无插件输出",
},
screens: {
open: "打开",
offline: "连接到此主机以打开插件设置。",
File diff suppressed because it is too large Load Diff
@@ -56,12 +56,12 @@ describe("buildDraftPanelDescriptor", () => {
});
expect(idleDescriptor).toMatchObject({
label: "新建 Agent",
subtitle: "新建 Agent",
label: "新建智能体",
subtitle: "新建智能体",
});
expect(creatingDescriptor).toMatchObject({
label: "新建 Agent",
subtitle: "正在创建 Agent",
label: "新建智能体",
subtitle: "正在创建智能体",
});
await i18n.changeLanguage("en");
});
@@ -428,7 +428,7 @@ describe("combined model selector data", () => {
workspaceDirectory: "/repo",
hasClient: true,
}),
).toEqual({ ok: false, reason: "初始 prompt 必填" });
).toEqual({ ok: false, reason: "初始提示词必填" });
} finally {
await i18n.changeLanguage("en");
}