Files
aiturk-hermes-ide/apps/desktop/e2e/turkish-settings.spec.ts
T

137 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { execFileSync } from 'node:child_process'
import * as path from 'node:path'
import { type MockBackendFixture, setupMockBackend, waitForAppReady } from './fixtures'
import { expect, test } from './test'
let fixture: MockBackendFixture | null = null
type DesktopTestWindow = Window & {
hermesDesktop: {
api<T = unknown>(request: { path: string }): Promise<T>
setUiLanguage(locale: string): void
selectSavePath(options?: { title?: string; defaultPath?: string }): Promise<string | null>
}
}
test.beforeAll(async () => {
test.setTimeout(150_000)
fixture = await setupMockBackend({ extraDisplayConfig: ' language: tr' })
await waitForAppReady(fixture, 120_000)
await expect
.poll(
async () => {
const status = await fixture!.page.evaluate(() =>
(window as unknown as DesktopTestWindow).hermesDesktop.api({ path: '/api/status' })
)
return Boolean(status)
},
{ timeout: 30_000 }
)
.toBe(true)
})
test.afterAll(async () => {
await fixture?.cleanup()
fixture = null
})
test('Turkish safety settings persist the backend enum through the real desktop bridge', async () => {
const { page, sandbox } = fixture!
await page.evaluate(() => {
window.location.hash = '/settings?tab=config%3Asafety'
})
await expect(page.getByText('Gizli bilgileri maskele', { exact: true })).toBeVisible()
await expect(
page.getByText('Algılanan gizli bilgileri mümkün olduğunda modelin görebildiği içerikten gizler.', { exact: true })
).toBeVisible()
const approvals = page.locator('[data-tour="field-approvals.mode"]')
await approvals.getByRole('combobox').click()
await page.getByRole('option', { name: 'Elle onayla', exact: true }).click()
await expect
.poll(
async () => {
const config = await page.evaluate(() =>
(window as unknown as DesktopTestWindow).hermesDesktop.api<Record<string, unknown>>({ path: '/api/config' })
)
return (config.approvals as { mode?: string } | undefined)?.mode
},
{ timeout: 30_000 }
)
.toBe('manual')
await expect
.poll(
() => {
return execFileSync(
process.env.HERMES_DESKTOP_PYTHON || 'python',
[
'-c',
'import pathlib, sys, yaml; print(yaml.safe_load(pathlib.Path(sys.argv[1]).read_text(encoding="utf-8")).get("approvals", {}).get("mode", ""))',
path.join(sandbox.hermesHome, 'config.yaml')
],
{ encoding: 'utf8' }
).trim()
},
{ timeout: 15_000 }
)
.toBe('manual')
await expect(approvals.getByRole('combobox')).toContainText('Elle onayla')
await page.screenshot({ path: test.info().outputPath('turkish-safety-settings.png'), fullPage: true })
})
test('native language bridge updates the Mac menu and preserves menu-free Windows', async () => {
const { app, page } = fixture!
const platform = await app.evaluate(() => process.platform)
for (const locale of ['en', 'tr']) {
await page.evaluate(language => {
;(window as unknown as DesktopTestWindow).hermesDesktop.setUiLanguage(language)
}, locale)
await expect
.poll(() => app.evaluate(({ Menu }) => Menu.getApplicationMenu()?.items.map((item: { label: string }) => item.label) ?? null))
.toEqual(
platform === 'darwin'
? expect.arrayContaining([locale === 'tr' ? 'Dosya' : 'File', locale === 'tr' ? 'Düzen' : 'Edit'])
: null
)
}
})
test('native save dialog follows language while preserving caller title and path', async () => {
const { app, page } = fixture!
await app.evaluate(({ dialog }) => {
const state = globalThis as typeof globalThis & { originalSave?: unknown; saveOptions?: unknown }
state.originalSave = dialog.showSaveDialog
dialog.showSaveDialog = async (_parent: unknown, options: unknown) => {
state.saveOptions = options
return { canceled: true, filePath: '' }
}
})
try {
for (const locale of ['tr', 'en']) {
const result = await page.evaluate(async language => {
const bridge = (window as unknown as DesktopTestWindow).hermesDesktop
bridge.setUiLanguage(language)
return bridge.selectSavePath({ defaultPath: 'My custom archive.zip' })
}, locale)
expect(result).toBeNull()
const options = await app.evaluate(() => (globalThis as typeof globalThis & { saveOptions?: unknown }).saveOptions)
expect(options).toMatchObject({ title: locale === 'tr' ? 'Kaydet' : 'Save', defaultPath: 'My custom archive.zip' })
}
await page.evaluate(async () => {
const bridge = (window as unknown as DesktopTestWindow).hermesDesktop
bridge.setUiLanguage('tr')
await bridge.selectSavePath({ title: 'My custom title' })
})
expect(await app.evaluate(() => (globalThis as typeof globalThis & { saveOptions?: unknown }).saveOptions))
.toMatchObject({ title: 'My custom title' })
} finally {
await app.evaluate(({ dialog }) => {
const state = globalThis as typeof globalThis & { originalSave?: typeof dialog.showSaveDialog; saveOptions?: unknown }
dialog.showSaveDialog = state.originalSave!
delete state.originalSave
delete state.saveOptions
})
}
})