feat(desktop): fold Rubrics/Growth/Runtimes into one Evals nav entry (3 tabs + shared rubric selector)

This commit is contained in:
ZiyaZhang
2026-07-19 23:31:47 -07:00
parent 211ffb4b7c
commit 0207b5edd2
14 changed files with 781 additions and 105 deletions

View File

@@ -37,8 +37,37 @@ test('resolveHiddenPages: empty array → show everything', () => {
test('resolveHiddenPages: custom list → honored as-is', () => {
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['prs', 'growth'] }),
['prs', 'growth']
M.resolveHiddenPages({ hiddenPages: ['prs', 'bench'] }),
['prs', 'bench']
)
})
test('resolveHiddenPages: legacy rubrics/growth/runtimes ids remap to evals (lane-evals-merge)', () => {
// 2026-07-19: three separate nav items were merged into one Evals
// door. Old config values must keep hiding what the user asked for —
// if they'd hidden Rubrics before, they should still see no Rubrics
// surface after upgrade (which means Evals stays hidden).
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['rubrics'] }),
['evals']
)
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['growth'] }),
['evals']
)
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['runtimes'] }),
['evals']
)
// Multiple legacy ids collapse to a single 'evals' entry.
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['rubrics', 'growth', 'runtimes'] }),
['evals']
)
// Legacy ids mixed with unrelated ids preserve the unrelated ids.
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['prs', 'growth', 'bench'] }),
['prs', 'evals', 'bench']
)
})
@@ -50,8 +79,8 @@ test('resolveHiddenPages: non-array garbage → falls back to defaults (safe)',
test('resolveHiddenPages: filters out non-string / blank entries', () => {
assert.deepStrictEqual(
M.resolveHiddenPages({ hiddenPages: ['prs', '', null, 42, 'growth'] }),
['prs', 'growth']
M.resolveHiddenPages({ hiddenPages: ['prs', '', null, 42, 'bench'] }),
['prs', 'bench']
)
})
@@ -219,13 +248,13 @@ function makeSidebar() {
makeBtn('hub'),
makeBtn('bench'),
])
// "runtime" group — mission (default hidden) sits here.
// "runtime" group — mission (default hidden) sits here. Post
// lane-evals-merge (2026-07-19) rubrics/growth/runtimes fold into
// a single 'evals' button; the sidebar shim mirrors that new shape.
makeGroup([
makeBtn('rubrics'),
makeBtn('evals'),
makeBtn('plugins'),
makeBtn('runtimes'),
makeBtn('mission'),
makeBtn('growth'),
makeBtn('prs'),
])
return { buttons, groups }
@@ -263,11 +292,13 @@ test('DOM filter (case 2): empty array → nothing hidden (all pages show)', ()
test('DOM filter (case 3): custom list → matching buttons hidden, others untouched', () => {
const sb = makeSidebar()
// 'growth' remaps to 'evals' via LEGACY_ID_ALIAS (lane-evals-merge);
// 'prs' passes through unchanged. Both target actual sidebar buttons.
applyFilter(sb, { hiddenPages: ['prs', 'growth'] })
const hidden = sb.buttons.filter((b) => b.classList.contains('nav-item--hidden'))
assert.deepStrictEqual(
hidden.map((b) => b.dataset.tab).sort(),
['growth', 'prs']
['evals', 'prs']
)
// Playground + mission are NOT hidden because the researcher opted them in
// via an explicit list; only the ids in the list are hidden.

View File

@@ -41,10 +41,28 @@ test('no lane still carries pending — all four slots flipped', () => {
`all four coordinated slots should be flipped (found ${buttonPending.length} still-pending)`)
})
test('Runtimes tab and pane exist', () => {
assert.match(HTML, /data-tab="runtimes"/)
assert.match(HTML, /data-pane="runtimes"/)
assert.match(HTML, /id="runtimes-pane"/)
test('Runtimes surface preserved inside the Evals pane', () => {
// Post lane-evals-merge (2026-07-19), Runtimes is a tab inside the
// Evals door, not its own top-level nav. The nav button is 'evals';
// the runtimes-pane id + data-pane="runtimes" stay because
// runtimes-page.js queries them by that selector.
assert.match(HTML, /data-tab="evals"/, 'Evals nav button missing')
assert.match(HTML, /data-pane="runtimes"/, 'runtimes sub-pane still keeps its data-pane hook')
assert.match(HTML, /id="runtimes-pane"/, 'runtimes-pane id preserved for runtimes-page.js binding')
assert.match(HTML, /data-evals-tab-pane="runtime"/, 'Runtime tab pane marker present')
})
test('Evals door hosts Rubrics/Growth/Runtime as tabs', () => {
// Sanity: the three sub-pane markers are present and reachable via
// their evals-tab id. Guards against a future edit that silently
// orphans a tab pane.
assert.match(HTML, /data-evals-tab="rubrics"/, 'Rubrics tab button present')
assert.match(HTML, /data-evals-tab="growth"/, 'Growth tab button present')
assert.match(HTML, /data-evals-tab="runtime"/, 'Runtime tab button present')
assert.match(HTML, /data-evals-tab-pane="rubrics"/, 'Rubrics tab pane present')
assert.match(HTML, /data-evals-tab-pane="growth"/, 'Growth tab pane present')
assert.match(HTML, /data-evals-tab-pane="runtime"/, 'Runtime tab pane present')
assert.match(HTML, /id="evals-shared-rubric"/, 'Shared rubric selector present')
})
test('Settings tab and pane exist', () => {