33// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
44
55import 'dart:async' ;
6+ import 'dart:ui' ;
67
78import 'package:devtools_app/devtools_app.dart' ;
89import 'package:devtools_app/src/shared/editor/api_classes.dart' ;
@@ -299,6 +300,23 @@ void main() {
299300 );
300301 });
301302
303+ testWidgets ('softWrap input has expected tooltip' , (tester) async {
304+ // Load the property editor.
305+ await tester.pumpWidget (wrap (propertyEditor));
306+
307+ // Change the editable args.
308+ controller.initForTestsOnly (editableArgsResult: result2);
309+ await tester.pumpAndSettle ();
310+
311+ // Verify the input options are expected.
312+ final softWrapInput = _findDropdownButtonFormField ('softWrap' );
313+ await _tooltipContentIsExpected (
314+ softWrapInput,
315+ tooltipContent: softWrapTooltipContent,
316+ tester: tester,
317+ );
318+ });
319+
302320 testWidgets ('align input has expected options' , (tester) async {
303321 // Load the property editor.
304322 await tester.pumpWidget (wrap (propertyEditor));
@@ -327,6 +345,23 @@ void main() {
327345 tester: tester,
328346 );
329347 });
348+
349+ testWidgets ('align input has expected tooltip' , (tester) async {
350+ // Load the property editor.
351+ await tester.pumpWidget (wrap (propertyEditor));
352+
353+ // Change the editable args.
354+ controller.initForTestsOnly (editableArgsResult: result2);
355+ await tester.pumpAndSettle ();
356+
357+ // Verify the input options are expected.
358+ final alignInput = _findDropdownButtonFormField ('align' );
359+ await _tooltipContentIsExpected (
360+ alignInput,
361+ tooltipContent: alignTooltipContent,
362+ tester: tester,
363+ );
364+ });
330365 });
331366
332367 group ('filtering editable arguments' , () {
@@ -901,6 +936,36 @@ void _labelsAndRequiredTextAreExpected(
901936 );
902937}
903938
939+ Future <void > _tooltipContentIsExpected (
940+ Finder inputFinder, {
941+ required String tooltipContent,
942+ required WidgetTester tester,
943+ }) async {
944+ final inputRowFinder = find.ancestor (
945+ of: inputFinder,
946+ matching: find.byType (Row ),
947+ );
948+ final iconFinder = find.descendant (
949+ of: inputRowFinder,
950+ matching: find.byIcon (Icons .info_outline),
951+ );
952+
953+ // Verify tooltip is not visible.
954+ expect (find.text (tooltipContent), findsNothing);
955+
956+ // Simulate a hover for 600 ms.
957+ final gesture = await tester.createGesture (kind: PointerDeviceKind .mouse);
958+ await gesture.moveTo (tester.getRect (iconFinder).center);
959+ await tester.pump (const Duration (milliseconds: 600 ));
960+ await tester.pumpAndSettle ();
961+
962+ // Verify tooltip is visible with expected content.
963+ expect (find.text (tooltipContent), findsOneWidget);
964+
965+ // Clean-up, remove gesture pointer.
966+ await gesture.removePointer ();
967+ }
968+
904969Finder _helperTextForInput (Finder inputFinder, {required String matching}) {
905970 final rowFinder = find.ancestor (of: inputFinder, matching: find.byType (Row ));
906971 return find.descendant (of: rowFinder, matching: find.richText (matching));
@@ -1130,6 +1195,14 @@ final result1 = EditableArgumentsResult(
11301195);
11311196
11321197// Result 2
1198+ const softWrapDocumentation = '''
1199+ Whether or not the text should wrap.
1200+
1201+ If null, the default value is platform dependent. On [TargetPlatform.android],
1202+ the default is true. On [TargetPlatform.iOS], false. The remaining platforms
1203+ also default to false.
1204+ ''' ;
1205+
11331206final softWrapProperty = EditableArgument .fromJson ({
11341207 'name' : 'softWrap' ,
11351208 'type' : 'bool' ,
@@ -1138,12 +1211,32 @@ final softWrapProperty = EditableArgument.fromJson({
11381211 'hasArgument' : false ,
11391212 'isEditable' : true ,
11401213 'isRequired' : false ,
1214+ 'documentation' : softWrapDocumentation,
11411215});
11421216final softWrapInputExpectations = {
11431217 'isSet' : false ,
11441218 'isRequired' : false ,
11451219 'isDefault' : true ,
11461220};
1221+ const softWrapTooltipContent = '''
1222+ bool softWrap
1223+
1224+ Default value: true
1225+
1226+ Documentation:
1227+ Whether or not the text should wrap.
1228+
1229+ If null, the default value is platform dependent. On TargetPlatform.android,
1230+ the default is true. On TargetPlatform.iOS, false. The remaining platforms
1231+ also default to false.
1232+ ''' ;
1233+
1234+ const alignDocumentation = '''
1235+ How to align the child.
1236+
1237+ The x and y values of the [Alignment] control the horizontal and vertical
1238+ alignment, respectively.
1239+ ''' ;
11471240final alignProperty = EditableArgument .fromJson ({
11481241 'name' : 'align' ,
11491242 'type' : 'enum' ,
@@ -1153,6 +1246,7 @@ final alignProperty = EditableArgument.fromJson({
11531246 'isRequired' : false ,
11541247 'isEditable' : true ,
11551248 'value' : 'Alignment.center' ,
1249+ 'documentation' : alignDocumentation,
11561250 'options' : [
11571251 'Alignment.bottomCenter' ,
11581252 'Alignment.bottomLeft' ,
@@ -1170,6 +1264,19 @@ final alignInputExpectations = {
11701264 'isRequired' : false ,
11711265 'isDefault' : false ,
11721266};
1267+ const alignTooltipContent = '''
1268+ Alignment? align
1269+
1270+ Default value: Alignment.bottomLeft
1271+
1272+ Documentation:
1273+ How to align the child.
1274+
1275+ The x and y values of the Alignment control the horizontal and vertical
1276+ alignment, respectively.
1277+ ''' ;
1278+
1279+
11731280final result2 = EditableArgumentsResult (
11741281 name: widgetName,
11751282 args: [softWrapProperty, alignProperty],
0 commit comments