fix(locale): gate browser detection on window and tolerate a missing languages list

Node >= 21 exposes a global `navigator` reporting the machine's own language,
so gating detection on `navigator` let a non-browser boot of the client tree
resolve to `en` instead of the documented fallback; `window` is the browser
test. `navigator.languages` is spec-required but absent on some embedders and
older WebViews, where spreading it would throw at boot, so the walk tolerates
its absence and `navigator.language` covers that host.

The per-spec pin boilerplate collapses into one suite-level
`usePinnedBrowserLanguages('zh-CN')`, which owns the rationale in
dsh-client-test-runtime, and the English-browser e2e scenario now clears the
console warnings channel too — its page has no closing inventory spec.
This commit is contained in:
creatixchu
2026-07-31 15:49:59 +08:00
parent cb754a0319
commit e5563ae433
19 changed files with 84 additions and 76 deletions

View File

@@ -2,10 +2,10 @@
* locale service, declaration-aware Appearance row registration, snapshot
* projection into the row store, and HMR collapse recovery. */
import { Context } from 'cordis'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { describe, expect, it } from 'vitest'
import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client'
import { LocaleService } from '@deepseek-ai/dsh-client-locale/client'
import { pinBrowserLanguages } from '@deepseek-ai/dsh-client-test-runtime'
import { usePinnedBrowserLanguages } from '@deepseek-ai/dsh-client-test-runtime'
import { apply, inject, SETTINGS_NS } from '@deepseek-ai/dsh-client-ui-theme/client'
import type { AppearanceRowInjected, ThemeService } from '@deepseek-ai/dsh-client-ui-theme/client'
import { AppearanceRow } from '../src/client/AppearanceRow.tsx'
@@ -13,9 +13,7 @@ import type { createAppearanceRowStore } from '../src/client/settings-store.ts'
// The service reads its initial locale from the browser; these specs assert
// the shipped Chinese copy, so they state the browser they assume.
let restoreLanguages: () => void
beforeEach(() => { restoreLanguages = pinBrowserLanguages('zh-CN') })
afterEach(() => { restoreLanguages() })
usePinnedBrowserLanguages('zh-CN')
const SLOT = 'settings.general.item'