@@ -5,7 +5,7 @@ import type { RuntimeChatItem } from "@/renderer/state/slices/runtimeEventSlice"
55import { ToolCall } from "./ToolCall" ;
66
77describe ( "ToolCall — Claude View (Read) rich rendering" , ( ) => {
8- it ( "syntax-highlights the file body and strips the LLM line-number prefixes " , async ( ) => {
8+ it ( "renders the rich file body directly without args/result labels " , async ( ) => {
99 const item : RuntimeChatItem = {
1010 id : "toolu_read" ,
1111 type : "tool_call" ,
@@ -29,13 +29,17 @@ describe("ToolCall — Claude View (Read) rich rendering", () => {
2929 fireEvent . click ( getDisclosureTrigger ( ) ) ;
3030
3131 const resultViewport = await waitFor ( ( ) => {
32- const viewport = getSectionViewport ( "result" ) ;
32+ const viewport = findRichViewport ( ) ;
3333 if ( ! viewport . classList . contains ( "lc-shiki" ) ) {
34- throw new Error ( "result viewport not yet highlighted" ) ;
34+ throw new Error ( "read viewport not yet highlighted" ) ;
3535 }
3636 return viewport ;
3737 } ) ;
3838
39+ // No labeled args/result headers — only the rich view of the file body.
40+ expect ( findSectionHeader ( "args" ) ) . toBeNull ( ) ;
41+ expect ( findSectionHeader ( "result" ) ) . toBeNull ( ) ;
42+
3943 // The "1: " / "2: " line-number prefixes that the read tool emits should
4044 // be stripped before highlighting.
4145 expect ( resultViewport . textContent ) . toContain ( "import { useEffect }" ) ;
@@ -72,16 +76,19 @@ describe("ToolCall — Claude View (Read) rich rendering", () => {
7276 fireEvent . click ( getDisclosureTrigger ( ) ) ;
7377
7478 const resultViewport = await waitFor ( ( ) => {
75- const viewport = getSectionViewport ( "result" ) ;
79+ const viewport = findRichViewport ( ) ;
7680 if ( ! viewport . textContent ?. includes ( "plain note body" ) ) {
77- throw new Error ( "result viewport not populated yet" ) ;
81+ throw new Error ( "read viewport not populated yet" ) ;
7882 }
7983 return viewport ;
8084 } ) ;
8185
82- // Result viewport for an unknown language stays in a plain <pre>, not the
83- // Shiki container. The args section (JSON) may still be highlighted —
84- // that's expected and irrelevant to this assertion.
86+ // No labeled args/result headers — only the rich view of the file body.
87+ expect ( findSectionHeader ( "args" ) ) . toBeNull ( ) ;
88+ expect ( findSectionHeader ( "result" ) ) . toBeNull ( ) ;
89+
90+ // A read result with an unknown language renders in a plain <pre>, not the
91+ // Shiki container.
8592 expect ( resultViewport . tagName . toLowerCase ( ) ) . toBe ( "pre" ) ;
8693 expect ( resultViewport . classList . contains ( "lc-shiki" ) ) . toBe ( false ) ;
8794 } ) ;
@@ -95,17 +102,17 @@ function getDisclosureTrigger(): HTMLElement {
95102 return trigger ;
96103}
97104
98- function getSectionViewport ( label : string ) : HTMLElement {
99- const headers = Array . from ( document . querySelectorAll ( "div" ) ) . filter (
100- ( el ) => el . textContent ?. trim ( ) === label ,
105+ function findSectionHeader ( label : string ) : HTMLElement | null {
106+ return (
107+ Array . from ( document . querySelectorAll ( "div" ) ) . find ( ( el ) => el . textContent ?. trim ( ) === label ) ??
108+ null
101109 ) ;
102- const header = headers [ 0 ] ;
103- if ( ! header ) {
104- throw new Error ( `section label "${ label } " not found` ) ;
105- }
106- const viewport = header . nextElementSibling ;
107- if ( ! ( viewport instanceof HTMLElement ) ) {
108- throw new Error ( `viewport sibling for section "${ label } " not found` ) ;
109- }
110+ }
111+
112+ function findRichViewport ( ) : HTMLElement {
113+ const body = document . querySelector ( '[data-slot="disclosure-body"]' ) ;
114+ if ( ! ( body instanceof HTMLElement ) ) throw new Error ( "disclosure body not found" ) ;
115+ const viewport = body . querySelector ( ".lc-shiki, pre" ) ;
116+ if ( ! ( viewport instanceof HTMLElement ) ) throw new Error ( "rich viewport not found" ) ;
110117 return viewport ;
111118}
0 commit comments