@@ -12,6 +12,12 @@ public sealed class LearnFidelityTests(StandaloneAppFixture fixture)
1212 private readonly record struct ContextGapMeasurement ( double LeftGapPx , double RightGapPx ) ;
1313 private readonly record struct ContextRailClipMeasurement ( double LeftClipPx , double RightClipPx ) ;
1414 private readonly record struct FocusWordSlackMeasurement ( double SlackPx ) ;
15+ private readonly record struct ActivePhraseHighlightMeasurement (
16+ double HighlightWidthPx ,
17+ double RowWidthPx ,
18+ double WordWidthPx ,
19+ string BorderBottomStyle ,
20+ string BackgroundImage ) ;
1521 private readonly record struct OrpDeltaMeasurement ( double DeltaPx ) ;
1622 private readonly record struct VisibleContextWordGapMeasurement ( double LeftWordGapPx , double RightWordGapPx ) ;
1723
@@ -76,6 +82,38 @@ await Expect(page.GetByTestId(UiTestIds.Learn.NextPhrase))
7682 }
7783 }
7884
85+ [ Test ]
86+ public async Task LearnScreen_ActivePhraseHighlightMarksMoreThanTheCurrentWord ( )
87+ {
88+ const string scenario = "learn-active-phrase-highlight" ;
89+ const string step = "active-phrase-highlight" ;
90+ var page = await fixture . NewPageAsync ( additionalContext : true ) ;
91+
92+ try
93+ {
94+ UiScenarioArtifacts . ResetScenario ( scenario ) ;
95+
96+ await ReaderRouteDriver . OpenLearnAsync ( page , BrowserTestConstants . Routes . LearnDemo ) ;
97+ await Expect ( page . GetByTestId ( UiTestIds . Learn . Page ) )
98+ . ToBeVisibleAsync ( new ( ) { Timeout = BrowserTestConstants . Timing . ExtendedVisibleTimeoutMs } ) ;
99+ await Expect ( page . GetByTestId ( UiTestIds . Learn . ActivePhraseHighlight ) ) . ToBeVisibleAsync ( ) ;
100+ await WaitForLearnLayoutReadyAsync ( page ) ;
101+
102+ var measurement = await MeasureActivePhraseHighlightAsync ( page ) ;
103+
104+ await Assert . That ( measurement . HighlightWidthPx > measurement . WordWidthPx * 1.45 ) . IsTrue ( ) . Because ( $ "Expected the RSVP active phrase highlight to span beyond only the current word, but highlight={ measurement . HighlightWidthPx : 0.##} px and word={ measurement . WordWidthPx : 0.##} px.") ;
105+ await Assert . That ( measurement . HighlightWidthPx <= measurement . RowWidthPx ) . IsTrue ( ) . Because ( $ "Expected the RSVP active phrase highlight to stay inside the focus row, but highlight={ measurement . HighlightWidthPx : 0.##} px and row={ measurement . RowWidthPx : 0.##} px.") ;
106+ await Assert . That ( measurement . BorderBottomStyle ) . IsEqualTo ( "solid" ) ;
107+ await Assert . That ( measurement . BackgroundImage ) . IsNotEqualTo ( "none" ) ;
108+
109+ await UiScenarioArtifacts . CapturePageAsync ( page , scenario , step ) ;
110+ }
111+ finally
112+ {
113+ await page . Context . CloseAsync ( ) ;
114+ }
115+ }
116+
79117 [ Test ]
80118 public async Task LearnScreen_DemoContextRails_ShowTwoWordsPerSideWithoutRightRailClipping ( )
81119 {
@@ -462,6 +500,44 @@ private static Task<ContextGapMeasurement> MeasureContextGapsAsync(Microsoft.Pla
462500 right = UiTestIds . Learn . ContextRight
463501 } ) ;
464502
503+ private static Task < ActivePhraseHighlightMeasurement > MeasureActivePhraseHighlightAsync ( Microsoft . Playwright . IPage page ) =>
504+ page . EvaluateAsync < ActivePhraseHighlightMeasurement > (
505+ """
506+ ids => {
507+ const highlight = document.querySelector(`[data-test="${ids.highlight}"]`);
508+ const row = document.querySelector(`[data-test="${ids.row}"]`);
509+ const word = document.querySelector(`[data-test="${ids.word}"]`);
510+ if (!highlight || !row || !word) {
511+ return {
512+ highlightWidthPx: 0,
513+ rowWidthPx: 0,
514+ wordWidthPx: 0,
515+ borderBottomStyle: '',
516+ backgroundImage: 'none'
517+ };
518+ }
519+
520+ const highlightRect = highlight.getBoundingClientRect();
521+ const rowRect = row.getBoundingClientRect();
522+ const wordRect = word.getBoundingClientRect();
523+ const style = getComputedStyle(highlight);
524+
525+ return {
526+ highlightWidthPx: highlightRect.width,
527+ rowWidthPx: rowRect.width,
528+ wordWidthPx: wordRect.width,
529+ borderBottomStyle: style.borderBottomStyle,
530+ backgroundImage: style.backgroundImage
531+ };
532+ }
533+ """ ,
534+ new
535+ {
536+ highlight = UiTestIds . Learn . ActivePhraseHighlight ,
537+ row = UiTestIds . Learn . FocusRow ,
538+ word = UiTestIds . Learn . Word
539+ } ) ;
540+
465541 private static Task < VisibleContextWordGapMeasurement > MeasureVisibleContextWordGapsAsync ( Microsoft . Playwright . IPage page ) =>
466542 page . EvaluateAsync < VisibleContextWordGapMeasurement > (
467543 """
0 commit comments