Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions apps/desktop/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ const withMakaRoot: Decorator = (Story, context) => {
// lines are ~1.8× the width of the Chinese copy, so a row that fits in zh
// overflows, truncates, or clips in en. Stories were locked to `zh`, which
// is exactly why those breakages only ever showed up in the shipped app.
const locale = context.globals.locale === 'en' ? 'en' : 'zh';
const locale =
context.globals.locale === 'en'
? 'en'
: context.globals.locale === 'zh-TW'
? 'zh-TW'
: 'zh-CN';

root.classList.toggle('dark', colorScheme === 'dark');
root.style.colorScheme = colorScheme;
Expand Down Expand Up @@ -96,7 +101,8 @@ const preview: Preview = {
toolbar: {
icon: 'globe',
items: [
{ title: '中文', value: 'zh' },
{ title: '简体中文', value: 'zh-CN' },
{ title: '繁體中文', value: 'zh-TW' },
{ title: 'English', value: 'en' },
],
},
Expand All @@ -114,7 +120,7 @@ const preview: Preview = {
},
initialGlobals: {
colorScheme: 'light',
locale: 'zh',
locale: 'zh-CN',
palette: 'default',
},
parameters: {
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/e2e/accessibility-coverage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ test('every settings page exposes named actionable controls', async ({ window: p
const sectionLabels = (await navigation.getByRole('button').allTextContents())
.map((label) => label.trim().replace(/\s*Beta$/, ''))
.filter((label) => label.length > 0 && label !== '返回应用');
const expectedSectionLabels = groupedNav('zh')
const expectedSectionLabels = groupedNav('zh-CN')
.flatMap(({ items }) => items)
.filter(({ enabled }) => enabled)
.map(({ label }) => label);
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/e2e/context-window-save.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import { expect, test } from './fixtures';
import { getProviderSettingsCopy } from '../src/renderer/features/connection-settings';

const copy = getProviderSettingsCopy('zh').detail;
const copy = getProviderSettingsCopy('zh-CN').detail;
const MODEL_ID = 'custom-reasoner';

test('one save persists a context window that is still focused', async ({
Expand Down
34 changes: 17 additions & 17 deletions apps/desktop/e2e/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ async function seedE2eConnection(userDataDir: string): Promise<void> {
}
}

async function seedE2eLocale(userDataDir: string, locale: 'zh' | 'en'): Promise<void> {
async function seedE2eLocale(userDataDir: string, locale: 'zh-CN' | 'zh-TW' | 'en'): Promise<void> {
const workspaceRoot = path.join(userDataDir, 'workspaces', 'default');
await createSettingsStore(workspaceRoot).update({
personalization: { uiLocale: locale },
Expand Down Expand Up @@ -426,7 +426,7 @@ async function withE2eWindow(
seed: boolean;
readinessSelector: string;
e2eFixtureScenario?: string;
locale?: 'zh' | 'en';
locale?: 'zh-CN' | 'zh-TW' | 'en';
/** Opt this window back into animated scrolling; see `scroll-motion-policy`. */
scrollMotion?: 'auto' | 'smooth';
/** #1312: force app:info's platform so the window boots natively into that platform's `data-os` cascade. */
Expand Down Expand Up @@ -603,7 +603,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
}, { scope: 'worker', auto: true }],
directoryReferenceWindow: async ({}, use) => {
await withE2eWindow(
{ seed: true, readinessSelector: COMPOSER_INPUT, locale: 'zh', showWindow: true },
{ seed: true, readinessSelector: COMPOSER_INPUT, locale: 'zh-CN', showWindow: true },
async (page, { userDataDir, app }) => {
const folder = path.join(userDataDir, 'referenced-source');
await mkdir(path.join(folder, 'nested'), { recursive: true });
Expand All @@ -620,15 +620,15 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
},
// Seeded: a pre-staged connection clears onboarding so the composer is ready.
window: async ({}, use) => {
await withE2eWindow({ seed: true, readinessSelector: COMPOSER_INPUT, locale: 'zh' }, use);
await withE2eWindow({ seed: true, readinessSelector: COMPOSER_INPUT, locale: 'zh-CN' }, use);
},
agentGraphWindow: async ({}, use) => {
await withE2eWindow(
{
seed: false,
readinessSelector: '.maka-agent-graph-panel',
e2eFixtureScenario: 'agent-graph-layout',
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
},
use,
Expand All @@ -638,7 +638,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
await withE2eWindow({
seed: false,
readinessSelector: '[data-maka-contract="onboarding-card"]',
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
}, use);
},
Expand All @@ -647,7 +647,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
{
seed: true,
readinessSelector: COMPOSER_INPUT,
locale: 'zh',
locale: 'zh-CN',
gitReviewExtraFiles: 0,
},
async (page, context) => {
Expand All @@ -663,7 +663,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
await withE2eWindow({
seed: true,
readinessSelector: COMPOSER_INPUT,
locale: 'zh',
locale: 'zh-CN',
invocableSkills: true,
}, use);
},
Expand All @@ -680,7 +680,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
await withE2eWindow({
seed: true,
readinessSelector: COMPOSER_INPUT,
locale: 'zh',
locale: 'zh-CN',
newTaskProject: true,
showWindow: true,
}, use);
Expand All @@ -694,15 +694,15 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
seed: false,
readinessSelector: '[data-maka-contract="search-modal"][open]',
e2eFixtureScenario: 'sidebar-search-modal-open',
locale: 'zh',
locale: 'zh-CN',
}, use);
},
parentRemovalWindow: async ({}, use) => {
await withE2eWindow(
{
seed: true,
readinessSelector: COMPOSER_INPUT,
locale: 'zh',
locale: 'zh-CN',
parentRemovalSessions: true,
},
use,
Expand All @@ -713,7 +713,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
{
seed: true,
readinessSelector: COMPOSER_INPUT,
locale: 'zh',
locale: 'zh-CN',
railRenderSessions: true,
},
use,
Expand All @@ -734,7 +734,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
// Every other fixture window names its locale; without one the renderer
// takes the host's, so any test that reaches a control by its label
// passes on a Chinese desktop and cannot find it on an English CI runner.
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
}, async (page, { app }) => {
const viewport = await page.evaluate(() => ({ width: innerWidth, height: innerHeight }));
Expand All @@ -760,7 +760,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
seed: false,
readinessSelector: '[data-turn-id]',
e2eFixtureScenario: 'chat-partial-history',
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
}, use);
},
Expand All @@ -773,7 +773,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
seed: false,
readinessSelector: '.settingsSurface',
e2eFixtureScenario: 'settings-models',
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
}, use);
},
Expand All @@ -782,7 +782,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
seed: false,
readinessSelector: '.settingsCapabilityGroup',
e2eFixtureScenario: 'settings-permissions',
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
}, use);
},
Expand All @@ -794,7 +794,7 @@ export const test = base.extend<E2eTestFixtures, E2eWorkerFixtures>({
seed: false,
readinessSelector: '[data-turn-id]',
e2eFixtureScenario: 'turn-narrative',
locale: 'zh',
locale: 'zh-CN',
showWindow: true,
}, use);
},
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/e2e/request-header-row-contract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { getProviderSettingsCopy } from '../src/renderer/features/connection-set
* surfaces as they first render, and this editor is three clicks deep.
*/

const copy = getProviderSettingsCopy('zh').detail;
const copy = getProviderSettingsCopy('zh-CN').detail;

test('the request header remove button centres on its field', async ({
requestHeaderRowWindow: page,
Expand Down
42 changes: 42 additions & 0 deletions apps/desktop/e2e/zh-tw-locale.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { ensureSidebarExpanded, expect, test } from './fixtures';

test('switches General Settings from Simplified to Traditional Chinese', async ({
window: page,
}) => {
await ensureSidebarExpanded(page);
await page.getByRole('button', { name: '设置', exact: true }).click();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Expand the sidebar before trying to open Settings. The shared window fixture explicitly starts with the navigation column collapsed (fixtures.ts:57-71), so this Settings button is not mounted. Running this exact spec on the current head times out here after 30 seconds; the Playwright snapshot shows only the titlebar and composer, and neither locale screenshot is written. Call the existing ensureSidebarExpanded(page) helper before this click (and again after reload if the remount collapses it), or use a fixture that opens Settings directly.

await expect(page.getByRole('main', { name: '设置内容' })).toBeVisible();
await page.getByRole('button', { name: '通用', exact: true }).click();
await expect(page.getByText('界面语言', { exact: true }).first()).toBeVisible();
await page.keyboard.press('Escape');

await page.evaluate(async () => {
await window.maka.settings.update({ personalization: { uiLocale: 'zh-TW' } });
});
await page.reload();
await page.waitForSelector('.maka-composer-editor');
await ensureSidebarExpanded(page);
await page.getByRole('button', { name: '設定', exact: true }).click();
await expect(page.getByRole('main', { name: '設定內容' })).toBeVisible();
await page.getByRole('button', { name: '通用', exact: true }).click();
await expect(page.getByText('介面語言', { exact: true }).first()).toBeVisible();
});
13 changes: 5 additions & 8 deletions apps/desktop/renderer-architecture.json
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@
"./locales/shell-copy.js": 1,
"@maka/core/redaction": 1
},
"importSpecifiers": 3,
"nonTriviaTokens": 515
"importSpecifiers": 2,
"nonTriviaTokens": 504
},
"src/renderer/app-shell-detail-panel.tsx": {
"importDeclarations": 0,
Expand Down Expand Up @@ -446,7 +446,7 @@
"nonTriviaTokens": 672
},
"src/renderer/app-shell-effects.ts": {
"importDeclarations": 13,
"importDeclarations": 12,
"bridgePaths": {
"window.maka.app.info": 1,
"window.maka.appWindow.subscribeCommand": 1,
Expand Down Expand Up @@ -492,12 +492,11 @@
"./theme": 1,
"./titlebar-modal-sync": 1,
"@astryxdesign/core/hooks": 1,
"@maka/core/redaction": 1,
"@maka/core/session-event-health": 1,
"react": 1
},
"importSpecifiers": 21,
"nonTriviaTokens": 3823
"importSpecifiers": 20,
"nonTriviaTokens": 3816
},
"src/renderer/app-shell-overlays.tsx": {
"importDeclarations": 8,
Expand Down Expand Up @@ -2920,7 +2919,6 @@
"./settings-expandable-row": 1,
"./settings-section": 1,
"./settings-skeleton.js": 1,
"@astryxdesign/core": 1,
"@maka/ui": 1,
"react": 1
}
Expand Down Expand Up @@ -3905,7 +3903,6 @@
"../features/connection-settings": 1,
"./oauth-login-flow-guard": 1,
"./runtime-host-settings-target.js": 1,
"@maka/core/redaction": 1,
"@maka/ui": 1,
"react": 1
}
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/main/__tests__/about-update-status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
} from '../../renderer/settings/about-update-status.js';
import { getSettingsPreferencesCopy } from '../../renderer/locales/settings-preferences-copy.js';

const copy = getSettingsPreferencesCopy('zh').about;
const copy = getSettingsPreferencesCopy('zh-CN').about;

test('a packaged nightly is tokened Nightly, never 正式版', () => {
const facts = aboutChannelFacts({ buildMode: 'packaged', updateChannel: 'nightly' }, copy);
Expand All @@ -47,7 +47,7 @@ test('buildMode decides before updateChannel, whose dev value is a placeholder',

test('the nightly steady states each read as themselves', () => {
const detail = (status: Parameters<typeof aboutUpdateStatusDetail>[0]) =>
aboutUpdateStatusDetail(status, copy);
aboutUpdateStatusDetail(status, copy, { isDevBuild: false });

assert.equal(
detail({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ describe('Boundary decisions notify the read model', () => {
function handlersWithRecorder() {
const boundaryChanges: string[] = [];
const handlers = createAppShellSessionEventHandlers({
uiLocale: 'zh',
uiLocale: 'zh-CN',
activeIdRef: { current: 'session-a' },
liveTurnBySessionRef: { current: {} },
refreshMessages: async () => true,
Expand Down
30 changes: 30 additions & 0 deletions apps/desktop/src/main/__tests__/agent-graph-panel-copy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import assert from 'node:assert/strict';
import { test } from 'node:test';
import { getAgentGraphPanelCopy } from '../../renderer/agent-graph-panel.js';

test('Traditional Chinese Agent Graph copy does not use Simplified fallbacks', () => {
const copy = getAgentGraphPanelCopy('zh-TW');
assert.equal(copy.loading, '正在讀取 Graph 狀態…');
assert.equal(copy.openSession, '開啟子任務');
assert.equal(copy.currentEpoch, '目前');
assert.equal(copy.status('active'), '執行中');
});
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ test('a stale in-memory default pointing at a retired connection is not testable
assert.ok(!ids.includes('diag:test-default'));
});

for (const locale of ['en', 'zh'] as const) {
for (const locale of ['en', 'zh-CN'] as const) {
test(`${locale} static shortcut hints preserve both platform variants`, () => {
const commands = buildCommandList({
locale,
Expand All @@ -111,6 +111,6 @@ for (const locale of ['en', 'zh'] as const) {
other: 'Ctrl+,',
});
assert.equal(byId.get('diag:copy-diagnostics')?.platformHint?.other, 'Ctrl+Shift+D · ' +
(locale === 'zh' ? '脱敏日志 · 仅写入剪贴板' : 'Redacted logs · clipboard only'));
(locale === 'zh-CN' ? '脱敏日志 · 仅写入剪贴板' : 'Redacted logs · clipboard only'));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ test('rebuilds an active Computer Use menu when its resolved locale changes', ()
assert.deepEqual(menus.at(-1)?.map((row) => row.label), ['Stop Using Safari']);

locale.observe(mergeSettings(createDefaultSettings(), {
personalization: { uiLocale: 'zh' },
personalization: { uiLocale: 'zh-CN' },
}));
assert.deepEqual(menus.at(-1)?.map((row) => row.label), ['停止操作 Safari']);

Expand Down
Loading