@@ -16,7 +16,7 @@ public static MauiAppBuilder UseTelerikInHouseTestingService(this MauiAppBuilder
1616 IsAppUnderTest = defaultIsAppUnderTest ,
1717 TestCommandTcpPort = testCommandTcpPort
1818 } ;
19-
19+
2020 @this . Services . TryAddSingleton < ITestingService > ( instance ) ;
2121 DependencyService . RegisterSingleton < ITestingService > ( instance ) ;
2222
@@ -28,6 +28,12 @@ public static MauiAppBuilder UseTelerikInHouseTestingService(this MauiAppBuilder
2828 instance . IsAppUnderTest = true ;
2929 }
3030
31+ if ( instance . IsAppUnderTest )
32+ {
33+ SetAutomationIds ( ) ;
34+ StopScrollBarsHiding ( ) ;
35+ }
36+
3137 @this . ConfigureLifecycleEvents ( events =>
3238 {
3339#if ANDROID
@@ -42,6 +48,9 @@ public static MauiAppBuilder UseTelerikInHouseTestingService(this MauiAppBuilder
4248
4349 if ( instance . IsAppUnderTest )
4450 {
51+ SetAutomationIds ( ) ;
52+ StopScrollBarsHiding ( ) ;
53+
4554 BootUpCommandServer ( instance ) ;
4655 }
4756 } ) ;
@@ -69,7 +78,17 @@ public static MauiAppBuilder UseTelerikInHouseTestingService(this MauiAppBuilder
6978 BootUpCommandServer ( instance ) ;
7079 }
7180
72- app . Windows . Single ( ) . OverrideUserInterfaceStyle = UIKit . UIUserInterfaceStyle . Light ;
81+ if ( app . Windows . Count ( ) > 0 )
82+ {
83+ app . Windows . Single ( ) . OverrideUserInterfaceStyle = UIKit . UIUserInterfaceStyle . Light ;
84+ }
85+
86+ var window = app . ConnectedScenes . OfType < UIKit . UIWindowScene > ( ) . SelectMany ( s => s . Windows ) . FirstOrDefault ( w => w . IsKeyWindow ) ;
87+
88+ if ( window != null )
89+ {
90+ window . OverrideUserInterfaceStyle = UIKit . UIUserInterfaceStyle . Light ;
91+ }
7392
7493 return false ;
7594 } ) ;
@@ -80,6 +99,95 @@ public static MauiAppBuilder UseTelerikInHouseTestingService(this MauiAppBuilder
8099 return @this ;
81100 }
82101
102+ private static void StopScrollBarsHiding ( )
103+ {
104+ #if WINDOWS
105+ Microsoft . Maui . Handlers . ScrollViewHandler . Mapper . ModifyMapping ( nameof ( ScrollView . VerticalScrollBarVisibility ) , ( h , v , r ) =>
106+ {
107+ Microsoft . UI . Xaml . Setter settter = new Microsoft . UI . Xaml . Setter ( )
108+ {
109+ Property = Microsoft . UI . Xaml . Controls . Primitives . ScrollBar . IndicatorModeProperty ,
110+ Value = Microsoft . UI . Xaml . Controls . Primitives . ScrollingIndicatorMode . MouseIndicator
111+ } ;
112+
113+ var scroolBarType = typeof ( Microsoft . UI . Xaml . Controls . Primitives . ScrollBar ) ;
114+
115+ Microsoft . UI . Xaml . Style style = new Microsoft . UI . Xaml . Style ( ) { TargetType = scroolBarType } ;
116+ style . Setters . Add ( settter ) ;
117+
118+ var scrollView = h . PlatformView ;
119+ scrollView . Resources . Add ( scroolBarType , style ) ;
120+ } ) ;
121+ #endif
122+ }
123+
124+ private static void SetAutomationIds ( )
125+ {
126+ #if __ANDROID__ || WINDOWS
127+ Microsoft . Maui . Handlers . ViewHandler . ViewMapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
128+ Microsoft . Maui . Handlers . ContentViewHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
129+ Microsoft . Maui . Handlers . ImageButtonHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
130+ Microsoft . Maui . Handlers . LabelHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
131+ Microsoft . Maui . Handlers . LayoutHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
132+ Microsoft . Maui . Handlers . PickerHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
133+ Microsoft . Maui . Handlers . RadioButtonHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
134+ Microsoft . Maui . Handlers . ScrollViewHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
135+ Microsoft . Maui . Handlers . SearchBarHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
136+ Microsoft . Maui . Handlers . SliderHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
137+ Microsoft . Maui . Handlers . SwitchHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
138+ Microsoft . Maui . Handlers . TimePickerHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
139+ Microsoft . Maui . Handlers . DatePickerHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
140+ Microsoft . Maui . Handlers . ButtonHandler . Mapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
141+ Maui . Handlers . RadButtonHandler . RadButtonMapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
142+ Maui . Handlers . RadBorderHandler . BorderMapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
143+ Maui . Handlers . RadItemsControlHandler . ItemsControlMapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
144+ Maui . Handlers . RadCheckBoxHandler . RadCheckBoxMapper . AppendToMapping ( nameof ( IView . AutomationId ) , ( h , v ) => SetAutomationId ( v ) ) ;
145+ #if __ANDROID__
146+ // NOTE: The Semantics mapper sets MauiAccessibilityDelegateCompat that prevents ContentDescription from being set for EditText.
147+ // Because of that Semantics mapper is modified and does not do anything.
148+ // For reference see: https://github.com/dotnet/maui/blob/main/src/Core/src/Platform/Android/SemanticExtensions.cs#L26
149+ Microsoft . Maui . Handlers . EntryHandler . Mapper . ModifyMapping ( nameof ( IView . Semantics ) , ( h , v , m ) => { } ) ;
150+ Microsoft . Maui . Handlers . EntryHandler . Mapper . ModifyMapping ( nameof ( IView . AutomationId ) , ( h , v , m ) => SetEditTextContentDescription ( h , v ) ) ;
151+ #endif
152+ #endif
153+ }
154+
155+ #if __ANDROID__ || WINDOWS
156+ private static void SetAutomationId ( IView v )
157+ {
158+ var automationId = v . AutomationId ;
159+ if ( ! string . IsNullOrEmpty ( automationId ) )
160+ {
161+ if ( v is BindableObject element )
162+ {
163+ #if WINDOWS
164+ // NOTE: If TextInput has placeholder don't set description. The default description of the platform control is the placeholder.
165+ if ( element is Telerik . Maui . IRadTextInput textInput && ! string . IsNullOrEmpty ( textInput . Placeholder ) )
166+ {
167+ return ;
168+ }
169+ #endif
170+ SemanticProperties . SetDescription ( element , automationId ) ;
171+ }
172+ }
173+ }
174+ #endif
175+
176+ #if __ANDROID__
177+ private static void SetEditTextContentDescription ( Microsoft . Maui . Handlers . IEntryHandler handler , IView view )
178+ {
179+ var automationId = view . AutomationId ;
180+ if ( ! string . IsNullOrEmpty ( automationId ) )
181+ {
182+ var platformView = handler . PlatformView ;
183+ if ( platformView != null )
184+ {
185+ platformView . ContentDescription = automationId ;
186+ }
187+ }
188+ }
189+ #endif
190+
83191 private static void BootUpCommandServer ( TestingService testingService )
84192 {
85193 int ? port = testingService . TestCommandTcpPort ;
@@ -107,7 +215,7 @@ private static void BootUpCommandServer(TestingService testingService)
107215 tcpCommandServer . BeginAcceptTcpClient ( BeginAcceptTcpClientAsync , testingService ) ;
108216 Console . WriteLine ( "TEST COMMAND! Listening on " + port . Value ) ;
109217 }
110- catch ( Exception e )
218+ catch ( Exception e )
111219 {
112220 Console . WriteLine ( "TEST COMMAND! Failed to start server." ) ;
113221 Console . WriteLine ( e ) ;
@@ -125,7 +233,7 @@ private static void BeginAcceptTcpClientAsync(IAsyncResult client)
125233 using var reader = new StreamReader ( stream ) ;
126234 using var writer = new StreamWriter ( stream ) ;
127235 string ? line = null ;
128- while ( ( line = await reader . ReadLineAsync ( ) ) != null )
236+ while ( ( line = await reader . ReadLineAsync ( ) ) != null )
129237 {
130238 Console . WriteLine ( $ "TEST COMMAND> { line } ") ;
131239 try
@@ -137,7 +245,7 @@ private static void BeginAcceptTcpClientAsync(IAsyncResult client)
137245 await writer . FlushAsync ( ) ;
138246 }
139247 }
140- catch ( Exception e )
248+ catch ( Exception e )
141249 {
142250 await writer . WriteLineAsync ( $ "ERROR: { e . Message } ") ;
143251 await writer . FlushAsync ( ) ;
0 commit comments