Skip to content

test(web): JS unit-test layer for static modules (closes #641)#760

Merged
memtomem merged 2 commits intomainfrom
feat/js-unit-tests
May 4, 2026
Merged

test(web): JS unit-test layer for static modules (closes #641)#760
memtomem merged 2 commits intomainfrom
feat/js-unit-tests

Conversation

@memtomem
Copy link
Copy Markdown
Owner

@memtomem memtomem commented May 4, 2026

Summary

  • New packages/memtomem/tests-js/ (vitest + jsdom) loads the production index.html into JSDOM, strips its <script> tags, and injects the static modules verbatim — no build step, matching how FastAPI serves them. The harness shims matchMedia (used by initTheme at top level) and serves /locales/*.json from disk so I18N boots with real translation maps.
  • Three first-cut regression guards:
  • New test-js CI job runs npm ci && npm test on Node 20; failure fails the same build as pytest.

Closes #641.

Test plan

  • npm test passes locally (5 tests in 2 files, ~470ms).
  • No unhandled JSDOM errors during script load (sibling-module identifiers used by app.js's DOMContentLoaded handler — _initTabHelp, _indexingHydrateFromServer, etc. — are stubbed pre-DCL).
  • CI test-js job runs green on this PR.
  • Future: add tests when shipping new branching logic in static modules; the orphan-render fixture is the template for "build STATE → call render → assert DOM".

Notes for reviewers

  • The harness is intentionally minimal. Tests use a real JSDOM per test (Node env) instead of vitest's shared jsdom env, because app.js carries top-level event-listener registrations and a per-file shared globalThis would leak handler state across tests.
  • STATE and I18N are top-level const in their modules, so they don't auto-populate window. The bootstrap shim in bootApp lifts them onto window so tests can mutate them. Function declarations (_renderMemorySourceTree etc.) populate window automatically per script semantics — no shim needed for those.
  • Out of scope (per the issue): full DOM E2E, visual regression, changing the no-build serving model.

🤖 Generated with Claude Code

Stand up a vitest + jsdom suite under packages/memtomem/tests-js/ for
the hand-rolled static modules in src/memtomem/web/static/. Until now
the only automated guards on those modules were locale-parity and the
i18n AST-grep — every behavioural change relied on manual sessions or
ad-hoc Playwright runs, and #587 / #595 / #639 each shipped a UI bug
whose minimal repro was a 10-line jsdom assertion.

The runner loads the production index.html into JSDOM, strips its
<script> tags, and injects requested static modules verbatim — no
build step, matching how FastAPI serves them. ``bootApp`` shims
``matchMedia`` (used by ``initTheme`` at top level) and stubs the
locale fetch from disk so ``I18N`` boots with real translation maps.

Three regression guards:
- ``_renderMemorySourceTree`` orphan rendering (#639): asserts
  ``.source-vendor-orphan`` block + user sub-tab badge counts orphans.
- empty user vendor with orphan-only sources (#639 review): asserts
  the empty-state placeholder is suppressed when orphans are real
  content.
- ``I18N.applyDOM`` ``data-i18n-placeholder`` refresh (#595): asserts
  placeholder attributes update on language change without static-key
  clobber.

CI: new ``test-js`` job runs ``npm ci && npm test`` on Node 20.
Failure fails the same build as pytest.

Co-Authored-By: Claude <[email protected]>
- Fix matchMedia comment: app.js queries 'prefers-color-scheme: light',
  not 'dark' (shim returns matches:false either way, comment-only).
- Add note next to the DCL-handler stub list so future contributors
  extend it when adding a new top-level call in app.js's
  DOMContentLoaded handler.
- Drop the unused `let dom` in render-memory-source-tree.test.mjs
  (only window/document are read inside the tests).

Co-Authored-By: Claude <[email protected]>
@memtomem memtomem merged commit c2d860a into main May 4, 2026
11 checks passed
@memtomem memtomem deleted the feat/js-unit-tests branch May 4, 2026 11:41
@github-actions github-actions Bot locked and limited conversation to collaborators May 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tooling: introduce a JS unit-test layer for mm web static modules

2 participants