fix(deploy): copy error text verbatim, never re-parse it as HTML
Closes #595
What
The deploy page's ๐ Copy error button set a detached div's innerHTML to this.dataset.copy and copied its textContent. The browser has already decoded the entity-escaped data-copy attribute, so this parsed the raw error text as HTML a second time:
- copied stack traces lost anything tag-like (
<anonymous>,List<T>, โฆ) - markup in an error ran on click (a detached
<img src=x onerror=โฆ>still loads and fires)
The handler is now navigator.clipboard.writeText(this.dataset.copy). data-copy stays HTML-escaped, which is correct for an attribute.
deploy/index.html is a hand-kept mirror of src/deploy/index.js, not generated from it, so both copies change.
Tests
| Acceptance criterion | Covered by |
|---|---|
1. Both files use the direct handler; neither contains d.innerHTML=this.dataset.copy | Diff; plus a new Jest test that reads deploy/index.html and fails if the inlined copy regresses |
| 2. Replace the test asserting the buggy handler | src/deploy/tests/index.test.js: asserts the direct handler, no innerHTML/textContent, and that data-copy still holds <script> |
3. DOM-level test: exact string reaches the clipboard, window.__pwned stays undefined | deploy/tests/ui.spec.js (Playwright, real Chromium, against the shipped deploy/index.html). Renders a stack with <tag>, <anonymous>, List<T>, <script> and <img onerror>, clicks Copy with a stubbed clipboard, and checks the exact string. A control <img onerror> in a detached div proves the payload would fire in this browser, then asserts __pwned is still undefined. Fails against main. |
| 4. Existing deploy UI tests pass | Local: Jest 504/504, Playwright 98/98 |
Playwright stands in for the jsdom test the issue suggests: the repo has no jest-environment-jsdom, and Playwright exercises the inlined page that actually ships.
Local checks: npm run check (prettier + eslint: 0 errors, 22 pre-existing warnings outside these files), npm run typecheck, npm test -- --coverage, npx playwright test.
No .github/workflows/ changes (#480).
๐ค Generated with Claude Code
Problem
See the linked issue.
Risk
Low โ 4 file(s) changed; no CI- or runtime-critical paths touched.
Test plan
Tests added/updated: deploy/tests/ui.spec.js,src/deploy/tests/index.test.js. Verification: bash scripts/dev-lead-lint.sh (shellcheck --severity=warning) ran pre-commit; the bats suite runs in CI.
Rollback
Revert this PR. No non-revertible side effects (no tags, migrations, or external state).
Monitoring
This PR's CI checks (Lint + bats) are the success/regression signal.
Summary by CodeRabbit
-
Bug Fixes
- Deployment error details now copy the exact original text, including HTML-like and script content, without interpreting it as HTML.
- Copying deployment error details works consistently in both the deployed page and the application interface, preserving the displayed stack trace content.
-
Tests
- Added regression coverage verifying that stack traces are preserved when copied, including content that resembles HTML or scripts.