Skip to content

Commit 4d85aba

Browse files
committed
feat(overview): add executive overview with precision-aware rankings and result-level evidence
1 parent 1e60c7b commit 4d85aba

27 files changed

Lines changed: 3436 additions & 63 deletions

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Deliberately compact test fixture (one benchmark row per line, <=60 lines);
2+
# oxfmt/prettier would pretty-print it to ~530 lines. See overview-data.test.ts drift guard.
3+
packages/app/cypress/fixtures/api/overview-rows.json

packages/app/cypress/component/header.cy.tsx

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,24 @@ import { PathnameContext } from 'next/dist/shared/lib/hooks-client-context.share
55
import { Header } from '@/components/header/header';
66
import { ThemeProvider } from '@/components/ui/theme-provider';
77

8+
// Component specs mount outside the Next app shell, so the global stylesheet is
9+
// never injected. The layout assertions below need real Tailwind output, and
10+
// next-style-loader inserts before this anchor node, so both must exist before
11+
// the stylesheet module evaluates.
12+
const cssAnchor = document.createElement('noscript');
13+
cssAnchor.id = '__next_css__DO_NOT_USE__';
14+
document.head.append(cssAnchor);
15+
require('@/app/globals.css');
16+
817
const queryClient = new QueryClient({
918
defaultOptions: { queries: { retry: false } },
1019
});
1120

