test(renderer): stub window.scrollTo so the DOM suite runs stderr-clean - #280
Conversation
jsdom defines window.scrollTo as a stub that logs "Not implemented: Window's scrollTo() method" instead of doing anything, so every call lands on stderr. motion/react calls it while resolving a height: "auto" keyframe, which DropdownSection animates on open and close, and a full test:coverage run printed the line twice with nothing failing. Overwrite it in the renderer-dom setup file, next to the existing Element.prototype.scrollTo stub. Nothing under test depends on the page having scrolled, and a quiet run means a real warning is visible.
Zaldaryon
left a comment
There was a problem hiding this comment.
Approved. This test-only change correctly replaces jsdom's noisy window.scrollTo stub in the shared renderer-dom setup. I reproduced the base/head difference: 224 renderer-dom tests passed on both, while the base emitted three "Not implemented: Window's scrollTo() method" lines and the head emitted none. The override is scoped to jsdom and leaves production behavior unchanged.
Local verification passed: npm run typecheck; npm run lint:ci with 0 errors and 15 existing warnings; npm run format:check; npm run test:coverage with 1633 passed and 2 skipped and coverage of 92.60% statements, 89.84% branches, 92.03% functions, and 94.05% lines; and npm run build:unpack. GitHub typecheck, lint, test, SonarCloud, Ubuntu build, and Windows build passed. The macOS build is policy-skipped.
A full
npm run test:coverageondevprints two lines of stderr with nothing failing:Harmless, but it trains you to ignore stderr, which is exactly where a real warning would land.
Where it comes from
Nothing in
src/renderercallswindow.scrollTo. The call is inmotion/react:KeyframesResolverparks the page scroll while it measures an element, then restores it withwindow.scrollTo(0, resolver.suspendedScrollY)(node_modules/framer-motion/dist/es/render/utils/KeyframesResolver.mjs:41). That measurement only happens for keyframes it cannot resolve statically,height: "auto"being the usual one.The component animating
height: "auto"here isDropdownSection(src/renderer/src/components/ui/DropdownSection.tsx:58), on themotion.divthat expands when its title button is clicked.Bisecting the renderer-dom project file by file, the only file that emits the line is
tests/renderer-dom/infoAndHelpPage.test.tsx. Both of its tests click "Debug info", which is theDropdownSectiononInfoAndHelpPage(src/renderer/src/features/info/pages/InfoAndHelpPage.tsx:48, mounted withstartOpen={false}). Run alone the file emits the line once across three repeats, run inside the full suite it emits it twice, so the second one is the same open animation getting far enough to resolve its keyframes under different timing rather than a second source. No other test file produced the line.While looking, the other scroll APIs in the renderer are
scrollRef.current?.scrollTo(...)inStickyMenu.tsx:177andListMods.tsx:151, both on an element and both already covered by theElement.prototype.scrollTostub the setup file has had for a while. There is noscrollIntoViewcall anywhere insrc.The fix
Stub it in
tests/renderer-dom/setup.ts, right next to the existing element stub, so every current and future test that opens a dropdown is covered in one place. The call is legitimate library behaviour and the component is doing nothing wrong, so there is no case for touchingDropdownSection.One wrinkle worth the comment that ships with it: unlike the other stubs in that file, this one cannot be guarded with
if (!window.scrollTo). jsdom does define the method, it just refuses to do anything except log. So the assignment is unconditional.Before and after
Baseline, on this branch with the setup change stashed:
After:
Same for
npx vitest run --project renderer-domon its own: two lines before, zero bytes after. No other stray stderr surfaced once this one went quiet, so there is nothing to report as observed-but-out-of-scope.Gates
npm run typecheckpasses (node, web, tests)npm run lint:ci0 errors, the same 15 pre-existingreact-hooks/exhaustive-depswarnings as ondevnpm run format:checkcleannpm run test:coverage137 files, 1633 passed, 2 skipped, coverage 92.6 / 89.84 / 92.03 / 94.05 against floors of 89 / 87 / 85 / 85