Files
crewli/apps/app/tests/unit/lib/timetable/row-height.test.ts
bert.hausmans 3d4bd3fc38 test(timetable): row-height helper + StageHeaderCell prop seam (B4)
B4 — jsdom-runnable assertions for the structural pieces of B2/B3.

apps/app/tests/unit/lib/timetable/row-height.test.ts (4 tests):
  - laneCount=0 → 52px (Math.max(1, 0) fallback path)
  - laneCount=1 → 52px (single-lane stage row)
  - laneCount=3 → 148px
  - laneCount=10 → 484px (10 × 48 + 4)

apps/app/tests/component/StageHeaderCell.test.ts (4 tests):
  - row-height-px prop applies as inline blockSize on the root
  - prop omitted → no inline blockSize set (legacy `block-size: 100%`
    CSS path takes over for any caller still relying on parent-driven sizing)
  - 484px for laneCount=10 round-trips through the prop without truncation
  - conflict badge renders only when conflictCount > 0 (existing behavior;
    locked in as part of touching this surface)

Visual scroll/alignment proof (sticky-left freeze pane, sticky-top axis,
horizontal scroll cohesion across 14 stages, diagonal trackpad scroll,
pixel-perfect header↔row alignment) is deferred to TEST-VISUAL-001
explicitly: jsdom does not compute position:sticky offsets, scrollbar
visibility, layout overflow chains, or scroll containment ancestry. This
is a known limitation of jsdom-based component testing — not a test gap
in this branch. The sticky behavior, z-index ladder, and DOM structure
are all in place per E1-E4; their validation requires a real browser,
which is exactly what the Playwright CT migration on TEST-INFRA-001 +
TEST-VISUAL-001 unlocks.

No existing tests asserted the old broken layout (no references to the
deprecated `tt-page__rows`, `tt-page__stages`, or `<GridBg>` in tests/).
The unused GridBg component file remains on disk; deleting it is a
stylistic cleanup outside this stabilization scope.

Test count: 389 → 397.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:33:12 +02:00

34 lines
1.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest'
import { computeStageRowHeight } from '@/lib/timetable/row-height'
/**
* One-line helper, four assertion cases — keep this surface tight; this
* is the canonical row-height math for both StageRow content and the
* sticky-left StageHeaderCell. If either side drifts, the freeze panes
* misalign in the browser. The math:
*
* max(1, laneCount) × (laneHeight + lanePad) + lanePad
*
* with the canonical constants laneHeight=44, lanePad=4 → 48 per lane + 4.
*/
const LANE_HEIGHT = 44
const LANE_PAD = 4
describe('computeStageRowHeight', () => {
it('falls back to single-lane height when laneCount is 0', () => {
expect(computeStageRowHeight(0, LANE_HEIGHT, LANE_PAD)).toBe(52)
})
it('returns 52px for laneCount=1', () => {
expect(computeStageRowHeight(1, LANE_HEIGHT, LANE_PAD)).toBe(52)
})
it('returns 148px for laneCount=3', () => {
expect(computeStageRowHeight(3, LANE_HEIGHT, LANE_PAD)).toBe(148)
})
it('returns 484px for laneCount=10 (10 × 48 + 4)', () => {
expect(computeStageRowHeight(10, LANE_HEIGHT, LANE_PAD)).toBe(484)
})
})