@@ -76,6 +76,57 @@ Future<GoRouter> createGoRouterWithStatefulShellRoute(
76
76
return router;
77
77
}
78
78
79
+ Future <GoRouter > createGoRouterWithStatefulShellRouteAndPopScopes (
80
+ WidgetTester tester, {
81
+ bool canPopShellRouteBuilder = true ,
82
+ bool canPopBranch = true ,
83
+ bool canPopBranchSubRoute = true ,
84
+ PopInvokedWithResultCallback <bool >? onPopShellRouteBuilder,
85
+ PopInvokedWithResultCallback <bool >? onPopBranch,
86
+ PopInvokedWithResultCallback <bool >? onPopBranchSubRoute,
87
+ }) async {
88
+ final GoRouter router = GoRouter (
89
+ initialLocation: '/c' ,
90
+ routes: < RouteBase > [
91
+ StatefulShellRoute .indexedStack (
92
+ branches: < StatefulShellBranch > [
93
+ StatefulShellBranch (routes: < RouteBase > [
94
+ GoRoute (
95
+ path: '/c' ,
96
+ builder: (_, __) => PopScope (
97
+ onPopInvokedWithResult: onPopBranch,
98
+ canPop: canPopBranch,
99
+ child: const Text ('Home' )),
100
+ routes: < RouteBase > [
101
+ GoRoute (
102
+ path: 'c1' ,
103
+ builder: (_, __) => PopScope (
104
+ onPopInvokedWithResult: onPopBranchSubRoute,
105
+ canPop: canPopBranchSubRoute,
106
+ child: const Text ('SubRoute' ),
107
+ ),
108
+ ),
109
+ ]),
110
+ ]),
111
+ ],
112
+ builder: (BuildContext context, GoRouterState state,
113
+ StatefulNavigationShell navigationShell) =>
114
+ PopScope (
115
+ onPopInvokedWithResult: onPopShellRouteBuilder,
116
+ canPop: canPopShellRouteBuilder,
117
+ child: navigationShell,
118
+ ),
119
+ ),
120
+ ],
121
+ );
122
+
123
+ addTearDown (router.dispose);
124
+ await tester.pumpWidget (MaterialApp .router (
125
+ routerConfig: router,
126
+ ));
127
+ return router;
128
+ }
129
+
79
130
void main () {
80
131
group ('pop' , () {
81
132
testWidgets ('restore() update currentConfiguration in pop()' ,
@@ -152,6 +203,91 @@ void main() {
152
203
expect (find.text ('Home' ), findsOneWidget);
153
204
});
154
205
206
+ testWidgets (
207
+ 'PopScope intercepts back button on StatefulShellRoute builder route' ,
208
+ (WidgetTester tester) async {
209
+ bool didPopShellRouteBuilder = false ;
210
+ bool didPopBranch = false ;
211
+ bool didPopBranchSubRoute = false ;
212
+
213
+ await createGoRouterWithStatefulShellRouteAndPopScopes (
214
+ tester,
215
+ canPopShellRouteBuilder: false ,
216
+ onPopShellRouteBuilder: (_, __) => didPopShellRouteBuilder = true ,
217
+ onPopBranch: (_, __) => didPopBranch = true ,
218
+ onPopBranchSubRoute: (_, __) => didPopBranchSubRoute = true ,
219
+ );
220
+
221
+ expect (find.text ('Home' ), findsOneWidget);
222
+ await tester.binding.handlePopRoute ();
223
+ await tester.pumpAndSettle ();
224
+
225
+ // Verify that PopScope intercepted the back button
226
+ expect (didPopShellRouteBuilder, isTrue);
227
+ expect (didPopBranch, isFalse);
228
+ expect (didPopBranchSubRoute, isFalse);
229
+
230
+ expect (find.text ('Home' ), findsOneWidget);
231
+ });
232
+
233
+ testWidgets (
234
+ 'PopScope intercepts back button on StatefulShellRoute branch route' ,
235
+ (WidgetTester tester) async {
236
+ bool didPopShellRouteBuilder = false ;
237
+ bool didPopBranch = false ;
238
+ bool didPopBranchSubRoute = false ;
239
+
240
+ await createGoRouterWithStatefulShellRouteAndPopScopes (
241
+ tester,
242
+ canPopBranch: false ,
243
+ onPopShellRouteBuilder: (_, __) => didPopShellRouteBuilder = true ,
244
+ onPopBranch: (_, __) => didPopBranch = true ,
245
+ onPopBranchSubRoute: (_, __) => didPopBranchSubRoute = true ,
246
+ );
247
+
248
+ expect (find.text ('Home' ), findsOneWidget);
249
+ await tester.binding.handlePopRoute ();
250
+ await tester.pumpAndSettle ();
251
+
252
+ // Verify that PopScope intercepted the back button
253
+ expect (didPopShellRouteBuilder, isFalse);
254
+ expect (didPopBranch, isTrue);
255
+ expect (didPopBranchSubRoute, isFalse);
256
+
257
+ expect (find.text ('Home' ), findsOneWidget);
258
+ });
259
+
260
+ testWidgets (
261
+ 'PopScope intercepts back button on StatefulShellRoute branch sub route' ,
262
+ (WidgetTester tester) async {
263
+ bool didPopShellRouteBuilder = false ;
264
+ bool didPopBranch = false ;
265
+ bool didPopBranchSubRoute = false ;
266
+
267
+ final GoRouter goRouter =
268
+ await createGoRouterWithStatefulShellRouteAndPopScopes (
269
+ tester,
270
+ canPopBranchSubRoute: false ,
271
+ onPopShellRouteBuilder: (_, __) => didPopShellRouteBuilder = true ,
272
+ onPopBranch: (_, __) => didPopBranch = true ,
273
+ onPopBranchSubRoute: (_, __) => didPopBranchSubRoute = true ,
274
+ );
275
+
276
+ goRouter.push ('/c/c1' );
277
+ await tester.pumpAndSettle ();
278
+
279
+ expect (find.text ('SubRoute' ), findsOneWidget);
280
+ await tester.binding.handlePopRoute ();
281
+ await tester.pumpAndSettle ();
282
+
283
+ // Verify that PopScope intercepted the back button
284
+ expect (didPopShellRouteBuilder, isFalse);
285
+ expect (didPopBranch, isFalse);
286
+ expect (didPopBranchSubRoute, isTrue);
287
+
288
+ expect (find.text ('SubRoute' ), findsOneWidget);
289
+ });
290
+
155
291
testWidgets ('pops more than matches count should return false' ,
156
292
(WidgetTester tester) async {
157
293
final GoRouter goRouter = await createGoRouter (tester)
0 commit comments