@@ -249,6 +249,30 @@ window.ProbeRender = (function () {
249249 }
250250 document . addEventListener ( 'keydown' , onKey ) ;
251251 } ) ;
252+
253+ // Click handler for truncated expected pills
254+ document . addEventListener ( 'click' , function ( e ) {
255+ var target = e . target . closest ( '[data-full-expected]' ) ;
256+ if ( ! target ) return ;
257+ var full = target . getAttribute ( 'data-full-expected' ) ;
258+ var html = '<button class="probe-modal-close" title="Close">×</button>' ;
259+ html += '<div class="probe-label">Expected</div>' ;
260+ html += '<span style="' + pillCss + 'cursor:default;background:' + EXPECT_BG + ';font-size:13px;white-space:normal;line-height:1.5;">' + escapeAttr ( full ) + '</span>' ;
261+ var overlay = document . createElement ( 'div' ) ;
262+ overlay . className = 'probe-modal-overlay' ;
263+ var modal = document . createElement ( 'div' ) ;
264+ modal . className = 'probe-modal' ;
265+ modal . style . maxWidth = '420px' ;
266+ modal . style . whiteSpace = 'normal' ;
267+ modal . style . minWidth = '200px' ;
268+ modal . innerHTML = html ;
269+ overlay . appendChild ( modal ) ;
270+ document . body . appendChild ( overlay ) ;
271+ modal . querySelector ( '.probe-modal-close' ) . addEventListener ( 'click' , function ( ) { overlay . remove ( ) ; } ) ;
272+ overlay . addEventListener ( 'click' , function ( ev ) { if ( ev . target === overlay ) overlay . remove ( ) ; } ) ;
273+ function onKey ( ev ) { if ( ev . key === 'Escape' ) { overlay . remove ( ) ; document . removeEventListener ( 'keydown' , onKey ) ; } }
274+ document . addEventListener ( 'keydown' , onKey ) ;
275+ } ) ;
252276 }
253277
254278 // ── Test ID → doc page URL mapping ─────────────────────────────
@@ -504,6 +528,21 @@ window.ProbeRender = (function () {
504528 return '<span style="' + pillCss + cursor + 'background:' + bg + ';' + border + '"' + extra + '>' + label + '</span>' ;
505529 }
506530
531+ var EXPECTED_TRUNCATE = 20 ;
532+ function expectedPill ( bg , fullLabel ) {
533+ var visible = fullLabel . replace ( / \u200B / g, '' ) ;
534+ if ( visible . length <= EXPECTED_TRUNCATE ) {
535+ return '<span style="' + pillCss + 'cursor:default;background:' + bg + ';">' + fullLabel + '</span>' ;
536+ }
537+ var count = 0 , cutIdx = 0 ;
538+ for ( var ci = 0 ; ci < fullLabel . length && count < EXPECTED_TRUNCATE - 3 ; ci ++ ) {
539+ if ( fullLabel [ ci ] !== '\u200B' ) count ++ ;
540+ cutIdx = ci + 1 ;
541+ }
542+ var label = fullLabel . substring ( 0 , cutIdx ) + '\u2026' ;
543+ return '<span style="' + pillCss + 'cursor:pointer;background:' + bg + ';" data-full-expected="' + escapeAttr ( fullLabel ) + '">' + label + '</span>' ;
544+ }
545+
507546 function verdictBg ( v ) {
508547 return v === 'Pass' ? PASS_BG : v === 'Warn' ? WARN_BG : FAIL_BG ;
509548 }
@@ -777,7 +816,7 @@ window.ProbeRender = (function () {
777816 var isUnscored = first . scored === false ;
778817 var opacity = isUnscored ? 'opacity:0.55;' : '' ;
779818 var sepCls = i === unscoredStart ? ' probe-unscored-sep' : '' ;
780- t += '<td data-test-label="' + escapeAttr ( shortLabels [ i ] ) + '" class="' + sepCls + '" style="text-align:center;padding:3px 4px;' + opacity + '">' + pill ( EXPECT_BG , first . expected . replace ( / o r c l o s e / g, '/\u2715' ) . replace ( / \/ / g, '/\u200B' ) ) + '</td>' ;
819+ t += '<td data-test-label="' + escapeAttr ( shortLabels [ i ] ) + '" class="' + sepCls + '" style="text-align:center;padding:3px 4px;' + opacity + '">' + expectedPill ( EXPECT_BG , first . expected . replace ( / o r c l o s e / g, '/\u2715' ) . replace ( / \/ / g, '/\u200B' ) ) + '</td>' ;
781820 } ) ;
782821 t += '</tr>' ;
783822
0 commit comments