21+
/** Minimum touch target, per WCAG 2.5.8 and the `size-11` / `min-h-11` utilities. */
22+
const MIN_TOUCH_PX = 44;
23+
/** Tolerance for sub-pixel layout rounding. */
24+
const EPSILON = 0.5;
25+
1226
function createMockRouter() {
1327
return {
1428
push: cy.stub(),
@@ -20,6 +34,10 @@ function createMockRouter() {
2034
};
2135
}
2236

37+
function rectOf(selector: string) {
38+
return cy.get(selector).then(($el) => $el[0].getBoundingClientRect());
39+
}
40+
2341
describe('Header', () => {
2442
beforeEach(() => {
2543
const mockRouter = createMockRouter();
@@ -74,8 +92,93 @@ describe('Header', () => {
7492
cy.viewport(375, 812);
7593
cy.get('[data-testid="mobile-menu-toggle"]').should('be.visible');
7694
cy.get('[data-testid="mobile-menu-toggle"]').click();
77-
cy.contains('Dashboard').should('be.visible');
78-
cy.contains('Comparisons').should('be.visible');
79-
cy.contains('Supporters').should('be.visible');
95+
cy.get('[data-testid="mobile-menu"]').within(() => {
96+
cy.contains('Dashboard').should('be.visible');
97+
cy.contains('Comparisons').should('be.visible');
98+
cy.contains('Supporters').should('be.visible');
99+
});
100+
});
101+
102+
describe('at 320x700', () => {
103+
beforeEach(() => {
104+
cy.viewport(320, 700);
105+
});
106+
107+
it('hides the GitHub star control', () => {
108+
cy.get('[data-testid="header-star-button"]').should('not.be.visible');
109+
});
110+
111+
it('keeps the remaining controls inside the header bounds', () => {
112+
cy.get('[data-testid="header"]').then(($header) => {
113+
const bounds = $header[0].getBoundingClientRect();
114+
const selectors = [
115+
'[data-testid="header-brand"]',
116+
'[data-testid="language-toggle"]',
117+
'[data-testid="theme-toggle"]',
118+
'[data-testid="mobile-menu-toggle"]',
119+
];
120+
selectors.forEach((selector) => {
121+
rectOf(selector).then((rect) => {
122+
expect(rect.left, `${selector} left edge`).to.be.at.least(bounds.left - EPSILON);
123+
expect(rect.right, `${selector} right edge`).to.be.at.most(bounds.right + EPSILON);
124+
});
125+
});
126+
});
127+
});
128+
129+
it('gives the brand and language controls a 44px touch height', () => {
130+
['[data-testid="header-brand"]', '[data-testid="language-toggle"]'].forEach((selector) => {
131+
rectOf(selector).then((rect) => {
132+
expect(rect.height, `${selector} height`).to.be.at.least(MIN_TOUCH_PX - EPSILON);
133+
});
134+
});
135+
});
136+
137+
it('gives the icon controls a 44px touch target in both dimensions', () => {
138+
['[data-testid="theme-toggle"]', '[data-testid="mobile-menu-toggle"]'].forEach((selector) => {
139+
rectOf(selector).then((rect) => {
140+
expect(rect.width, `${selector} width`).to.be.at.least(MIN_TOUCH_PX - EPSILON);
141+
expect(rect.height, `${selector} height`).to.be.at.least(MIN_TOUCH_PX - EPSILON);
142+
});
143+
});
144+
});
145+
146+
it('does not overflow horizontally', () => {
147+
cy.get('[data-testid="header"]').then(($header) => {
148+
const header = $header[0];
149+
expect(header.scrollWidth, 'header scrollWidth').to.be.at.most(header.clientWidth);
150+
});
151+
});
152+
153+
it('still opens the menu and exposes its links', () => {
154+
cy.get('[data-testid="mobile-menu-toggle"]').click();
155+
cy.get('[data-testid="mobile-menu"]').should('be.visible');
156+
cy.get('[data-testid="mobile-menu"]').within(() => {
157+
['Home', 'Dashboard', 'Comparisons', 'Supporters', 'Datasets', 'Articles', 'About'].forEach(
158+
(label) => {
159+
cy.contains('a', label).should('be.visible');
160+
},
161+
);
162+
});
163+
cy.get('[data-testid="mobile-menu"] a').each(($link) => {
164+
const rect = $link[0].getBoundingClientRect();
165+
expect(rect.height, `${$link.text()} link height`).to.be.at.least(MIN_TOUCH_PX - EPSILON);
166+
});
167+
});
168+
169+
it('exposes the minecraft audio toggles in the mobile menu without overflowing', () => {
170+
cy.get('[data-testid="theme-toggle"]').click();
171+
cy.get('[data-testid="theme-toggle"]').click();
172+
cy.get('html').should('have.class', 'minecraft');
173+
cy.get('[data-testid="mobile-menu-toggle"]').click();
174+
cy.get('[data-testid="mobile-menu"]').within(() => {
175+
cy.get('button[aria-label="Mute music"]').should('be.visible');
176+
cy.get('button[aria-label="Mute click sounds"]').should('be.visible');
177+
});
178+
cy.get('[data-testid="header"]').then(($header) => {
179+
const header = $header[0];
180+
expect(header.scrollWidth, 'header scrollWidth').to.be.at.most(header.clientWidth);
181+
});
182+
});
80183
});
81184
});
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Focused smoke coverage for /overview. In fixtures mode the page is served by
2+
// the synthetic cypress/fixtures/api/overview-rows.json through the real data
3+
// builder, so every expected value below was derived by running the assembler
4+
// over that fixture (the drift guard in overview-data.test.ts locks the same
5+
// values) — never eyeballed. The fixture exercises every 8.7 state: coverage-driven
6+
// primary precision, ranked vs coverage secondary, all not-ranked reasons, and —
7+
// uniquely — a cross-day evidence range the live dataset does not produce.
8+
9+
const MODEL_LABELS = [
10+
'DeepSeek V4 Pro 1.6T',
11+
'Kimi K2.5/2.6/2.7-Code 1T',
12+
'MiniMax M3 428B',
13+
'GLM5.2',
14+
'Qwen3.5 397B',
15+
];
16+
17+
/** The page must never scroll sideways: the whole comparison has to fit. */
18+
function expectNoHorizontalOverflow() {
19+
cy.document().then((doc) => {
20+
expect(doc.documentElement.scrollWidth).to.be.lte(doc.documentElement.clientWidth);
21+
});
22+
}
23+
24+
/**
25+
* A narrow document is not enough: a table parked in an `overflow-x` region
26+
* keeps the document narrow while still scrolling sideways, so nothing inside
27+
* the surface may be wider than its own box either. `sr-only` clips (1px) and
28+
* non-replaced inline boxes are exempt — CSSOM reports a spurious `scrollWidth`
29+
* for inline boxes in Firefox, and `overflow` cannot apply to them anyway.
30+
*/
31+
function expectNoHorizontalScroller(testId: string) {
32+
cy.get(`[data-testid="${testId}"]`).then(([surface]) => {
33+
const scrollers = [surface, ...surface.querySelectorAll('*')]
34+
.filter(
35+
(el) =>
36+
!el.classList.contains('sr-only') &&
37+
getComputedStyle(el).display !== 'inline' &&
38+
el.scrollWidth > el.clientWidth + 1,
39+
)
40+
.map((el) => `${el.tagName} ${el.scrollWidth}>${el.clientWidth}`);
41+
expect(scrollers, `horizontally scrollable inside ${testId}`).to.deep.equal([]);
42+
});
43+
}
44+
45+
function desktopModel(model: string) {
46+
return cy.get(`[data-testid="overview-desktop-model"][data-model="${model}"]`);
47+
}
48+
49+
describe('Overview page', () => {
50+
it('summarizes every active model without interactive widgets', () => {
51+
cy.viewport(1280, 800);
52+
cy.visit('/overview');
53+
54+
cy.contains('h1', 'AI Inference Overview').should('exist');
55+
cy.get('[data-testid="overview-desktop-matrix"]').should('be.visible');
56+
cy.get('[data-testid="overview-desktop-matrix"] h2').should('have.length', MODEL_LABELS.length);
57+
for (const label of MODEL_LABELS) {
58+
cy.get('[data-testid="overview-desktop-matrix"]').should('contain.text', label);
59+
}
60+
// Database-wide freshness line + the methodology footnote's once-per-page note.
61+
cy.contains('Database snapshot through Jul 18').should('exist');
62+
cy.contains(
63+
'The default precision maximizes comparable hardware coverage. Not ranked does not mean slower.',
64+
).should('exist');
65+
// A one-glance summary, not an interactive widget.
66+
cy.get('[data-testid="overview-desktop-matrix"]').within(() => {
67+
cy.get('details, summary, button').should('not.exist');
68+
});
69+
});
70+
71+
it('ranks the primary precision, dates each read, and accounts for every hardware', () => {
72+
cy.viewport(1280, 800);
73+
cy.visit('/overview');
74+
75+
desktopModel('DeepSeek-V4-Pro').within(() => {
76+
// Primary precision, its leader, and the runner-up's own signed delta (ASCII minus).
77+
cy.contains('FP4 · PRIMARY @50').should('exist');
78+
cy.contains('B300').should('exist');
79+
cy.contains('1,122').should('exist');
80+
cy.contains('Leader').should('exist');
81+
cy.contains('-20%').should('exist');
82+
// FP8 measured one platform → one compact coverage line, not a second table.
83+
cy.contains('FP8 coverage: GB200 NVL72 measured; insufficient comparable results.').should(
84+
'exist',
85+
);
86+
// Leader @50 is bracketed by two run days (en-dash range); same-day reads and
87+
// the @100 read (its own leader) collapse to a single date.
88+
cy.contains('Jun 24–Jul 4').should('exist');
89+
cy.contains('Jul 18').should('exist');
90+
cy.contains('381').should('exist');
91+
cy.contains('Only exact result').should('exist');
92+
// Every remaining hardware carries one reason, both clamp directions included.
93+
cy.contains('cannot reach @50').should('exist');
94+
cy.contains('no exact @50 result').should('exist');
95+
cy.contains('no 8K/1K data').should('exist');
96+
cy.contains('standard decode only').should('exist');
97+
// Each ranked value links into its own pre-filtered dashboard view.
98+
cy.get('a[href*="i_gpus="]')
99+
.first()
100+
.should('have.attr', 'href')
101+
.and('include', 'g_model=DeepSeek-V4-Pro')
102+
.and('include', 'i_gpus=b300_sglang_mtp')
103+
.and('include', 'i_spec=mtp');
104+
});
105+
});
106+
107+
it('opens a ranked secondary only when the other precision adds comparable hardware', () => {
108+
cy.viewport(1280, 800);
109+
cy.visit('/overview');
110+
111+
// Qwen: FP8 ranks a comparable pair AND adds MI355X, so it renders subordinate rows.
112+
desktopModel('Qwen-3.5-397B-A17B').within(() => {
113+
cy.contains('FP4 · PRIMARY @50').should('exist');
114+
cy.contains('FP8 @50').should('exist');
115+
cy.contains('MI355X').should('exist');
116+
cy.contains('760').should('exist');
117+
cy.contains('-16%').should('exist');
118+
});
119+
// MiniMax: wider exact-@50 FP8 coverage flips the primary precision to FP8;
120+
// FP4 falls back to a single-hardware coverage line.
121+
desktopModel('MiniMax-M3').within(() => {
122+
cy.contains('FP8 · PRIMARY @50').should('exist');
123+
cy.contains('FP4 coverage: H200 measured; insufficient comparable results.').should('exist');
124+
});
125+
});
126+
127+
it('stacks on a 390px phone with no sideways scroll', () => {
128+
cy.viewport(390, 844);
129+
cy.visit('/overview');
130+
131+
cy.get('[data-testid="overview-mobile-list"]').should('be.visible');
132+
cy.get('[data-testid="overview-desktop-matrix"]').should('not.be.visible');
133+
cy.get('[data-testid="overview-mobile-list"]').within(() => {
134+
cy.get('details, summary, button').should('not.exist');
135+
});
136+
expectNoHorizontalOverflow();
137+
expectNoHorizontalScroller('overview-mobile-list');
138+
});
139+
140+
it('renders the Chinese sibling with the same hierarchy and the per-GPU unit', () => {
141+
cy.viewport(1280, 800);
142+
cy.visit('/zh/overview');
143+
144+
cy.contains('h1', 'AI 推理总览').should('exist');
145+
cy.contains('输出 tok/s/GPU').should('exist');
146+
desktopModel('DeepSeek-V4-Pro').within(() => {
147+
cy.contains('FP4 · 主排名 @50').should('exist');
148+
});
149+
cy.contains('默认精度优先覆盖更多可比较硬件。未参与排名不代表性能更低。').should('exist');
150+
});
151+
});

0 commit comments

Comments
 (0)