fix: wrap rich-text fields in <p> so TM renders special characters correctly - #356
fix: wrap rich-text fields in <p> so TM renders special characters correctly#356SavioBS629 wants to merge 4 commits into
Conversation
…al chars TM's v2 API entity-encodes <, > and & in step/result, preconditions and description on write, and the TM UI renders those fields as rich text only when the value is HTML-wrapped — bare text is displayed literally, so a plain ">" surfaced to users as ">" (PMAA-185, FD 1709260, TM-26634). Per the TM team, external API content must be wrapped in <p> tags. Wrap those fields on createTestCase and updateTestCase when the value is not already HTML and contains an encodable character; all other payloads are sent unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SavioBS629
left a comment
There was a problem hiding this comment.
Claude Code Review (automated) — 3 inline finding(s). Full report in the PR comment below. Verdict: Failed - see PR comment.
| if (LOOKS_LIKE_HTML.test(text) || !HAS_ENCODABLE_CHARS.test(text)) { | ||
| return text; | ||
| } | ||
| return `<p>${text}</p>`; |
There was a problem hiding this comment.
[High] Wrapping bare text without escaping lets TM strip tag-like tokens (data loss)
Once wrapped in <p>, TM's sanitizer treats the value as HTML and strips unknown tag-like tokens entirely: Press <Enter> to submit the form is stored as Press to submit the form; List<String>, <username>, <input> vanish the same way (verified live: TC-5368849 in sandbox PR-148108). Pre-PR these inputs were entity-encoded and lossless.
Suggestion: escape the bare text before wrapping — `<p>${text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</p>`. Verified live that this round-trips byte-identically and renders correctly (TC-5368865).
Reviewer: review (built-in fallback)
| @@ -0,0 +1,20 @@ | |||
| // TM UI renders these fields as rich text only when HTML-wrapped; | |||
| const LOOKS_LIKE_HTML = /^\s*<[a-z][^>]*>/i; | |||
There was a problem hiding this comment.
[Medium] LOOKS_LIKE_HTML misclassifies leading tag-like tokens as HTML
"<Enter> key submits the form" matches /^\s*<[a-z][^>]*>/i, so it is passed through bare and TM's sanitizer strips <Enter> — same data loss via a different path.
Suggestion: only treat input as HTML when it starts with a known rich-text tag (p|br|ul|ol|li|b|i|em|strong|u|a|span|div|table); otherwise escape-and-wrap.
Reviewer: review (built-in fallback)
| @@ -0,0 +1,20 @@ | |||
| // TM UI renders these fields as rich text only when HTML-wrapped; | |||
There was a problem hiding this comment.
[Low] Truncated comment with trailing whitespace
The comment ends mid-sentence ("…only when HTML-wrapped; ").
Suggestion: complete the sentence: bare text displays TM's entity-encoding literally in the UI, hence the wrap.
Reviewer: review (built-in fallback)
Claude Code PR ReviewPR: #356 • Head: cc3a498 • Reviewers: review (built-in fallback; no in-scope project reviewers discovered) SummaryWraps TM rich-text fields (step/result, preconditions, description) in Review Table
Findings
Verdict: FAIL — one High data-loss finding; fix is a two-line escape before wrapping, verified against the live TM API. |
…own editor TM's sanitizer (Sanitize.fragment with RTE_ALLOWED_CONTENT) strips unknown tag-like tokens inside HTML values, so wrapping unescaped text lost content like "<Enter>" or "List<String>". TM's own Lexical editor and import paths escape text then wrap in <p>; do the same, and pass through only values that start with a tag from TM's allowed-elements list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude Code PR ReviewContinues the previous review — changes since PR: #356 • Head: aca16d4 • Reviewers: review (built-in fallback; no in-scope project reviewers discovered) SummaryDelta adds entity-escaping before the Review Table
Findings
Note (informational, not a finding): bare text is now treated strictly as literal text — a client that pre-encodes Verdict: PASS — all three prior findings resolved and verified against the live TM API; no new findings in the delta. |
Summary
Fixes PMAA-185 (FD 1709260, originally TM-26634): test cases created/updated via MCP displayed
>as the literal text>in the TM UI.Root cause
TM's v2 API entity-encodes
<,>and&in step/result, preconditions and description on write, and the TM UI renders those fields as rich text only when the value is HTML-wrapped — bare text is displayed literally. The MCP server sent bare text, so a plain>surfaced to users as>. Confirmed with the TM team: external API content must be wrapped in<p>tags (their supported contract).Fix
New
rich-text.tshelper wraps a value in<p>…</p>when it is not already HTML and contains an encodable character (<,>,&). Applied totest_case_steps(step + result),preconditionsanddescriptionincreateTestCase(v1 and v2 paths) andupdateTestCase. Payloads without encodable characters, and values that are already HTML, are sent unchanged.Verification
Settings > Users→ storedSettings > Users→ UI shows literal>(bug, repro TC-5315740 / TC-5352932 via plain curl, no MCP involved)<p>Settings > Users</p>→ stored<p>Settings > Users</p>→ UI rendersSettings > Userscorrectly (TC-5358753, confirmed by TM team screenshot)tscand eslint clean.🤖 Generated with Claude Code