test: keep the unit suite off the network - #296
Merged
Merged
Conversation
What: every 'npm test' run printed ~30 lines of ECONNREFUSED / AbortError / AsyncTaskManager stack traces. All tests passed, so nobody looked. Why: two sources. (1) happy-dom is a real resource loader: <link rel="stylesheet"> and <iframe src> fixtures in sanitizer, feed-service and discovery tests made it open sockets to localhost:3000 and https://evil.com. (2) tests/pages/billing-success.test.tsx rendered with a session_id, which fires the page's /api/license/retrieve fetch on mount, in three tests that never stubbed fetch. Nothing awaited either, so the suite stayed green while doing real network I/O — a direct violation of the no-network rule for unit tests. Fix: vitest.config.js disables CSS/JS file loading and iframe page loading via environmentOptions.happyDOM.settings; billing-success gets a file-level pending fetch stub plus an assertion that the page requests the session's license. A disabled iframe load still prints one NotSupportedError line per fixture (happy-dom's unconditional console.error) — four lines, deterministic, documented. Prevention: tests/environment/no-real-network.test.ts spies node:http(s) request and asserts a stylesheet link and an iframe insert never reach it; CLAUDE.md happy-dom gotchas record the setting and the fetch-stub rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GQoLHbPfaTCHvPuaoqGZeJ
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
forcingfx
enabled auto-merge (squash)
September 9, 2026 20:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Every
npm testrun printed ~30 lines ofECONNREFUSED/AbortError/AsyncTaskManager has been destroyedstack traces. All tests passed, so it went unnoticed.Why
Two sources, attributed by temporarily wrapping
node:http.requestto name the running test:<link rel="stylesheet">and<iframe src>fixtures insanitizer.test.js,feed-service.test.jsandstrategies.test.jsmade it open sockets tolocalhost:3000andhttps://evil.com.billing-success.test.tsxrendered with asession_id, which fires the page's/api/license/retrievefetch on mount, in three tests that never stubbedfetch.Nothing awaited either, so the suite stayed green while doing real network I/O.
Fix
vitest.config.js:environmentOptions.happyDOM.settingsdisables CSS/JS file loading and iframe page loading.billing-success.test.tsx: file-level pendingfetchstub, plus an assertion that the page requests the session's license (the behaviour those tests were silently exercising).A disabled iframe load still prints one
NotSupportedErrorline per fixture (happy-dom's unconditionalconsole.error, 4 lines total). Silencing those would need a fetch interceptor that changes semantics for every unstubbed page fetch; not worth it.Prevention
tests/environment/no-real-network.test.tsspiesnode:http(s).requestand asserts a stylesheet link and an iframe insert never reach it (red before the config change).Verification
npx tsc --noEmit: clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01GQoLHbPfaTCHvPuaoqGZeJ