Fix the UI dying at load, and add a page smoke test

$('#prefs').onclick referenced a prefsModal that was never defined, and an
uncaught ReferenceError stops the whole script -- taking the theme toggle,
the feed filter, the event stream and loadFeeds() down with it, so the app
rendered an empty shell.

The scheduling patch had anchored on a function the rewrite already
deleted; str.replace matched nothing and said nothing.

tests/page-smoke.js executes the page against a stub DOM so this class of
failure is visible, since every server-side check passed while the UI was
completely dead. Handler wiring now skips a bad reference instead of
throwing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
This commit is contained in:
2026-09-10 02:31:18 +00:00
parent 9dc4c1ddfa
commit 9960befed5
3 changed files with 149 additions and 1 deletions

View File

@@ -56,6 +56,36 @@ and until now nothing set them.
---
## 2026-09-10 — The whole UI was dead, and server-side tests could not see it
Reported as "my feeds seem to have disappeared", then "settings and dark/light mode don't do
anything either". One cause for all three.
`$('#prefs').onclick = prefsModal` referenced a function that did not exist. An uncaught
`ReferenceError` stops the entire script, and that line sits above the theme toggle, the feed
filter, the SSE connection and the `loadFeeds()` call that fills the sidebar — so everything below
it silently never ran.
**Cause: a patch anchored on something already deleted.** The scheduling UI was inserted with
`str.replace` anchored on `function toggleSettings(){`, which belonged to the *old* basic UI that
the full rewrite had already removed. Python's replace matches nothing and says nothing, and there
was no assert — so `prefsModal`, `everyText`, `due` and `globalEvery` were never added, while the
line *calling* `prefsModal` went in fine via a different anchor that did match.
**Why it got through.** Every check was server-side: curl for status codes, JSON shape, config
contents. All passed, because the server was fine. `node --check` also passed — it parses, and a
ReferenceError is a runtime failure. The page was never executed.
`tests/page-smoke.js` now runs the real page script against a stub DOM, fails on anything thrown,
and flags handlers wired to elements that do not exist. Confirmed non-vacuous by reintroducing the
exact bug: exit 1 pointing at the offending line, clean once restored. Run it with
`node tests/page-smoke.js`.
Wiring is also defensive now — `on(sel, ev, fn)` logs and skips rather than throwing, so one dead
reference cannot blank the app again.
---
## 2026-09-10 — Scheduling, and two bugs it uncovered
**Scheduling.** The original engine had none — it only skipped feeds on `<ttl>`; the schedule lived