fix(deploy): copy error text verbatim, never re-parse it as HTML

Merged
DO
3d ago
+72-7

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 criterionCovered by
1. Both files use the direct handler; neither contains d.innerHTML=this.dataset.copyDiff; plus a new Jest test that reads deploy/index.html and fails if the inlined copy regresses
2. Replace the test asserting the buggy handlersrc/deploy/tests/index.test.js: asserts the direct handler, no innerHTML/textContent, and that data-copy still holds &lt;script&gt;
3. DOM-level test: exact string reaches the clipboard, window.__pwned stays undefineddeploy/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 passLocal: 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.