@@ -589,6 +589,163 @@ void main() {
589
589
expect (tester.testTextInput.setClientArgs! ['inputAction' ], TextInputAction .done.toString ());
590
590
});
591
591
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
+
592
749
group ('contributes semantics' , () {
593
750
TestSemantics buildExpected ({ required String routeName }) {
594
751
return TestSemantics .root (
@@ -749,10 +906,10 @@ void main() {
749
906
await tester.tap (find.byTooltip ('Search' ));
750
907
await tester.pumpAndSettle ();
751
908
752
- final Material appBarBackground = tester.widget <Material >(find.descendant (
909
+ final Material appBarBackground = tester.widgetList <Material >(find.descendant (
753
910
of: find.byType (AppBar ),
754
911
matching: find.byType (Material ),
755
- ));
912
+ )).first ;
756
913
expect (appBarBackground.color, Colors .white);
757
914
758
915
final TextField textField = tester.widget <TextField >(find.byType (TextField ));
@@ -777,10 +934,10 @@ void main() {
777
934
await tester.tap (find.byTooltip ('Search' ));
778
935
await tester.pumpAndSettle ();
779
936
780
- final Material appBarBackground = tester.widget <Material >(find.descendant (
937
+ final Material appBarBackground = tester.widgetList <Material >(find.descendant (
781
938
of: find.byType (AppBar ),
782
939
matching: find.byType (Material ),
783
- ));
940
+ )).first ;
784
941
expect (appBarBackground.color, themeData.primaryColor);
785
942
786
943
final TextField textField = tester.widget <TextField >(find.byType (TextField ));
@@ -789,9 +946,9 @@ void main() {
789
946
});
790
947
791
948
// 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 {
793
950
// 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 ].
795
952
final _TestEmptySearchDelegate delegate = _TestEmptySearchDelegate ();
796
953
final List <String > selectedResults = < String > [];
797
954
@@ -980,6 +1137,7 @@ class _TestSearchDelegate extends SearchDelegate<String> {
980
1137
this .suggestions = 'Suggestions' ,
981
1138
this .result = 'Result' ,
982
1139
this .actions = const < Widget > [],
1140
+ this .flexibleSpace ,
983
1141
this .defaultAppBarTheme = false ,
984
1142
super .searchFieldDecorationTheme,
985
1143
super .searchFieldStyle,
@@ -993,6 +1151,7 @@ class _TestSearchDelegate extends SearchDelegate<String> {
993
1151
final String suggestions;
994
1152
final String result;
995
1153
final List <Widget > actions;
1154
+ final Widget ? flexibleSpace;
996
1155
static const Color hintTextColor = Colors .green;
997
1156
998
1157
@override
@@ -1048,6 +1207,11 @@ class _TestSearchDelegate extends SearchDelegate<String> {
1048
1207
return actions;
1049
1208
}
1050
1209
1210
+ @override
1211
+ Widget ? buildFlexibleSpace (BuildContext context) {
1212
+ return flexibleSpace;
1213
+ }
1214
+
1051
1215
@override
1052
1216
PreferredSizeWidget buildBottom (BuildContext context) {
1053
1217
return const PreferredSize (
0 commit comments