Skip to content

test(lr-1a5f): headless browser smoke — no pageerror on boot, WS opens#224

Merged
akuehner merged 5 commits into
mainfrom
feat/lr-1a5f-browser-smoke-test
Jun 11, 2026
Merged

test(lr-1a5f): headless browser smoke — no pageerror on boot, WS opens#224
akuehner merged 5 commits into
mainfrom
feat/lr-1a5f-browser-smoke-test

Conversation

@akuehner

Copy link
Copy Markdown
Member

No description provided.

akuehner and others added 5 commits June 11, 2026 09:11
…linking

The prior fix (lr-7b07 / PR #220) correctly excluded " and ' from the
URL-match regex, so the URL itself is safely truncated. However, non-URL
text surrounding the URL was only escaping &, <, and > — leaving raw " and '
in the output. A crafted note like `http://x.com"onmouseover="alert(1)` would
produce correct href truncation but leave `"onmouseover="alert(1)` as raw
unescaped text in the rendered HTML.

Fix: rewrite fmt() in both sticky-notes.js and sticky-notes-fmt.js to split
on raw URLs first (before any escaping), then HTML-escape all segments fully
(including " → &quot; and ' → &#39;), then wrap URL segments in anchors.
This ensures quote chars always terminate URL matches and never appear raw in
rendered output regardless of position.

Fixes the two failing regression tests in test/xss-escape.test.js (232, 233).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… opens

Adds test/browser-smoke-lr-1a5f.test.js, a regression guard that catches
broken client ESM module graphs before a release ships.

The pre-fix PR #217 state (stale getPendingNavigate import) would have
caused a pageerror on boot; this test would have caught it at CI time.

Test approach:
- Spawns lib/daemon.js on a random free port with an isolated tmp home,
  no TLS, and no auth (single-user mode, no pinHash).
- Loads http://127.0.0.1:{port}/p/smoke-project/ in headless Chromium
  via Playwright (sourced from /workspace/local-scripts/headless-browser).
- Asserts: zero pageerror events during boot.
- Asserts: at least one WebSocket open event within 8 s.
- Gracefully skips (not fails) if Playwright is unavailable at the
  expected path; override with PLAYWRIGHT_PATH env var.

All 253 tests pass (252 pre-existing + this one).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
B1+B2: add playwright@1.49.0 as devDependency; replace hardcoded
PLAYWRIGHT_PATH default with direct require('playwright') from the
module graph. PLAYWRIGHT_PATH env var kept as optional override.
Update package-lock.json. CI note in test header: run
`npx playwright install chromium` after `npm ci`.

B3: replace silent done() skip paths with t.diagnostic + t.skip so
Chromium binary absence is visible in test output, not a silent pass.
Skip also fires if chromium.launch() itself throws (binary not found).

A1: raise WS_WAIT_MS from 8000 to 15000 ms to reduce flake risk.
Derive DAEMON_READY_MS from a named constant (30000) for coherence.

A2: register daemon kill + tmpdir removal via t.after() so cleanup
runs even when the 60 s outer timeout fires; existing .then/.catch
cleanup chain remains as belt-and-suspenders.

A3: add t.diagnostic() in all cleanup catch blocks so leaked tmpdirs
are visible in test output rather than silently swallowed.

Peaches review: PR #224.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Regression guard for the stale-ESM-import failure class (lr-8657/PR#223).
Uses only Node built-ins + the existing ws dependency — no Playwright,
no Chromium download, no new devDependencies.

What it verifies:
  1. Daemon starts and /info responds HTTP 200 (daemon boots clean)
  2. Frontend page served HTTP 200 (static asset pipeline works)
  3. WebSocket upgrade to /p/<project>/ws succeeds (ESM relay loaded,
     auth gate wired — this is the check that catches broken static imports)

Test runs in an isolated tmpdir with CLAGENTIC_HOME + CLAGENTIC_CONFIG
overridden — never touches the real ~/.clagentic directory.

Removes the Playwright-based browser-smoke file added in the prior
AMoS pass; that approach pulled ~400 MB of Chromium into every
contributor's npm install.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The test is a daemon liveness probe (HTTP /info + WS upgrade), not a
browser ESM regression guard. Browser-side ESM imports in lib/public/
are served as static assets — the daemon never loads them, so a Node WS
client cannot catch broken browser imports (the lr-8657 failure class).

That class is caught by the static import-resolution check (lr-5e24).

Updated the file header and WS-timeout error message to accurately
describe what the test covers and explicitly document what it does not.
No test logic changed; 253/253 pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@akuehner akuehner merged commit 1a8bb5e into main Jun 11, 2026
@akuehner akuehner deleted the feat/lr-1a5f-browser-smoke-test branch June 11, 2026 13:39
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