From 90f6fb1513a21af94d42ae0faae944f5b747cdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Vincke?= Date: Fri, 22 Nov 2019 12:03:52 +0100 Subject: [PATCH 1/6] Added support for webView's 'onPageStarted' event --- packages/webview_flutter/CHANGELOG.md | 4 + .../webviewflutter/FlutterWebViewClient.java | 17 +++++ .../webview_flutter/example/lib/main.dart | 3 + .../ios/Classes/FLTWKNavigationDelegate.m | 6 ++ .../lib/platform_interface.dart | 3 + .../lib/src/webview_method_channel.dart | 3 + .../webview_flutter/lib/webview_flutter.dart | 14 ++++ packages/webview_flutter/pubspec.yaml | 2 +- .../test/webview_flutter_test.dart | 75 +++++++++++++++++++ 9 files changed, 126 insertions(+), 1 deletion(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index e577b30f53af..43d647f85f70 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.17 + +* Add support for onPageStarted event. + ## 0.3.16 * Add support for async NavigationDelegates. Synchronous NavigationDelegates diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java index 37ec1c992e26..b660a721d0db 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java @@ -5,6 +5,7 @@ package io.flutter.plugins.webviewflutter; import android.annotation.TargetApi; +import android.graphics.Bitmap; import android.os.Build; import android.util.Log; import android.view.KeyEvent; @@ -66,6 +67,12 @@ private boolean shouldOverrideUrlLoading(WebView view, String url) { return true; } + private void onPageStarted(WebView view, String url) { + Map args = new HashMap<>(); + args.put("url", url); + methodChannel.invokeMethod("onPageStarted", args); + } + private void onPageFinished(WebView view, String url) { Map args = new HashMap<>(); args.put("url", url); @@ -106,6 +113,11 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, request); } + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + FlutterWebViewClient.this.onPageStarted(view, url); + } + @Override public void onPageFinished(WebView view, String url) { FlutterWebViewClient.this.onPageFinished(view, url); @@ -132,6 +144,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, url); } + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + FlutterWebViewClient.this.onPageStarted(view, url); + } + @Override public void onPageFinished(WebView view, String url) { FlutterWebViewClient.this.onPageFinished(view, url); diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 5f3e0f8ff4fa..e8f4c1339790 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -66,6 +66,9 @@ class _WebViewExampleState extends State { print('allowing navigation to $request'); return NavigationDecision.navigate; }, + onPageStarted: (String url) { + print('Page started loading: $url'); + }, onPageFinished: (String url) { print('Page finished loading: $url'); }, diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m index abcca0a5e8a9..15c13857fc24 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m @@ -16,6 +16,12 @@ - (instancetype)initWithChannel:(FlutterMethodChannel*)channel { return self; } +#pragma mark - WKNavigationDelegate conformance + +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { + [_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url": webView.URL.absoluteString}]; +} + - (void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index cf6a2fd933f7..a3b8f6d5b70d 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -23,6 +23,9 @@ abstract class WebViewPlatformCallbacksHandler { /// If true is returned the navigation is allowed, otherwise it is blocked. FutureOr onNavigationRequest({String url, bool isForMainFrame}); + /// Invoked by [WebViewPlatformController] when a page has started loading. + void onPageStarted(String url); + /// Invoked by [WebViewPlatformController] when a page has finished loading. void onPageFinished(String url); } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index 2bb7470a1145..99048ac399b4 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -38,6 +38,9 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { case 'onPageFinished': _platformCallbacksHandler.onPageFinished(call.arguments['url']); return null; + case 'onPageStarted': + _platformCallbacksHandler.onPageStarted(call.arguments['url']); + return null; } throw MissingPluginException( '${call.method} was invoked but has no handler'); diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 11541d322dfb..73e72683a2fa 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -70,6 +70,9 @@ enum NavigationDecision { typedef FutureOr NavigationDelegate( NavigationRequest navigation); +/// Signature for when a [WebView] has started loading a page. +typedef void PageStartedCallback(String url); + /// Signature for when a [WebView] has finished loading a page. typedef void PageFinishedCallback(String url); @@ -139,6 +142,7 @@ class WebView extends StatefulWidget { this.javascriptChannels, this.navigationDelegate, this.gestureRecognizers, + this.onPageStarted, this.onPageFinished, this.debuggingEnabled = false, this.userAgent, @@ -254,6 +258,9 @@ class WebView extends StatefulWidget { /// * When a navigationDelegate is set HTTP requests do not include the HTTP referer header. final NavigationDelegate navigationDelegate; + /// Invoked when a page starts loading. + final PageStartedCallback onPageStarted; + /// Invoked when a page has finished loading. /// /// This is invoked only for the main frame. @@ -449,6 +456,13 @@ class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler { return allowNavigation; } + @override + void onPageStarted(String url) { + if (_widget.onPageStarted != null) { + _widget.onPageStarted(url); + } + } + @override void onPageFinished(String url) { if (_widget.onPageFinished != null) { diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 4883f049f759..236d591aea61 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.16 +version: 0.3.17 author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 5184ddd13de3..f3a96255ae1a 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -601,6 +601,63 @@ void main() { expect(ttsMessagesReceived, ['Hello', 'World']); }); + group('$PageStartedCallback', () { + testWidgets('onPageStarted is not null', (WidgetTester tester) async { + String returnedUrl; + + await tester.pumpWidget(WebView( + initialUrl: 'https://youtube.com', + onPageStarted: (String url) { + returnedUrl = url; + }, + )); + + final FakePlatformWebView platformWebView = + fakePlatformViewsController.lastCreatedView; + + platformWebView.fakeOnPageStartedCallback(); + + expect(platformWebView.currentUrl, returnedUrl); + }); + + testWidgets('onPageStarted is null', (WidgetTester tester) async { + await tester.pumpWidget(const WebView( + initialUrl: 'https://youtube.com', + onPageStarted: null, + )); + + final FakePlatformWebView platformWebView = + fakePlatformViewsController.lastCreatedView; + + // The platform side will always invoke a call for onPageStarted. This is + // to test that it does not crash on a null callback. + platformWebView.fakeOnPageStartedCallback(); + }); + + testWidgets('onPageStarted changed', (WidgetTester tester) async { + String returnedUrl; + + await tester.pumpWidget(WebView( + initialUrl: 'https://youtube.com', + onPageStarted: (String url) {}, + )); + + await tester.pumpWidget(WebView( + initialUrl: 'https://youtube.com', + onPageStarted: (String url) { + returnedUrl = url; + }, + )); + + final FakePlatformWebView platformWebView = + fakePlatformViewsController.lastCreatedView; + + platformWebView.fakeOnPageStartedCallback(); + + expect(platformWebView.currentUrl, returnedUrl); + }); + }); + group('$PageFinishedCallback', () { testWidgets('onPageFinished is not null', (WidgetTester tester) async { String returnedUrl; @@ -968,6 +1025,24 @@ class FakePlatformWebView { }); } + void fakeOnPageStartedCallback() { + final StandardMethodCodec codec = const StandardMethodCodec(); + + final ByteData data = codec.encodeMethodCall(MethodCall( + 'onPageStarted', + {'url': currentUrl}, + )); + + // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. + // https://github.com/flutter/flutter/issues/33446 + // ignore: deprecated_member_use + BinaryMessages.handlePlatformMessage( + channel.name, + data, + (ByteData data) {}, + ); + } + void fakeOnPageFinishedCallback() { final StandardMethodCodec codec = const StandardMethodCodec(); From 0827c96e6aedb3cff80fb30b6b2fe593aaa2a26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Vincke?= Date: Fri, 22 Nov 2019 14:53:07 +0100 Subject: [PATCH 2/6] Fixed formatting --- .../webview_flutter/ios/Classes/FLTWKNavigationDelegate.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m index 15c13857fc24..fcd070cd3429 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m @@ -18,8 +18,9 @@ - (instancetype)initWithChannel:(FlutterMethodChannel*)channel { #pragma mark - WKNavigationDelegate conformance -- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { - [_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url": webView.URL.absoluteString}]; +- (void)webView:(WKWebView*)webView +didStartProvisionalNavigation:(WKNavigation*)navigation { + [_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url" : webView.URL.absoluteString}]; } - (void)webView:(WKWebView*)webView From 38edb8fa4143f4e25b5c573864c1417c48148a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Vincke?= Date: Fri, 22 Nov 2019 15:09:00 +0100 Subject: [PATCH 3/6] Fixed formatting --- packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m index fcd070cd3429..3e9d2762c7fa 100644 --- a/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m @@ -18,8 +18,7 @@ - (instancetype)initWithChannel:(FlutterMethodChannel*)channel { #pragma mark - WKNavigationDelegate conformance -- (void)webView:(WKWebView*)webView -didStartProvisionalNavigation:(WKNavigation*)navigation { +- (void)webView:(WKWebView*)webView didStartProvisionalNavigation:(WKNavigation*)navigation { [_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url" : webView.URL.absoluteString}]; } From 9e942d93cf9f384e80aa52dfad2d85353c8e7f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Vincke?= Date: Wed, 4 Dec 2019 14:58:43 +0100 Subject: [PATCH 4/6] Included onPageStarted in test_driver --- .../test_driver/webview_flutter_e2e.dart | 156 +++++++++--------- 1 file changed, 79 insertions(+), 77 deletions(-) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 324ab6140de5..37681910db48 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -17,8 +17,7 @@ void main() { E2EWidgetsFlutterBinding.ensureInitialized(); testWidgets('initalUrl', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); + final Completer controllerCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -37,8 +36,7 @@ void main() { }); testWidgets('loadUrl', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); + final Completer controllerCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -60,8 +58,8 @@ void main() { // enable this once https://github.com/flutter/flutter/issues/31510 // is resolved. testWidgets('loadUrl with headers', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); + final Completer controllerCompleter = Completer(); + final StreamController pageStarts = StreamController(); final StreamController pageLoads = StreamController(); await tester.pumpWidget( Directionality( @@ -73,6 +71,9 @@ void main() { controllerCompleter.complete(controller); }, javascriptMode: JavascriptMode.unrestricted, + onPageStarted: (String url) { + pageStarts.add(url); + }, onPageFinished: (String url) { pageLoads.add(url); }, @@ -80,23 +81,21 @@ void main() { ), ); final WebViewController controller = await controllerCompleter.future; - final Map headers = { - 'test_header': 'flutter_test_header' - }; - await controller.loadUrl('https://flutter-header-echo.herokuapp.com/', - headers: headers); + final Map headers = {'test_header': 'flutter_test_header'}; + await controller.loadUrl('https://flutter-header-echo.herokuapp.com/', headers: headers); final String currentUrl = await controller.currentUrl(); expect(currentUrl, 'https://flutter-header-echo.herokuapp.com/'); + await pageStarts.stream.firstWhere((String url) => url == currentUrl); await pageLoads.stream.firstWhere((String url) => url == currentUrl); - final String content = await controller - .evaluateJavascript('document.documentElement.innerText'); + + final String content = await controller.evaluateJavascript('document.documentElement.innerText'); expect(content.contains('flutter_test_header'), isTrue); }); testWidgets('JavaScriptChannel', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); + final Completer controllerCompleter = Completer(); + final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); final List messagesReceived = []; await tester.pumpWidget( @@ -105,8 +104,7 @@ void main() { child: WebView( key: GlobalKey(), // This is the data URL for: '' - initialUrl: - 'data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+', + initialUrl: 'data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+', onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, @@ -121,6 +119,9 @@ void main() { }, ), ].toSet(), + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, @@ -128,6 +129,7 @@ void main() { ), ); final WebViewController controller = await controllerCompleter.future; + await pageStarted.future; await pageLoaded.future; expect(messagesReceived, isEmpty); @@ -152,12 +154,11 @@ void main() { '''; - final String resizeTestBase64 = - base64Encode(const Utf8Encoder().convert(resizeTest)); + final String resizeTestBase64 = base64Encode(const Utf8Encoder().convert(resizeTest)); final Completer resizeCompleter = Completer(); + final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final Completer controllerCompleter = - Completer(); + final Completer controllerCompleter = Completer(); final GlobalKey key = GlobalKey(); final WebView webView = WebView( @@ -176,6 +177,9 @@ void main() { }, ), ].toSet(), + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, @@ -198,6 +202,7 @@ void main() { ); await controllerCompleter.future; + await pageStarted.future; await pageLoaded.future; expect(resizeCompleter.isCompleted, false); @@ -221,8 +226,7 @@ void main() { }); testWidgets('set custom userAgent', (WidgetTester tester) async { - final Completer controllerCompleter1 = - Completer(); + final Completer controllerCompleter1 = Completer(); final GlobalKey _globalKey = GlobalKey(); await tester.pumpWidget( Directionality( @@ -258,10 +262,8 @@ void main() { expect(customUserAgent2, 'Custom_User_Agent2'); }); - testWidgets('use default platform userAgent after webView is rebuilt', - (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); + testWidgets('use default platform userAgent after webView is rebuilt', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); final GlobalKey _globalKey = GlobalKey(); // Build the webView with no user agent to get the default platform user agent. await tester.pumpWidget( @@ -312,10 +314,8 @@ void main() { group('Media playback policy', () { String audioTestBase64; setUpAll(() async { - final ByteData audioData = - await rootBundle.load('assets/sample_audio.ogg'); - final String base64AudioData = - base64Encode(Uint8List.view(audioData.buffer)); + final ByteData audioData = await rootBundle.load('assets/sample_audio.ogg'); + final String base64AudioData = base64Encode(Uint8List.view(audioData.buffer)); final String audioTest = ''' Audio auto play @@ -341,8 +341,8 @@ void main() { }); testWidgets('Auto media playback', (WidgetTester tester) async { - Completer controllerCompleter = - Completer(); + Completer controllerCompleter = Completer(); + Completer pageStarted = Completer(); Completer pageLoaded = Completer(); await tester.pumpWidget( @@ -355,6 +355,9 @@ void main() { controllerCompleter.complete(controller); }, javascriptMode: JavascriptMode.unrestricted, + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, @@ -363,12 +366,14 @@ void main() { ), ); WebViewController controller = await controllerCompleter.future; + await pageStarted.future; await pageLoaded.future; String isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(false)); controllerCompleter = Completer(); + pageStarted = Completer(); pageLoaded = Completer(); // We change the key to re-create a new webview as we change the initialMediaPlaybackPolicy @@ -382,26 +387,28 @@ void main() { controllerCompleter.complete(controller); }, javascriptMode: JavascriptMode.unrestricted, + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, - initialMediaPlaybackPolicy: - AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, ), ), ); controller = await controllerCompleter.future; + await pageStarted.future; await pageLoaded.future; isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(true)); }); - testWidgets('Changes to initialMediaPlaybackPolocy are ignored', - (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); + testWidgets('Changes to initialMediaPlaybackPolocy are ignored', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + Completer pageStarted = Completer(); Completer pageLoaded = Completer(); final GlobalKey key = GlobalKey(); @@ -415,6 +422,9 @@ void main() { controllerCompleter.complete(controller); }, javascriptMode: JavascriptMode.unrestricted, + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, @@ -423,11 +433,13 @@ void main() { ), ); final WebViewController controller = await controllerCompleter.future; + await pageStarted.future; await pageLoaded.future; String isPaused = await controller.evaluateJavascript('isPaused();'); expect(isPaused, _webviewBool(false)); + pageStarted = Completer(); pageLoaded = Completer(); await tester.pumpWidget( @@ -440,17 +452,20 @@ void main() { controllerCompleter.complete(controller); }, javascriptMode: JavascriptMode.unrestricted, + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, - initialMediaPlaybackPolicy: - AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, ), ), ); await controller.reload(); + await pageStarted.future; await pageLoaded.future; isPaused = await controller.evaluateJavascript('isPaused();'); @@ -467,11 +482,10 @@ void main() { '''; - final String getTitleTestBase64 = - base64Encode(const Utf8Encoder().convert(getTitleTest)); + final String getTitleTestBase64 = base64Encode(const Utf8Encoder().convert(getTitleTest)); + final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final Completer controllerCompleter = - Completer(); + final Completer controllerCompleter = Completer(); await tester.pumpWidget( Directionality( @@ -481,6 +495,9 @@ void main() { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageStarted: (String url) { + pageStarted.complete(null); + }, onPageFinished: (String url) { pageLoaded.complete(null); }, @@ -489,6 +506,7 @@ void main() { ); final WebViewController controller = await controllerCompleter.future; + await pageStarted.future; await pageLoaded.future; final String title = await controller.getTitle(); @@ -497,14 +515,12 @@ void main() { group('NavigationDelegate', () { final String blankPage = ""; - final String blankPageEncoded = 'data:text/html;charset=utf-8;base64,' + - base64Encode(const Utf8Encoder().convert(blankPage)); + final String blankPageEncoded = + 'data:text/html;charset=utf-8;base64,' + base64Encode(const Utf8Encoder().convert(blankPage)); testWidgets('can allow requests', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final StreamController pageLoads = - StreamController.broadcast(); + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -516,9 +532,7 @@ void main() { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) - ? NavigationDecision.prevent - : NavigationDecision.navigate; + return (request.url.contains('youtube.com')) ? NavigationDecision.prevent : NavigationDecision.navigate; }, onPageFinished: (String url) => pageLoads.add(url), ), @@ -527,8 +541,7 @@ void main() { await pageLoads.stream.first; // Wait for initial page load. final WebViewController controller = await controllerCompleter.future; - await controller - .evaluateJavascript('location.href = "https://www.google.com/"'); + await controller.evaluateJavascript('location.href = "https://www.google.com/"'); await pageLoads.stream.first; // Wait for the next page load. final String currentUrl = await controller.currentUrl(); @@ -536,10 +549,8 @@ void main() { }); testWidgets('can block requests', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final StreamController pageLoads = - StreamController.broadcast(); + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -551,9 +562,7 @@ void main() { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) - ? NavigationDecision.prevent - : NavigationDecision.navigate; + return (request.url.contains('youtube.com')) ? NavigationDecision.prevent : NavigationDecision.navigate; }, onPageFinished: (String url) => pageLoads.add(url), ), @@ -562,23 +571,19 @@ void main() { await pageLoads.stream.first; // Wait for initial page load. final WebViewController controller = await controllerCompleter.future; - await controller - .evaluateJavascript('location.href = "https://www.youtube.com/"'); + await controller.evaluateJavascript('location.href = "https://www.youtube.com/"'); // There should never be any second page load, since our new URL is // blocked. Still wait for a potential page change for some time in order // to give the test a chance to fail. - await pageLoads.stream.first - .timeout(const Duration(milliseconds: 500), onTimeout: () => null); + await pageLoads.stream.first.timeout(const Duration(milliseconds: 500), onTimeout: () => null); final String currentUrl = await controller.currentUrl(); expect(currentUrl, isNot(contains('youtube.com'))); }); testWidgets('supports asynchronous decisions', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final StreamController pageLoads = - StreamController.broadcast(); + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -592,8 +597,7 @@ void main() { navigationDelegate: (NavigationRequest request) async { NavigationDecision decision = NavigationDecision.prevent; decision = await Future.delayed( - const Duration(milliseconds: 10), - () => NavigationDecision.navigate); + const Duration(milliseconds: 10), () => NavigationDecision.navigate); return decision; }, onPageFinished: (String url) => pageLoads.add(url), @@ -603,8 +607,7 @@ void main() { await pageLoads.stream.first; // Wait for initial page load. final WebViewController controller = await controllerCompleter.future; - await controller - .evaluateJavascript('location.href = "https://www.google.com"'); + await controller.evaluateJavascript('location.href = "https://www.google.com"'); await pageLoads.stream.first; // Wait for second page to load. final String currentUrl = await controller.currentUrl(); @@ -627,6 +630,5 @@ Future _getUserAgent(WebViewController controller) async { if (defaultTargetPlatform == TargetPlatform.iOS) { return await controller.evaluateJavascript('navigator.userAgent;'); } - return jsonDecode( - await controller.evaluateJavascript('navigator.userAgent;')); + return jsonDecode(await controller.evaluateJavascript('navigator.userAgent;')); } From c44293324766469d438471ab280f6df206204339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Vincke?= Date: Wed, 4 Dec 2019 15:40:37 +0100 Subject: [PATCH 5/6] Formatting pass --- .../test_driver/webview_flutter_e2e.dart | 103 ++++++++++++------ 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 37681910db48..1c121439b531 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -17,7 +17,8 @@ void main() { E2EWidgetsFlutterBinding.ensureInitialized(); testWidgets('initalUrl', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -36,7 +37,8 @@ void main() { }); testWidgets('loadUrl', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -58,7 +60,8 @@ void main() { // enable this once https://github.com/flutter/flutter/issues/31510 // is resolved. testWidgets('loadUrl with headers', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); final StreamController pageStarts = StreamController(); final StreamController pageLoads = StreamController(); await tester.pumpWidget( @@ -81,20 +84,25 @@ void main() { ), ); final WebViewController controller = await controllerCompleter.future; - final Map headers = {'test_header': 'flutter_test_header'}; - await controller.loadUrl('https://flutter-header-echo.herokuapp.com/', headers: headers); + final Map headers = { + 'test_header': 'flutter_test_header' + }; + await controller.loadUrl('https://flutter-header-echo.herokuapp.com/', + headers: headers); final String currentUrl = await controller.currentUrl(); expect(currentUrl, 'https://flutter-header-echo.herokuapp.com/'); await pageStarts.stream.firstWhere((String url) => url == currentUrl); await pageLoads.stream.firstWhere((String url) => url == currentUrl); - final String content = await controller.evaluateJavascript('document.documentElement.innerText'); + final String content = await controller + .evaluateJavascript('document.documentElement.innerText'); expect(content.contains('flutter_test_header'), isTrue); }); testWidgets('JavaScriptChannel', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); final List messagesReceived = []; @@ -104,7 +112,8 @@ void main() { child: WebView( key: GlobalKey(), // This is the data URL for: '' - initialUrl: 'data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+', + initialUrl: + 'data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+', onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, @@ -154,11 +163,13 @@ void main() { '''; - final String resizeTestBase64 = base64Encode(const Utf8Encoder().convert(resizeTest)); + final String resizeTestBase64 = + base64Encode(const Utf8Encoder().convert(resizeTest)); final Completer resizeCompleter = Completer(); final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); final GlobalKey key = GlobalKey(); final WebView webView = WebView( @@ -262,8 +273,10 @@ void main() { expect(customUserAgent2, 'Custom_User_Agent2'); }); - testWidgets('use default platform userAgent after webView is rebuilt', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); + testWidgets('use default platform userAgent after webView is rebuilt', + (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); final GlobalKey _globalKey = GlobalKey(); // Build the webView with no user agent to get the default platform user agent. await tester.pumpWidget( @@ -314,8 +327,10 @@ void main() { group('Media playback policy', () { String audioTestBase64; setUpAll(() async { - final ByteData audioData = await rootBundle.load('assets/sample_audio.ogg'); - final String base64AudioData = base64Encode(Uint8List.view(audioData.buffer)); + final ByteData audioData = + await rootBundle.load('assets/sample_audio.ogg'); + final String base64AudioData = + base64Encode(Uint8List.view(audioData.buffer)); final String audioTest = ''' Audio auto play @@ -341,7 +356,8 @@ void main() { }); testWidgets('Auto media playback', (WidgetTester tester) async { - Completer controllerCompleter = Completer(); + Completer controllerCompleter = + Completer(); Completer pageStarted = Completer(); Completer pageLoaded = Completer(); @@ -393,7 +409,8 @@ void main() { onPageFinished: (String url) { pageLoaded.complete(null); }, - initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + initialMediaPlaybackPolicy: + AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, ), ), ); @@ -406,7 +423,8 @@ void main() { expect(isPaused, _webviewBool(true)); }); - testWidgets('Changes to initialMediaPlaybackPolocy are ignored', (WidgetTester tester) async { + testWidgets('Changes to initialMediaPlaybackPolocy are ignored', + (WidgetTester tester) async { final Completer controllerCompleter = Completer(); Completer pageStarted = Completer(); Completer pageLoaded = Completer(); @@ -458,7 +476,8 @@ void main() { onPageFinished: (String url) { pageLoaded.complete(null); }, - initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + initialMediaPlaybackPolicy: + AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, ), ), ); @@ -482,10 +501,12 @@ void main() { '''; - final String getTitleTestBase64 = base64Encode(const Utf8Encoder().convert(getTitleTest)); + final String getTitleTestBase64 = + base64Encode(const Utf8Encoder().convert(getTitleTest)); final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); await tester.pumpWidget( Directionality( @@ -515,8 +536,8 @@ void main() { group('NavigationDelegate', () { final String blankPage = ""; - final String blankPageEncoded = - 'data:text/html;charset=utf-8;base64,' + base64Encode(const Utf8Encoder().convert(blankPage)); + final String blankPageEncoded = 'data:text/html;charset=utf-8;base64,' + + base64Encode(const Utf8Encoder().convert(blankPage)); testWidgets('can allow requests', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -532,7 +553,9 @@ void main() { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) ? NavigationDecision.prevent : NavigationDecision.navigate; + return (request.url.contains('youtube.com')) + ? NavigationDecision.prevent + : NavigationDecision.navigate; }, onPageFinished: (String url) => pageLoads.add(url), ), @@ -541,7 +564,8 @@ void main() { await pageLoads.stream.first; // Wait for initial page load. final WebViewController controller = await controllerCompleter.future; - await controller.evaluateJavascript('location.href = "https://www.google.com/"'); + await controller + .evaluateJavascript('location.href = "https://www.google.com/"'); await pageLoads.stream.first; // Wait for the next page load. final String currentUrl = await controller.currentUrl(); @@ -549,8 +573,10 @@ void main() { }); testWidgets('can block requests', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = StreamController.broadcast(); + final Completer controllerCompleter = + Completer(); + final StreamController pageLoads = + StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -562,7 +588,9 @@ void main() { }, javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { - return (request.url.contains('youtube.com')) ? NavigationDecision.prevent : NavigationDecision.navigate; + return (request.url.contains('youtube.com')) + ? NavigationDecision.prevent + : NavigationDecision.navigate; }, onPageFinished: (String url) => pageLoads.add(url), ), @@ -571,19 +599,23 @@ void main() { await pageLoads.stream.first; // Wait for initial page load. final WebViewController controller = await controllerCompleter.future; - await controller.evaluateJavascript('location.href = "https://www.youtube.com/"'); + await controller + .evaluateJavascript('location.href = "https://www.youtube.com/"'); // There should never be any second page load, since our new URL is // blocked. Still wait for a potential page change for some time in order // to give the test a chance to fail. - await pageLoads.stream.first.timeout(const Duration(milliseconds: 500), onTimeout: () => null); + await pageLoads.stream.first + .timeout(const Duration(milliseconds: 500), onTimeout: () => null); final String currentUrl = await controller.currentUrl(); expect(currentUrl, isNot(contains('youtube.com'))); }); testWidgets('supports asynchronous decisions', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = StreamController.broadcast(); + final Completer controllerCompleter = + Completer(); + final StreamController pageLoads = + StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -597,7 +629,8 @@ void main() { navigationDelegate: (NavigationRequest request) async { NavigationDecision decision = NavigationDecision.prevent; decision = await Future.delayed( - const Duration(milliseconds: 10), () => NavigationDecision.navigate); + const Duration(milliseconds: 10), + () => NavigationDecision.navigate); return decision; }, onPageFinished: (String url) => pageLoads.add(url), @@ -607,7 +640,8 @@ void main() { await pageLoads.stream.first; // Wait for initial page load. final WebViewController controller = await controllerCompleter.future; - await controller.evaluateJavascript('location.href = "https://www.google.com"'); + await controller + .evaluateJavascript('location.href = "https://www.google.com"'); await pageLoads.stream.first; // Wait for second page to load. final String currentUrl = await controller.currentUrl(); @@ -630,5 +664,6 @@ Future _getUserAgent(WebViewController controller) async { if (defaultTargetPlatform == TargetPlatform.iOS) { return await controller.evaluateJavascript('navigator.userAgent;'); } - return jsonDecode(await controller.evaluateJavascript('navigator.userAgent;')); + return jsonDecode( + await controller.evaluateJavascript('navigator.userAgent;')); } From 1bf479a8e3607041258aea7f79921d0048703627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Je=CC=81re=CC=81mie=20Vincke?= Date: Wed, 4 Dec 2019 15:48:50 +0100 Subject: [PATCH 6/6] Formatting pass --- .../example/test_driver/webview_flutter_e2e.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 1c121439b531..373e65c6cbdd 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -237,7 +237,8 @@ void main() { }); testWidgets('set custom userAgent', (WidgetTester tester) async { - final Completer controllerCompleter1 = Completer(); + final Completer controllerCompleter1 = + Completer(); final GlobalKey _globalKey = GlobalKey(); await tester.pumpWidget( Directionality( @@ -425,7 +426,8 @@ void main() { testWidgets('Changes to initialMediaPlaybackPolocy are ignored', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); + final Completer controllerCompleter = + Completer(); Completer pageStarted = Completer(); Completer pageLoaded = Completer(); @@ -540,8 +542,10 @@ void main() { base64Encode(const Utf8Encoder().convert(blankPage)); testWidgets('can allow requests', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = StreamController.broadcast(); + final Completer controllerCompleter = + Completer(); + final StreamController pageLoads = + StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr,