Skip to content

Clean all web warnings: eliminate vitest console noise + build/autofixer issues - #48

Merged
Aztec03hub merged 1 commit into
mainfrom
cleanup-web-warnings
Jun 26, 2026
Merged

Clean all web warnings: eliminate vitest console noise + build/autofixer issues#48
Aztec03hub merged 1 commit into
mainfrom
cleanup-web-warnings

Conversation

@Aztec03hub

Copy link
Copy Markdown
Owner

Goal

Bring the web side (web/) to a clean state: zero vitest unhandled errors, a clean test console, a clean vite build, and zero real svelte-autofixer issues.

What was wrong (analysis)

vitest console noise (real — invisible in a naive pnpm test tail; the default reporter prints test console output to stderr)

Warning Source Count Verdict
[claude-comms] /api/conversations bootstrap failed {…} (console.warn) mqtt-store-bootstrap.spec.js 4 intentional error-path test leaking its diagnostic into the suite console
[svelte] derived_inert (read of a derived from a now-destroyed effect) channel-modal-wires.spec.js (+ channel-modal-bugfix.spec.js) ~26–60 (intermittent) bits-ui Dialog teardown timing artifact
expected undefined to be truthy (flake, ~1/5 runs) history-status-normalization.spec.js intermittent timing race on a fixed 10ms wait for an async #fetchHistory

vite build

Already clean — exit 0, no warnings (largest chunk vendor-ui 425 kB < the 500 kB default limit).

svelte-autofixer (all 56 components + 5 .svelte.js modules + App.svelte)

Grep pre-screen + targeted autofixer runs. No Svelte 4 syntax (on:, export let, <slot>, $:) anywhere. $effect usages are all genuine side-effects (localStorage sync, focus/teardown, element measurement, IntersectionObserver, timers, dev warn) — several already comment that the "should be $derived" suggestion does not apply. Real issues found:

  • ReadReceipt.sveltetooltipText = $derived(() => {…}) passed a function to $derived (should be $derived.by) and was dead code (never referenced; the template inlines the logic). Plus an unkeyed {#each}.
  • EmojiPicker.svelte / SearchPanel.svelte — unkeyed {#each} over static lists.

What changed

  • mqtt-store-bootstrap.spec.js — spy + silence the intentional bootstrap-failed console.warn; assert the warning fired (strengthens, not weakens).
  • history-status-normalization.spec.js — poll-until-present helper replaces the fixed 10ms wait. No assertion weakened.
  • ReadReceipt.svelte — removed the dead malformed $derived; keyed the each.
  • EmojiPicker.svelte / SearchPanel.svelte — keyed the static each blocks.

The derived_inert warning is resolved by the bits-ui scroll-lock drain in tests/setup.js from #46 (picked up on rebase), so no console filter is needed — confirmed across 4 full runs with no suppression.

Before / after

Gate Before After
pnpm --dir web test green, but intermittent flake → exit 1 exit 0, deterministic
vitest stderr / console 4 bootstrap failed + ~26–60 derived_inert + flake 0 lines of stderr (verified across multiple runs)
pnpm --dir web build clean clean
svelte-autofixer real issues 4 0

Intentionally-left autofixer advisories (documented): bind:this (19 components — idiomatic DOM refs for focus/scroll/measure) and "assign inside $effect" on side-effecting effects (e.g. ArtifactList's reconcile writes to localStorage, so it must stay an effect — the autofixer itself hedges this one).

No Python touched (src/claude_comms/**.py / pyproject unchanged).

🤖 Generated with Claude Code

…sues

- mqtt-store-bootstrap.spec.js: spy and silence the intentional
  '/api/conversations bootstrap failed' console.warn from the error-path
  tests; assert the warning fired so suppression never hides a regression.
- history-status-normalization.spec.js: poll for the async fetchHistory
  result instead of a fixed 10ms wait, removing an intermittent flake.
- ReadReceipt.svelte: remove dead, malformed $derived (it passed a
  function to $derived and was never referenced); key the each block.
- EmojiPicker.svelte / SearchPanel.svelte: add keys to static each blocks.

The bits-ui Dialog 'derived_inert' teardown warning is resolved by the
scroll-lock drain in tests/setup.js (#46), so no console filter is needed.
@Aztec03hub
Aztec03hub merged commit c0a3a44 into main Jun 26, 2026
8 checks passed
Aztec03hub added a commit that referenced this pull request Jun 26, 2026
…e import/jsdom overhead (#52)

The web unit-test suite's cost was dominated by per-file overhead, not test
logic: the same module graph (App, mqtt-store, components, bits-ui, the
lucide-svelte icon barrel) was re-imported and re-executed, and a fresh jsdom
environment was created, for every one of the 94 spec files.

Switch the bulk of the suite to vitest's vmThreads pool, which runs each spec
file in its own fresh V8 VM context (full per-file isolation, no cross-file
state leakage) while reusing the worker's compiled-module cache across files.

The three specs that replace the whole window/location global object (not just
define a property on it) cannot run under vmThreads, where those globals are
non-configurable; they are routed to a standard threads project via
test.projects. No test assertions or test code changed.

Measured (matched-load A/B, 3 runs each):
  wall        ~51s  -> ~32s   (-37%)
  duration    ~47s  -> ~30s
  import      ~240s -> ~174s
  environment  ~46s -> ~5.4s  (-88%)
  transform    ~71s -> ~64s
  tests        ~16s -> ~12s

Still 94 files / 1292 tests pass with 0 unhandled errors and 0 stderr noise
(verified 5 consecutive runs). The bits-ui scroll-lock drain in tests/setup.js
(PR #46) and the clean output (PR #48) are preserved.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant