@@ -589,6 +589,163 @@ void main() {
589589 expect (tester.testTextInput.setClientArgs! ['inputAction' ], TextInputAction .done.toString ());
590590 });
591591
592+ testWidgets ('Custom flexibleSpace value' , (WidgetTester tester) async {
593+ const Widget flexibleSpace = Text ('custom flexibleSpace' );
594+ final _TestSearchDelegate delegate = _TestSearchDelegate (flexibleSpace: flexibleSpace);
595+
596+ await tester.pumpWidget (TestHomePage (delegate: delegate));
597+ await tester.tap (find.byTooltip ('Search' ));
598+ await tester.pumpAndSettle ();
599+
600+ expect (find.byWidget (flexibleSpace), findsOneWidget);
601+ });
602+
603+
604+ group ('contributes semantics with custom flexibleSpace' , () {
605+ const Widget flexibleSpace = Text ('FlexibleSpace' );
606+
607+ TestSemantics buildExpected ({ required String routeName }) {
608+ return TestSemantics .root (
609+ children: < TestSemantics > [
610+ TestSemantics (
611+ id: 1 ,
612+ textDirection: TextDirection .ltr,
613+ children: < TestSemantics > [
614+ TestSemantics (
615+ id: 2 ,
616+ children: < TestSemantics > [
617+ TestSemantics (
618+ id: 3 ,
619+ flags: < SemanticsFlag > [
620+ SemanticsFlag .scopesRoute,
621+ SemanticsFlag .namesRoute,
622+ ],
623+ label: routeName,
624+ textDirection: TextDirection .ltr,
625+ children: < TestSemantics > [
626+ TestSemantics (
627+ id: 4 ,
628+ children: < TestSemantics > [
629+ TestSemantics (
630+ id: 6 ,
631+ children: < TestSemantics > [
632+ TestSemantics (
633+ id: 8 ,
634+ flags: < SemanticsFlag > [
635+ SemanticsFlag .hasEnabledState,
636+ SemanticsFlag .isButton,
637+ SemanticsFlag .isEnabled,
638+ SemanticsFlag .isFocusable,
639+ ],
640+ actions: < SemanticsAction > [SemanticsAction .tap],
641+ tooltip: 'Back' ,
642+ textDirection: TextDirection .ltr,
643+ ),
644+ TestSemantics (
645+ id: 9 ,
646+ flags: < SemanticsFlag > [
647+ SemanticsFlag .isTextField,
648+ SemanticsFlag .isFocused,
649+ SemanticsFlag .isHeader,
650+ if (debugDefaultTargetPlatformOverride != TargetPlatform .iOS &&
651+ debugDefaultTargetPlatformOverride != TargetPlatform .macOS) SemanticsFlag .namesRoute,
652+ ],
653+ actions: < SemanticsAction > [
654+ if (debugDefaultTargetPlatformOverride == TargetPlatform .macOS ||
655+ debugDefaultTargetPlatformOverride == TargetPlatform .windows)
656+ SemanticsAction .didGainAccessibilityFocus,
657+ SemanticsAction .tap,
658+ SemanticsAction .setSelection,
659+ SemanticsAction .setText,
660+ SemanticsAction .paste,
661+ ],
662+ label: 'Search' ,
663+ textDirection: TextDirection .ltr,
664+ textSelection: const TextSelection (baseOffset: 0 , extentOffset: 0 ),
665+ ),
666+ TestSemantics (
667+ id: 10 ,
668+ label: 'Bottom' ,
669+ textDirection: TextDirection .ltr,
670+ ),
671+ ],
672+ ),
673+ TestSemantics (
674+ id: 7 ,
675+ children: < TestSemantics > [
676+ TestSemantics (
677+ id: 11 ,
678+ label: 'FlexibleSpace' ,
679+ textDirection: TextDirection .ltr,
680+ ),
681+ ],
682+ ),
683+ ],
684+ ),
685+ TestSemantics (
686+ id: 5 ,
687+ flags: < SemanticsFlag > [
688+ SemanticsFlag .hasEnabledState,
689+ SemanticsFlag .isButton,
690+ SemanticsFlag .isEnabled,
691+ SemanticsFlag .isFocusable,
692+ ],
693+ actions: < SemanticsAction > [SemanticsAction .tap],
694+ label: 'Suggestions' ,
695+ textDirection: TextDirection .ltr,
696+ ),
697+ ],
698+ ),
699+ ],
700+ ),
701+ ],
702+ ),
703+ ],
704+ );
705+ }
706+
707+ testWidgets ('includes routeName on Android' , (WidgetTester tester) async {
708+ final SemanticsTester semantics = SemanticsTester (tester);
709+ final _TestSearchDelegate delegate = _TestSearchDelegate (flexibleSpace: flexibleSpace);
710+ await tester.pumpWidget (TestHomePage (
711+ delegate: delegate,
712+ ));
713+
714+ await tester.tap (find.byTooltip ('Search' ));
715+ await tester.pumpAndSettle ();
716+
717+ expect (semantics, hasSemantics (
718+ buildExpected (routeName: 'Search' ),
719+ ignoreId: true ,
720+ ignoreRect: true ,
721+ ignoreTransform: true ,
722+ ));
723+
724+ semantics.dispose ();
725+ });
726+
727+ testWidgets ('does not include routeName' , (WidgetTester tester) async {
728+ final SemanticsTester semantics = SemanticsTester (tester);
729+ final _TestSearchDelegate delegate = _TestSearchDelegate (flexibleSpace: flexibleSpace);
730+ await tester.pumpWidget (TestHomePage (
731+ delegate: delegate,
732+ ));
733+
734+ await tester.tap (find.byTooltip ('Search' ));
735+ await tester.pumpAndSettle ();
736+
737+ expect (semantics, hasSemantics (
738+ buildExpected (routeName: '' ),
739+ ignoreId: true ,
740+ ignoreRect: true ,
741+ ignoreTransform: true ,
742+ ));
743+
744+ semantics.dispose ();
745+ }, variant: const TargetPlatformVariant (< TargetPlatform > { TargetPlatform .iOS, TargetPlatform .macOS }));
746+ });
747+
748+
592749 group ('contributes semantics' , () {
593750 TestSemantics buildExpected ({ required String routeName }) {
594751 return TestSemantics .root (
@@ -749,10 +906,10 @@ void main() {
749906 await tester.tap (find.byTooltip ('Search' ));
750907 await tester.pumpAndSettle ();
751908
752- final Material appBarBackground = tester.widget <Material >(find.descendant (
909+ final Material appBarBackground = tester.widgetList <Material >(find.descendant (
753910 of: find.byType (AppBar ),
754911 matching: find.byType (Material ),
755- ));
912+ )).first ;
756913 expect (appBarBackground.color, Colors .white);
757914
758915 final TextField textField = tester.widget <TextField >(find.byType (TextField ));
@@ -777,10 +934,10 @@ void main() {
777934 await tester.tap (find.byTooltip ('Search' ));
778935 await tester.pumpAndSettle ();
779936
780- final Material appBarBackground = tester.widget <Material >(find.descendant (
937+ final Material appBarBackground = tester.widgetList <Material >(find.descendant (
781938 of: find.byType (AppBar ),
782939 matching: find.byType (Material ),
783- ));
940+ )).first ;
784941 expect (appBarBackground.color, themeData.primaryColor);
785942
786943 final TextField textField = tester.widget <TextField >(find.byType (TextField ));
@@ -789,9 +946,9 @@ void main() {
789946 });
790947
791948 // Regression test for: https://github.com/flutter/flutter/issues/78144
792- testWidgets ('`Leading` and `Actions ` nullable test' , (WidgetTester tester) async {
949+ testWidgets ('`Leading`, `Actions` and `FlexibleSpace ` nullable test' , (WidgetTester tester) async {
793950 // The search delegate page is displayed with no issues
794- // even with a null return values for [buildLeading] and [buildActions ].
951+ // even with a null return values for [buildLeading], [buildActions] and [flexibleSpace ].
795952 final _TestEmptySearchDelegate delegate = _TestEmptySearchDelegate ();
796953 final List <String > selectedResults = < String > [];
797954
@@ -980,6 +1137,7 @@ class _TestSearchDelegate extends SearchDelegate<String> {
9801137 this .suggestions = 'Suggestions' ,
9811138 this .result = 'Result' ,
9821139 this .actions = const < Widget > [],
1140+ this .flexibleSpace ,
9831141 this .defaultAppBarTheme = false ,
9841142 super .searchFieldDecorationTheme,
9851143 super .searchFieldStyle,
@@ -993,6 +1151,7 @@ class _TestSearchDelegate extends SearchDelegate<String> {
9931151 final String suggestions;
9941152 final String result;
9951153 final List <Widget > actions;
1154+ final Widget ? flexibleSpace;
9961155 static const Color hintTextColor = Colors .green;
9971156
9981157 @override
@@ -1048,6 +1207,11 @@ class _TestSearchDelegate extends SearchDelegate<String> {
10481207 return actions;
10491208 }
10501209
1210+ @override
1211+ Widget ? buildFlexibleSpace (BuildContext context) {
1212+ return flexibleSpace;
1213+ }
1214+
10511215 @override
10521216 PreferredSizeWidget buildBottom (BuildContext context) {
10531217 return const PreferredSize (
0 commit comments