diff --git a/web/src/views/BenchmarkView.test.ts b/web/src/views/BenchmarkView.test.ts
new file mode 100644
index 0000000..32c7cff
--- /dev/null
+++ b/web/src/views/BenchmarkView.test.ts
@@ -0,0 +1,48 @@
+import { mount } from '@vue/test-utils'
+import { describe, it, expect, vi, beforeEach } from 'vitest'
+import BenchmarkView from './BenchmarkView.vue'
+
+beforeEach(() => {
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
+ ok: true,
+ // Return a shape that satisfies all child tab API calls:
+ // - ClassifierTab expects { models: {}, ... } from /api/benchmark/results
+ // - ClassifierTab expects ModelCategoriesResponse from /api/benchmark/models
+ // - LlmEvalTab, StyleTab, CompareTab have their own calls but also use models/tasks
+ json: async () => ({ models: {}, categories: {}, tasks: [], types: [], results: [] }),
+ text: async () => '',
+ }))
+ vi.stubGlobal('EventSource', class {
+ onmessage = null
+ onerror = null
+ close() {}
+ })
+})
+
+describe('BenchmarkView', () => {
+ it('renders page title "Benchmark"', () => {
+ const w = mount(BenchmarkView)
+ expect(w.text()).toContain('Benchmark')
+ })
+
+ it('has mode buttons: Classifier, LLM Eval, Writing Style', () => {
+ const w = mount(BenchmarkView)
+ const text = w.text()
+ expect(text).toContain('Classifier')
+ expect(text).toContain('LLM Eval')
+ expect(text).toContain('Writing Style')
+ })
+
+ it('does NOT have a Compare mode button', () => {
+ const w = mount(BenchmarkView)
+ const buttons = w.findAll('.mode-btn')
+ const labels = buttons.map(b => b.text())
+ expect(labels.every(l => !l.includes('Compare'))).toBe(true)
+ })
+
+ it('shows Classifier tab by default', () => {
+ const w = mount(BenchmarkView)
+ // ClassifierTab has a .classifier-tab root
+ expect(w.find('.classifier-tab').exists()).toBe(true)
+ })
+})
diff --git a/web/src/views/BenchmarkView.vue b/web/src/views/BenchmarkView.vue
index 667cde1..a4ae4ea 100644
--- a/web/src/views/BenchmarkView.vue
+++ b/web/src/views/BenchmarkView.vue
@@ -16,11 +16,6 @@
:class="{ active: benchMode === 'llm' }"
@click="benchMode = 'llm'"
>🤖 LLM Eval
-
-
@@ -39,10 +33,9 @@
import { ref } from 'vue'
import ClassifierTab from './ClassifierTab.vue'
import LlmEvalTab from './LlmEvalTab.vue'
-import CompareTab from './CompareTab.vue'
import StyleTab from './StyleTab.vue'
-type BenchMode = 'classifier' | 'llm' | 'compare' | 'style'
+type BenchMode = 'classifier' | 'llm' | 'style'
const benchMode = ref('classifier')
@@ -69,7 +62,7 @@ const benchMode = ref('classifier')
margin: 0;
}
-/* ── Mode toggle (segmented control) ────────────────────── */
+/* ── Mode toggle (segmented control) ── */
.mode-toggle {
display: inline-flex;
border: 1px solid var(--color-border, #d0d7e8);
diff --git a/web/src/views/CompareView.test.ts b/web/src/views/CompareView.test.ts
new file mode 100644
index 0000000..cff3487
--- /dev/null
+++ b/web/src/views/CompareView.test.ts
@@ -0,0 +1,31 @@
+import { mount, flushPromises } from '@vue/test-utils'
+import { describe, it, expect, vi, beforeEach } from 'vitest'
+import CompareView from './CompareView.vue'
+
+beforeEach(() => {
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
+ ok: true,
+ json: async () => ({ tasks: [], types: [], models: [] }),
+ text: async () => '',
+ }))
+ vi.stubGlobal('EventSource', class {
+ onmessage = null
+ onerror = null
+ close() {}
+ })
+})
+
+describe('CompareView', () => {
+ it('renders page title "Compare"', async () => {
+ const w = mount(CompareView)
+ await flushPromises()
+ expect(w.find('h1.page-title').text()).toContain('Compare')
+ })
+
+ it('wraps CompareTab component', async () => {
+ const w = mount(CompareView)
+ await flushPromises()
+ // CompareTab renders a .compare-tab root div
+ expect(w.find('.compare-tab').exists()).toBe(true)
+ })
+})
diff --git a/web/src/views/CompareView.vue b/web/src/views/CompareView.vue
index 3e7acda..c0d6761 100644
--- a/web/src/views/CompareView.vue
+++ b/web/src/views/CompareView.vue
@@ -1,10 +1,36 @@
-
-
CompareView
-
Coming soon.
+
+
+
+
+