Files
deepseek-harness/packages/client/test-runtime
creatixchu cb754a0319 feat(locale): derive the initial Settings language from the browser
A first visit resolved to Chinese regardless of the browser: LocaleService
read `dsh.locale` and fell straight back to `zh` when nothing was stored,
ignoring the languages the browser already states it reads.

The initial locale now resolves through three ordered sources — the persisted
preference, then `navigator` (first entry of the ordered language list whose
primary subtag names a shipped locale, so `zh-Hans-CN` -> zh and `en-GB` ->
en), then `FALLBACK_LOCALE`. An explicit choice still wins and nothing writes
the detected locale back to storage, so "has the user chosen?" stays a
question only the stored value answers.

Specs asserting the shipped Chinese copy now state the browser they assume:
the web e2e scenarios open their page with `locale: ZH_BROWSER_LOCALE`, and
package specs pin it through the new `pinBrowserLanguages` test helper.
`settings-chrome.e2e.ts` gains an English-browser scenario as the
assembled-app proof.
2026-07-31 15:26:46 +08:00
..

@deepseek-ai/dsh-client-test-runtime

English | 中文

jsdom slot test runtime for client feature specs: a real Cordis Context, the production SlotsService and web-react renderer, assembled around typed session/workspace doubles. Feature suites exercise declaration, registration, scope, store, inject, rendering, updates, and disposal without hand-building the machinery per suite — and without a second implementation of any production logic.

The doubles implement the same outward faces features receive through ctx (TestSessions implements ISessions, TestWorkspaces implements IWorkspaces; each fixture session is a FixtureSession implements SessionFace), so a production face change breaks the bench at compile time instead of silently drifting. Provide-bundle materialization runs the production SessionProvideChannel — the one implementation shared with SessionsService. Fixtures feed plain data: list rows, conversation snapshots (immer-patched via updateSnapshot), projection values, and ISession-typed behavior stubs that fail loud when a spec calls an unstubbed verb. The typed provide() constrains fakes for declared service names to Partial of that service's outward face.

Local DOM snapshots: declare(children) registers an auto frame whose per-key <div data-slot> wrappers are snapshot roots; renderSlot(key, owner) returns the slot-local view (container, scoped Testing Library queries, in-place update(owner)); a registered snapshot serializer folds CSS-module class hashes (_frame_a1b2c3frame) to keep .snap files structural and collapses <svg> internals to a data-content fingerprint. Suites needing a custom page frame use root.declare(children, Frame) instead; mount(plugin) runs a real fiber with fail-loud service prechecks, and dispose() tears down views, feature fibers, minted scopes, and persisted store state on one axis.

Not part of the product plugin graph (no dshClient); feature packages depend on it in devDependencies only.

Model Experience

None, as this package is browser-side test infrastructure; nothing here reaches a model request.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

  • Consumed through repository source aliases only. Specs resolve the package through tsconfig paths to src; the built lib/ artifact re-exports @deepseek-ai/dsh-client-runtime/client, whose bundle is a browser loader script with no Node ESM exports, so lib/index.js is not importable under plain Node. Acceptable while every consumer is an in-repo Vitest suite; a Node-compatible runtime entry is deferred until an out-of-repo consumer exists.
  • Conversation snapshots are fixture data, not replayed history. updateSnapshot writes the snapshot store directly; the wire-to-snapshot computation stays covered by the runtime package's own tests and the replay e2e. A fixture can therefore express states the production fold would never produce.