@@ -72,13 +72,17 @@ export function DiagnosisView({
7272 } ;
7373 } , [ services , testResults ] ) ;
7474
75+ const reportMarkdown = useMemo (
76+ ( ) =>
77+ hasResults && ! isRunning
78+ ? renderReportMarkdown ( services , testResults )
79+ : "" ,
80+ [ hasResults , isRunning , services , testResults ] ,
81+ ) ;
82+
7583 const handleCopyReport = async ( ) => {
7684 try {
77- // Rendered on demand: the full report is only needed on copy, not on
78- // every per-method result update during a run.
79- await navigator . clipboard . writeText (
80- renderReportMarkdown ( services , testResults ) ,
81- ) ;
85+ await navigator . clipboard . writeText ( reportMarkdown ) ;
8286 setCopied ( true ) ;
8387 setTimeout ( ( ) => setCopied ( false ) , 1500 ) ;
8488 } catch {
@@ -92,7 +96,7 @@ export function DiagnosisView({
9296 // Copy the report to the clipboard first as a fallback if the body is
9397 // truncated.
9498 const handleSubmitReport = ( ) => {
95- const report = renderReportMarkdown ( services , testResults ) ;
99+ const report = reportMarkdown ;
96100 void navigator . clipboard ?. writeText ( report ) . catch ( ( ) => { } ) ;
97101 const url = reportIssueUrl ( report , detectHostMode ( ) ) ;
98102 try {
@@ -123,11 +127,12 @@ export function DiagnosisView({
123127 < span className = "panel__label" > About</ span >
124128 </ div >
125129 < p className = "panel__desc" >
126- Runs every TrUAPI method against the connected host to build a coverage
127- report — which methods work, which fail, and which aren't wired
128- yet. Methods run one at a time, in order; those that need your approval
129- (signing, permission and resource requests) wait on your response
130- before the run continues. When it finishes, copy the report below.
130+ Runs every TrUAPI method against the connected host to build a
131+ coverage report — which methods work, which fail, and which
132+ aren't wired yet. Methods run one at a time, in order; those that
133+ need your approval (signing, permission and resource requests) wait on
134+ your response before the run continues. When it finishes, copy the
135+ report below.
131136 </ p >
132137 < p className = "diag__callout" >
133138 Before you start: make sure you are < strong > logged in</ strong > , and
@@ -145,24 +150,38 @@ export function DiagnosisView({
145150 Stop
146151 </ button >
147152 ) : (
148- < button type = "button" className = "btn btn--primary" onClick = { onRun } >
153+ < button
154+ type = "button"
155+ className = "btn btn--primary"
156+ data-testid = "diagnosis-run"
157+ onClick = { onRun }
158+ >
149159 < span className = "btn__glyph" > ▶</ span >
150160 Run diagnosis
151161 </ button >
152162 ) }
153163 { hasResults && (
154164 < span
155165 className = "autotest__summary"
166+ data-testid = "diagnosis-summary"
156167 data-has-fail = { ! isRunning && failCount > 0 }
157168 >
158169 { passCount } success · { failCount } failed
159170 </ span >
160171 ) }
161172 { hasResults && ! isRunning && (
162173 < div className = "diag__report-actions" >
174+ < pre
175+ hidden
176+ data-testid = "diagnosis-report-markdown"
177+ data-report-ready = { reportMarkdown . length > 0 }
178+ >
179+ { reportMarkdown }
180+ </ pre >
163181 < button
164182 type = "button"
165183 className = "autotest__report-copy"
184+ data-testid = "diagnosis-copy-report"
166185 onClick = { handleCopyReport }
167186 >
168187 { copied ? "Copied ✓" : "Copy report" }
@@ -188,6 +207,7 @@ export function DiagnosisView({
188207 < div key = { r . id } >
189208 < div
190209 className = "diag__row"
210+ data-testid = "diagnosis-row"
191211 data-status = { r . status }
192212 data-expandable = { expandable }
193213 onClick = {
0 commit comments