@@ -494,6 +494,123 @@ void main() {
494
494
final String title = await controller.getTitle ();
495
495
expect (title, 'Some title' );
496
496
});
497
+
498
+ group ('NavigationDelegate' , () {
499
+ final String blankPage = "<!DOCTYPE html><head></head><body></body></html>" ;
500
+ final String blankPageEncoded = 'data:text/html;charset=utf-8;base64,' +
501
+ base64Encode (const Utf8Encoder ().convert (blankPage));
502
+
503
+ testWidgets ('can allow requests' , (WidgetTester tester) async {
504
+ final Completer <WebViewController > controllerCompleter =
505
+ Completer <WebViewController >();
506
+ final StreamController <String > pageLoads =
507
+ StreamController <String >.broadcast ();
508
+ await tester.pumpWidget (
509
+ Directionality (
510
+ textDirection: TextDirection .ltr,
511
+ child: WebView (
512
+ key: GlobalKey (),
513
+ initialUrl: blankPageEncoded,
514
+ onWebViewCreated: (WebViewController controller) {
515
+ controllerCompleter.complete (controller);
516
+ },
517
+ javascriptMode: JavascriptMode .unrestricted,
518
+ navigationDelegate: (NavigationRequest request) {
519
+ return (request.url.contains ('youtube.com' ))
520
+ ? NavigationDecision .prevent
521
+ : NavigationDecision .navigate;
522
+ },
523
+ onPageFinished: (String url) => pageLoads.add (url),
524
+ ),
525
+ ),
526
+ );
527
+
528
+ await pageLoads.stream.first; // Wait for initial page load.
529
+ final WebViewController controller = await controllerCompleter.future;
530
+ await controller
531
+ .evaluateJavascript ('location.href = "https://www.google.com/"' );
532
+
533
+ await pageLoads.stream.first; // Wait for the next page load.
534
+ final String currentUrl = await controller.currentUrl ();
535
+ expect (currentUrl, 'https://www.google.com/' );
536
+ });
537
+
538
+ testWidgets ('can block requests' , (WidgetTester tester) async {
539
+ final Completer <WebViewController > controllerCompleter =
540
+ Completer <WebViewController >();
541
+ final StreamController <String > pageLoads =
542
+ StreamController <String >.broadcast ();
543
+ await tester.pumpWidget (
544
+ Directionality (
545
+ textDirection: TextDirection .ltr,
546
+ child: WebView (
547
+ key: GlobalKey (),
548
+ initialUrl: blankPageEncoded,
549
+ onWebViewCreated: (WebViewController controller) {
550
+ controllerCompleter.complete (controller);
551
+ },
552
+ javascriptMode: JavascriptMode .unrestricted,
553
+ navigationDelegate: (NavigationRequest request) {
554
+ return (request.url.contains ('youtube.com' ))
555
+ ? NavigationDecision .prevent
556
+ : NavigationDecision .navigate;
557
+ },
558
+ onPageFinished: (String url) => pageLoads.add (url),
559
+ ),
560
+ ),
561
+ );
562
+
563
+ await pageLoads.stream.first; // Wait for initial page load.
564
+ final WebViewController controller = await controllerCompleter.future;
565
+ await controller
566
+ .evaluateJavascript ('location.href = "https://www.youtube.com/"' );
567
+
568
+ // There should never be any second page load, since our new URL is
569
+ // blocked. Still wait for a potential page change for some time in order
570
+ // to give the test a chance to fail.
571
+ await pageLoads.stream.first
572
+ .timeout (const Duration (milliseconds: 500 ), onTimeout: () => null );
573
+ final String currentUrl = await controller.currentUrl ();
574
+ expect (currentUrl, isNot (contains ('youtube.com' )));
575
+ });
576
+
577
+ testWidgets ('supports asynchronous decisions' , (WidgetTester tester) async {
578
+ final Completer <WebViewController > controllerCompleter =
579
+ Completer <WebViewController >();
580
+ final StreamController <String > pageLoads =
581
+ StreamController <String >.broadcast ();
582
+ await tester.pumpWidget (
583
+ Directionality (
584
+ textDirection: TextDirection .ltr,
585
+ child: WebView (
586
+ key: GlobalKey (),
587
+ initialUrl: blankPageEncoded,
588
+ onWebViewCreated: (WebViewController controller) {
589
+ controllerCompleter.complete (controller);
590
+ },
591
+ javascriptMode: JavascriptMode .unrestricted,
592
+ navigationDelegate: (NavigationRequest request) async {
593
+ NavigationDecision decision = NavigationDecision .prevent;
594
+ decision = await Future <NavigationDecision >.delayed (
595
+ const Duration (milliseconds: 10 ),
596
+ () => NavigationDecision .navigate);
597
+ return decision;
598
+ },
599
+ onPageFinished: (String url) => pageLoads.add (url),
600
+ ),
601
+ ),
602
+ );
603
+
604
+ await pageLoads.stream.first; // Wait for initial page load.
605
+ final WebViewController controller = await controllerCompleter.future;
606
+ await controller
607
+ .evaluateJavascript ('location.href = "https://www.google.com"' );
608
+
609
+ await pageLoads.stream.first; // Wait for second page to load.
610
+ final String currentUrl = await controller.currentUrl ();
611
+ expect (currentUrl, 'https://www.google.com/' );
612
+ });
613
+ });
497
614
}
498
615
499
616
// JavaScript booleans evaluate to different string values on Android and iOS.
0 commit comments