feat: 终端二级设置支持自定义字体(字体族 + 9–32px 字号,实时生效)
- SidebarPrefs 新增 terminalFontFamily(空 = 跟随主题等宽字体)/ terminalFontSize(9–32,默认 13),PrefsSchema 与 parsePrefs 同步校验 - 声明式设置 API 扩展:SidebarSettingToggle 支持 type: 'switch' | 'text' | 'number'(缺省 switch,向后兼容)+ min/max/placeholder/unit - 终端卡片齿轮弹窗新增「终端字体」「终端字号」两行:blur/Enter 提交、number 钳制、提交失败回滚草稿 - TerminalView 经 store 订阅实时应用字体(options + re-fit + resize),懒加载 chunk 无新增依赖 - 新增 resolveTerminalFont 纯函数(回退链:用户字体 → 主题 token → 内置等宽栈)并单测 - 版本 0.11.0,README/AGENTS.md/设计文档同步
This commit is contained in:
+14
-2
@@ -47,10 +47,22 @@ describe('built-in tab registrations', () => {
|
||||
expect(toggles.map(t => t.key)).toEqual(['autoOpenSubagent', 'autoOpenJobs'])
|
||||
})
|
||||
|
||||
it('the terminal tab declares the model terminal-tools related setting', () => {
|
||||
it('the terminal tab declares the model terminal-tools, auto-terminal and custom-font settings', () => {
|
||||
const { service } = setup()
|
||||
const toggles = service.getTab('terminal')?.settings?.toggles ?? []
|
||||
expect(toggles.map(t => t.key)).toEqual(['agentTerminalTools', 'bottomPanelAutoTerminal'])
|
||||
expect(toggles.map(t => t.key)).toEqual(['agentTerminalTools', 'bottomPanelAutoTerminal', 'terminalFontFamily', 'terminalFontSize'])
|
||||
// The font rows are text/number inputs (not switches), with the size
|
||||
// row bounded by the shared 9–32 contract.
|
||||
expect(toggles[2]?.type).toBe('text')
|
||||
expect(toggles[2]?.title).toBeDefined()
|
||||
expect(toggles[2]?.placeholder).toBeDefined()
|
||||
expect(toggles[3]?.type).toBe('number')
|
||||
expect(toggles[3]?.min).toBe(9)
|
||||
expect(toggles[3]?.max).toBe(32)
|
||||
expect(toggles[3]?.unit).toBe('px')
|
||||
// The first two rows stay plain boolean switches.
|
||||
expect(toggles[0]?.type ?? 'switch').toBe('switch')
|
||||
expect(toggles[1]?.type ?? 'switch').toBe('switch')
|
||||
})
|
||||
|
||||
it('the browser tab declares its sandbox and link-takeover related settings', () => {
|
||||
|
||||
@@ -50,6 +50,10 @@ describe('dsh-better-sidebar plugin export shape', () => {
|
||||
// The terminal tools default OFF (the feature is dormant until the user
|
||||
// enables it in the side card settings).
|
||||
expect(resolved.agentTerminalTools).toBe(false)
|
||||
// The terminal font customizations default to the theme (empty family)
|
||||
// and 13px.
|
||||
expect(resolved.terminalFontFamily).toBe('')
|
||||
expect(resolved.terminalFontSize).toBe(13)
|
||||
// The enable-switch maps resolve to {} (everything on) for old documents.
|
||||
expect(resolved.tabsEnabled).toEqual({})
|
||||
expect(resolved.viewersEnabled).toEqual({})
|
||||
@@ -59,6 +63,6 @@ describe('dsh-better-sidebar plugin export shape', () => {
|
||||
const overridden = (PrefsSchema as unknown as {
|
||||
(input: Record<string, unknown> | undefined): Record<string, unknown>
|
||||
})({ openByDefault: false, defaultWidthPercent: 45 })
|
||||
expect(overridden).toEqual({ openByDefault: false, defaultWidthPercent: 45, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
expect(overridden).toEqual({ openByDefault: false, defaultWidthPercent: 45, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, terminalFontFamily: '', terminalFontSize: 13, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Interactive tests for the settings popup's text/number rows: the draft is
|
||||
* local state committed on blur through the parent's onCommit; the parent's
|
||||
* canonical return is adopted (clamped numbers, stored value for invalid
|
||||
* input), and the row remounts when the committed pref value changes (a
|
||||
* failed commit reverts prefs → the stored value reappears).
|
||||
*
|
||||
* Rendered with createRoot + act() in jsdom (the SSR specs stay in
|
||||
* side-card-section.spec.tsx; this file exercises the event paths).
|
||||
*/
|
||||
// @vitest-environment jsdom
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { createElement, type ReactNode } from 'react'
|
||||
import { createRoot, type Root } from 'react-dom/client'
|
||||
import { act } from 'react-dom/test-utils'
|
||||
|
||||
// The act() environment flag (React 18.2 reads it before flushing effects).
|
||||
;(globalThis as Record<string, unknown>).IS_REACT_ACT_ENVIRONMENT = true
|
||||
import type { SidebarSettingToggle } from '../src/client/service.ts'
|
||||
import { FeatureSettingsRows } from '../src/client/SideCardSection.tsx'
|
||||
import { SIDEBAR_PREFS_DEFAULTS } from '../src/prefs-shared.ts'
|
||||
|
||||
/** Render the rows into a detached container under React's act(). */
|
||||
function mount(node: ReactNode): { container: HTMLDivElement; rerender: (node: ReactNode) => void; unmount: () => void } {
|
||||
const container = document.createElement('div')
|
||||
document.body.append(container)
|
||||
const root: Root = createRoot(container)
|
||||
act(() => { root.render(node) })
|
||||
return {
|
||||
container,
|
||||
rerender: (next) => { act(() => { root.render(next) }) },
|
||||
unmount: () => {
|
||||
act(() => { root.unmount() })
|
||||
container.remove()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/** Type into an input and commit it via blur (React 18: input event +
|
||||
* focusout). The native setter bypasses React's value tracker so the
|
||||
* change is actually seen. */
|
||||
function typeAndBlur(input: HTMLInputElement, value: string): void {
|
||||
const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')!.set!
|
||||
act(() => {
|
||||
setter.call(input, value)
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }))
|
||||
input.dispatchEvent(new FocusEvent('focusout', { bubbles: true }))
|
||||
})
|
||||
}
|
||||
|
||||
const prefs = { ...SIDEBAR_PREFS_DEFAULTS }
|
||||
|
||||
describe('FeatureSettingsRows typed rows (interactive)', () => {
|
||||
it('commits the raw text on blur and adopts the canonical return', () => {
|
||||
const commits: Array<[string, string]> = []
|
||||
const toggle: SidebarSettingToggle = {
|
||||
key: 'terminalFontFamily',
|
||||
type: 'text',
|
||||
title: () => 'Font family',
|
||||
}
|
||||
const { container, unmount } = mount(createElement(FeatureSettingsRows, {
|
||||
toggles: [toggle],
|
||||
prefs,
|
||||
onToggle: () => {},
|
||||
onCommit: (t, raw) => {
|
||||
commits.push([t.key, raw])
|
||||
return raw
|
||||
},
|
||||
}))
|
||||
const input = container.querySelector('input')!
|
||||
typeAndBlur(input, 'Monaco')
|
||||
expect(commits).toEqual([['terminalFontFamily', 'Monaco']])
|
||||
// The canonical return is adopted into the draft.
|
||||
expect(input.value).toBe('Monaco')
|
||||
unmount()
|
||||
})
|
||||
|
||||
it('clamps numbers into the declared bounds on commit', () => {
|
||||
const commits: Array<[string, number]> = []
|
||||
const toggle: SidebarSettingToggle = {
|
||||
key: 'terminalFontSize',
|
||||
type: 'number',
|
||||
title: () => 'Font size',
|
||||
min: 9,
|
||||
max: 32,
|
||||
}
|
||||
const { container, unmount } = mount(createElement(FeatureSettingsRows, {
|
||||
toggles: [toggle],
|
||||
prefs: { ...prefs, terminalFontSize: 13 },
|
||||
onToggle: () => {},
|
||||
onCommit: (t, raw) => {
|
||||
const parsed = Number(raw)
|
||||
const clamped = Math.min(32, Math.max(9, Math.round(parsed)))
|
||||
commits.push([t.key, clamped])
|
||||
return String(clamped)
|
||||
},
|
||||
}))
|
||||
const input = container.querySelector('input')!
|
||||
typeAndBlur(input, '40')
|
||||
expect(commits).toEqual([['terminalFontSize', 32]])
|
||||
expect(input.value).toBe('32')
|
||||
unmount()
|
||||
})
|
||||
|
||||
it('clamps an emptied number input to the lower bound on commit (width-row precedent)', () => {
|
||||
const commits: Array<[string, number]> = []
|
||||
const toggle: SidebarSettingToggle = {
|
||||
key: 'terminalFontSize',
|
||||
type: 'number',
|
||||
title: () => 'Font size',
|
||||
min: 9,
|
||||
max: 32,
|
||||
}
|
||||
const { container, unmount } = mount(createElement(FeatureSettingsRows, {
|
||||
toggles: [toggle],
|
||||
prefs: { ...prefs, terminalFontSize: 13 },
|
||||
onToggle: () => {},
|
||||
// The parent mirrors the real handler: an emptied number parses to 0
|
||||
// and clamps into the bounds (a browser number input never holds a
|
||||
// non-numeric string — the draft can only be empty or numeric).
|
||||
onCommit: (t, raw) => {
|
||||
const clamped = Math.min(32, Math.max(9, Math.round(Number(raw))))
|
||||
commits.push([t.key, clamped])
|
||||
return String(clamped)
|
||||
},
|
||||
}))
|
||||
const input = container.querySelector('input')!
|
||||
typeAndBlur(input, '')
|
||||
expect(commits).toEqual([['terminalFontSize', 9]])
|
||||
expect(input.value).toBe('9')
|
||||
unmount()
|
||||
})
|
||||
|
||||
it('reverts the draft to the committed value after a failed commit reverts prefs', () => {
|
||||
const toggle: SidebarSettingToggle = {
|
||||
key: 'terminalFontFamily',
|
||||
type: 'text',
|
||||
title: () => 'Font family',
|
||||
}
|
||||
// The parent mirrors the real handler: the optimistic commit adopts the
|
||||
// typed value, and a FAILED write reverts prefs to the stored one.
|
||||
let prefsNow = { ...prefs, terminalFontFamily: 'Old' }
|
||||
const { container, rerender, unmount } = mount(createElement(FeatureSettingsRows, {
|
||||
toggles: [toggle],
|
||||
prefs: prefsNow,
|
||||
onToggle: () => {},
|
||||
onCommit: (_t, raw) => raw,
|
||||
}))
|
||||
const input = container.querySelector('input')!
|
||||
typeAndBlur(input, 'New')
|
||||
// Optimistic commit: the draft adopts the typed value.
|
||||
expect(input.value).toBe('New')
|
||||
// The optimistic pref lands (parent state): the key changes, the row
|
||||
// remounts with the same value — no visible reset while editing.
|
||||
prefsNow = { ...prefsNow, terminalFontFamily: 'New' }
|
||||
rerender(createElement(FeatureSettingsRows, {
|
||||
toggles: [toggle],
|
||||
prefs: prefsNow,
|
||||
onToggle: () => {},
|
||||
onCommit: (_t, raw) => raw,
|
||||
}))
|
||||
expect(container.querySelector('input')!.value).toBe('New')
|
||||
// The write fails: prefs revert to the stored value and the row
|
||||
// remounts with it (the stale draft is gone).
|
||||
prefsNow = { ...prefsNow, terminalFontFamily: 'Old' }
|
||||
rerender(createElement(FeatureSettingsRows, {
|
||||
toggles: [toggle],
|
||||
prefs: prefsNow,
|
||||
onToggle: () => {},
|
||||
onCommit: (_t, raw) => raw,
|
||||
}))
|
||||
expect(container.querySelector('input')!.value).toBe('Old')
|
||||
unmount()
|
||||
})
|
||||
})
|
||||
@@ -172,4 +172,47 @@ describe('FeatureSettingsRows (the secondary settings popup body)', () => {
|
||||
}))
|
||||
expect(html).toContain('checked=""')
|
||||
})
|
||||
|
||||
it('renders a text row as an input seeded with the pref value (empty = theme default)', () => {
|
||||
const html = renderToString(createElement(FeatureSettingsRows, {
|
||||
toggles: [{
|
||||
key: 'terminalFontFamily',
|
||||
type: 'text',
|
||||
title: () => 'Font family',
|
||||
desc: () => 'CSS stack',
|
||||
placeholder: '"JetBrains Mono", monospace',
|
||||
}],
|
||||
prefs: { ...prefs, terminalFontFamily: '"JetBrains Mono", monospace' },
|
||||
onToggle: () => {},
|
||||
onCommit: () => '',
|
||||
}))
|
||||
expect(html).toContain('Font family')
|
||||
expect(html).toContain('placeholder=""JetBrains Mono", monospace"')
|
||||
// The input carries the pref value (no switch for text rows).
|
||||
expect(html).toContain('value=""JetBrains Mono", monospace"')
|
||||
expect(html).not.toContain('type="checkbox"')
|
||||
})
|
||||
|
||||
it('renders a number row with the pref value, the declared bounds and a unit suffix', () => {
|
||||
const html = renderToString(createElement(FeatureSettingsRows, {
|
||||
toggles: [{
|
||||
key: 'terminalFontSize',
|
||||
type: 'number',
|
||||
title: () => 'Font size',
|
||||
min: 9,
|
||||
max: 32,
|
||||
unit: 'px',
|
||||
}],
|
||||
prefs: { ...prefs, terminalFontSize: 18 },
|
||||
onToggle: () => {},
|
||||
onCommit: () => '18',
|
||||
}))
|
||||
expect(html).toContain('Font size')
|
||||
expect(html).toContain('type="number"')
|
||||
expect(html).toContain('value="18"')
|
||||
expect(html).toContain('min="9"')
|
||||
expect(html).toContain('max="32"')
|
||||
expect(html).toContain('px')
|
||||
expect(html).not.toContain('type="checkbox"')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -517,6 +517,8 @@ describe('side card settings routes', () => {
|
||||
autoOpenJobs: true,
|
||||
agentTerminalTools: false,
|
||||
bottomPanelAutoTerminal: true,
|
||||
terminalFontFamily: '',
|
||||
terminalFontSize: 13,
|
||||
interceptOpenPath: true,
|
||||
htmlViewerNoSandbox: false,
|
||||
htmlViewerDefaultUnsafe: false,
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Terminal font resolution tests: the custom font prefs (side card settings,
|
||||
* terminal card) resolve into xterm options with a strict fallback chain —
|
||||
* user family > theme code font > the built-in monospace stack, and the size
|
||||
* clamped into the 9–32 contract.
|
||||
*/
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { SIDEBAR_PREFS_DEFAULTS, clampTerminalFontSize, TERMINAL_FONT_SIZE_MAX, TERMINAL_FONT_SIZE_MIN } from '../src/prefs-shared.ts'
|
||||
import { DEFAULT_TERMINAL_FONT_FAMILY, resolveTerminalFont } from '../src/client/terminal-font.ts'
|
||||
|
||||
describe('clampTerminalFontSize', () => {
|
||||
it('rounds and clamps into the 9–32 contract', () => {
|
||||
expect(clampTerminalFontSize(13)).toBe(13)
|
||||
expect(clampTerminalFontSize(15.6)).toBe(16)
|
||||
expect(clampTerminalFontSize(5)).toBe(TERMINAL_FONT_SIZE_MIN)
|
||||
expect(clampTerminalFontSize(40)).toBe(TERMINAL_FONT_SIZE_MAX)
|
||||
})
|
||||
})
|
||||
|
||||
describe('resolveTerminalFont', () => {
|
||||
it('falls back to the theme code font when the family pref is empty', () => {
|
||||
const { fontFamily, fontSize } = resolveTerminalFont(SIDEBAR_PREFS_DEFAULTS, 'var-theme-font')
|
||||
expect(fontFamily).toBe('var-theme-font')
|
||||
expect(fontSize).toBe(13)
|
||||
})
|
||||
|
||||
it('falls back to the built-in monospace stack when neither the pref nor the theme provides one', () => {
|
||||
expect(resolveTerminalFont(SIDEBAR_PREFS_DEFAULTS, undefined).fontFamily).toBe(DEFAULT_TERMINAL_FONT_FAMILY)
|
||||
// A whitespace-only pref counts as empty (theme default).
|
||||
expect(resolveTerminalFont({ ...SIDEBAR_PREFS_DEFAULTS, terminalFontFamily: ' ' }, undefined).fontFamily)
|
||||
.toBe(DEFAULT_TERMINAL_FONT_FAMILY)
|
||||
})
|
||||
|
||||
it('prefers the custom family verbatim and clamps the size', () => {
|
||||
const { fontFamily, fontSize } = resolveTerminalFont(
|
||||
{ ...SIDEBAR_PREFS_DEFAULTS, terminalFontFamily: '"JetBrains Mono", monospace', terminalFontSize: 40 },
|
||||
'var-theme-font',
|
||||
)
|
||||
expect(fontFamily).toBe('"JetBrains Mono", monospace')
|
||||
expect(fontSize).toBe(TERMINAL_FONT_SIZE_MAX)
|
||||
})
|
||||
})
|
||||
+26
-4
@@ -1153,6 +1153,8 @@ describe('side card preferences', () => {
|
||||
autoOpenJobs: true,
|
||||
agentTerminalTools: true,
|
||||
bottomPanelAutoTerminal: true,
|
||||
terminalFontFamily: '',
|
||||
terminalFontSize: 13,
|
||||
interceptOpenPath: true,
|
||||
htmlViewerNoSandbox: false,
|
||||
htmlViewerDefaultUnsafe: false,
|
||||
@@ -1172,6 +1174,8 @@ describe('side card preferences', () => {
|
||||
autoOpenJobs: true,
|
||||
agentTerminalTools: false,
|
||||
bottomPanelAutoTerminal: true,
|
||||
terminalFontFamily: '',
|
||||
terminalFontSize: 13,
|
||||
interceptOpenPath: true,
|
||||
htmlViewerNoSandbox: false,
|
||||
htmlViewerDefaultUnsafe: false,
|
||||
@@ -1191,6 +1195,8 @@ describe('side card preferences', () => {
|
||||
autoOpenJobs: true,
|
||||
agentTerminalTools: false,
|
||||
bottomPanelAutoTerminal: true,
|
||||
terminalFontFamily: '',
|
||||
terminalFontSize: 13,
|
||||
interceptOpenPath: true,
|
||||
htmlViewerNoSandbox: false,
|
||||
htmlViewerDefaultUnsafe: false,
|
||||
@@ -1225,6 +1231,22 @@ describe('side card preferences', () => {
|
||||
expect((await loadPrefs(wire({ interceptOpenPath: true }))).interceptOpenPath).toBe(true)
|
||||
})
|
||||
|
||||
it('resolves the terminal font prefs (family passthrough, size clamp)', async () => {
|
||||
// Absent → theme default (empty family) + default size.
|
||||
expect((await loadPrefs(wire({}))).terminalFontFamily).toBe('')
|
||||
expect((await loadPrefs(wire({}))).terminalFontSize).toBe(13)
|
||||
// A custom family survives verbatim; a malformed one falls back.
|
||||
expect((await loadPrefs(wire({ terminalFontFamily: '"JetBrains Mono", monospace' }))).terminalFontFamily)
|
||||
.toBe('"JetBrains Mono", monospace')
|
||||
expect((await loadPrefs(wire({ terminalFontFamily: 42 }))).terminalFontFamily).toBe('')
|
||||
// The size clamps into 9–32 (rounded); non-numbers fall back.
|
||||
expect((await loadPrefs(wire({ terminalFontSize: 5 }))).terminalFontSize).toBe(9)
|
||||
expect((await loadPrefs(wire({ terminalFontSize: 40 }))).terminalFontSize).toBe(32)
|
||||
expect((await loadPrefs(wire({ terminalFontSize: 15.6 }))).terminalFontSize).toBe(16)
|
||||
expect((await loadPrefs(wire({ terminalFontSize: 'big' }))).terminalFontSize).toBe(13)
|
||||
expect((await loadPrefs(wire({ terminalFontSize: 18 }))).terminalFontSize).toBe(18)
|
||||
})
|
||||
|
||||
it('validates the per-tab / per-viewer enable maps (absent keys mean enabled)', async () => {
|
||||
// A non-object map falls back to {} (everything enabled).
|
||||
expect((await loadPrefs(wire({ tabsEnabled: 'nope' }))).tabsEnabled).toEqual({})
|
||||
@@ -1242,9 +1264,9 @@ describe('side card preferences', () => {
|
||||
const store = createSidebarStore()
|
||||
// Node environment: no window → the width falls back to PANEL_DEFAULT,
|
||||
// while the open flag still follows the preference.
|
||||
store.setPrefs({ openByDefault: false, defaultWidthPercent: 45, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
store.setPrefs({ openByDefault: false, defaultWidthPercent: 45, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, terminalFontFamily: '', terminalFontSize: 13, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
store.setSession('fresh-session')
|
||||
expect(store.getPrefs()).toEqual({ openByDefault: false, defaultWidthPercent: 45, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
expect(store.getPrefs()).toEqual({ openByDefault: false, defaultWidthPercent: 45, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, terminalFontFamily: '', terminalFontSize: 13, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
const snapshot = store.getSnapshot()
|
||||
expect(snapshot.sessionId).toBe('fresh-session')
|
||||
expect(snapshot.state?.panelOpen).toBe(false)
|
||||
@@ -1280,7 +1302,7 @@ describe('side card preferences', () => {
|
||||
|
||||
it('skips the default explorer tab when the explorer type is disabled', () => {
|
||||
const store = createSidebarStore()
|
||||
store.setPrefs({ openByDefault: true, defaultWidthPercent: 30, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: { explorer: false }, viewersEnabled: {} })
|
||||
store.setPrefs({ openByDefault: true, defaultWidthPercent: 30, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, terminalFontFamily: '', terminalFontSize: 13, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: { explorer: false }, viewersEnabled: {} })
|
||||
store.setSession('no-explorer')
|
||||
const state = store.getSnapshot().state!
|
||||
const tabs = allLeaves(state.splits).flatMap(leaf => leaf.tabs)
|
||||
@@ -1288,7 +1310,7 @@ describe('side card preferences', () => {
|
||||
expect(state.splits.kind).toBe('leaf')
|
||||
// Re-enabling seeds the explorer tab again.
|
||||
const openStore = createSidebarStore()
|
||||
openStore.setPrefs({ openByDefault: true, defaultWidthPercent: 30, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
openStore.setPrefs({ openByDefault: true, defaultWidthPercent: 30, autoOpenSubagent: true, autoOpenJobs: true, agentTerminalTools: false, bottomPanelAutoTerminal: true, terminalFontFamily: '', terminalFontSize: 13, interceptOpenPath: true, htmlViewerNoSandbox: false, htmlViewerDefaultUnsafe: false, browserNoSandbox: false, browserInterceptLinks: true, tabsEnabled: {}, viewersEnabled: {} })
|
||||
openStore.setSession('with-explorer')
|
||||
const openTabs = allLeaves(openStore.getSnapshot().state!.splits).flatMap(leaf => leaf.tabs)
|
||||
expect(openTabs.map(tab => tab.type)).toEqual(['explorer'])
|
||||
|
||||
Reference in New Issue
Block a user