diff --git a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart index 17548901bcb8..e4facaf160f8 100644 --- a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart @@ -23,8 +23,6 @@ import 'package:webview_flutter/webview_flutter.dart'; Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - const bool _skipDueToIssue86757 = true; - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); server.forEach((HttpRequest request) { if (request.uri.path == '/hello.txt') { @@ -45,10 +43,10 @@ Future main() async { final String secondaryUrl = '$prefixUrl/secondary.txt'; final String headersUrl = '$prefixUrl/headers'; - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('initialUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final Completer pageFinishedCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -58,18 +56,22 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageFinished: pageFinishedCompleter.complete, ), ), ); + final WebViewController controller = await controllerCompleter.future; + await pageFinishedCompleter.future; + final String? currentUrl = await controller.currentUrl(); expect(currentUrl, primaryUrl); - }, skip: _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('loadUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final StreamController pageLoads = StreamController(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -79,14 +81,20 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageFinished: (String url) { + pageLoads.add(url); + }, ), ), ); final WebViewController controller = await controllerCompleter.future; + await controller.loadUrl(secondaryUrl); - final String? currentUrl = await controller.currentUrl(); - expect(currentUrl, secondaryUrl); - }, skip: _skipDueToIssue86757); + await expectLater( + pageLoads.stream.firstWhere((String url) => url == secondaryUrl), + completion(secondaryUrl), + ); + }); testWidgets('evaluateJavascript', (WidgetTester tester) async { final Completer controllerCompleter = @@ -110,7 +118,6 @@ Future main() async { expect(result, equals('2')); }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('loadUrl with headers', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -149,15 +156,14 @@ Future main() async { final String content = await controller .runJavascriptReturningResult('document.documentElement.innerText'); expect(content.contains('flutter_test_header'), isTrue); - }, skip: Platform.isAndroid && _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('JavascriptChannel', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final List messagesReceived = []; + final Completer channelCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -174,7 +180,7 @@ Future main() async { JavascriptChannel( name: 'Echo', onMessageReceived: (JavascriptMessage message) { - messagesReceived.add(message.message); + channelCompleter.complete(message.message); }, ), }, @@ -191,10 +197,11 @@ Future main() async { await pageStarted.future; await pageLoaded.future; - expect(messagesReceived, isEmpty); + expect(channelCompleter.isCompleted, isFalse); await controller.runJavascript('Echo.postMessage("hello");'); - expect(messagesReceived, equals(['hello'])); - }, skip: Platform.isAndroid && _skipDueToIssue86757); + + await expectLater(channelCompleter.future, completion('hello')); + }); testWidgets('resize webview', (WidgetTester tester) async { final Completer initialResizeCompleter = Completer(); @@ -263,7 +270,6 @@ Future main() async { expect(customUserAgent2, 'Custom_User_Agent2'); }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('use default platform userAgent after webView is rebuilt', (WidgetTester tester) async { final Completer controllerCompleter = @@ -313,7 +319,7 @@ Future main() async { final String customUserAgent2 = await _getUserAgent(controller); expect(customUserAgent2, defaultPlatformUserAgent); - }, skip: Platform.isAndroid && _skipDueToIssue86757); + }); group('Video playback policy', () { late String videoTestBase64; @@ -798,7 +804,6 @@ Future main() async { }); group('Programmatic Scroll', () { - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('setAndGetScrollPosition', (WidgetTester tester) async { const String scrollTestPage = ''' @@ -873,7 +878,7 @@ Future main() async { scrollPosY = await controller.getScrollY(); expect(scrollPosX, X_SCROLL * 2); expect(scrollPosY, Y_SCROLL * 2); - }, skip: Platform.isAndroid && _skipDueToIssue86757); + }); }); // Minimial end-to-end testing of the legacy Android implementation. @@ -889,7 +894,7 @@ Future main() async { testWidgets('initialUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); - final Completer loadCompleter = Completer(); + final Completer pageFinishedCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -899,18 +904,18 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, - onPageFinished: (String url) { - loadCompleter.complete(); - }, + onPageFinished: pageFinishedCompleter.complete, ), ), ); + final WebViewController controller = await controllerCompleter.future; - await loadCompleter.future; + await pageFinishedCompleter.future; + final String? currentUrl = await controller.currentUrl(); expect(currentUrl, primaryUrl); }); - }, skip: !Platform.isAndroid || _skipDueToIssue86757); + }, skip: !Platform.isAndroid); group('NavigationDelegate', () { const String blankPage = ''; @@ -1149,7 +1154,6 @@ Future main() async { expect(currentUrl, primaryUrl); }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('target _blank opens in same window', (WidgetTester tester) async { final Completer controllerCompleter = @@ -1175,9 +1179,8 @@ Future main() async { await pageLoaded.future; final String? currentUrl = await controller.currentUrl(); expect(currentUrl, primaryUrl); - }, skip: Platform.isAndroid && _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets( 'can open new window and go back', (WidgetTester tester) async { @@ -1213,9 +1216,8 @@ Future main() async { expect(controller.canGoBack(), completion(true)); await controller.goBack(); await pageLoaded.future; - expect(controller.currentUrl(), completion(primaryUrl)); + await expectLater(controller.currentUrl(), completion(primaryUrl)); }, - skip: _skipDueToIssue86757, ); testWidgets( @@ -1223,7 +1225,9 @@ Future main() async { (WidgetTester tester) async { final Completer controllerCompleter = Completer(); - final Completer onPageFinished = Completer(); + + Completer pageLoadCompleter = Completer(); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -1231,7 +1235,7 @@ Future main() async { key: GlobalKey(), initialUrl: primaryUrl, javascriptMode: JavascriptMode.unrestricted, - onPageFinished: (_) => onPageFinished.complete(), + onPageFinished: (_) => pageLoadCompleter.complete(), onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, @@ -1239,29 +1243,34 @@ Future main() async { ), ); - final WebViewController controller = await controllerCompleter.future; - await onPageFinished.future; + await pageLoadCompleter.future; + pageLoadCompleter = Completer(); + final WebViewController controller = await controllerCompleter.future; await controller.runJavascript('localStorage.setItem("myCat", "Tom");'); - - expect( - controller.runJavascriptReturningResult( - 'localStorage.getItem("myCat");', - ), - completion(_webviewString('Tom')), + final String myCatItem = await controller.runJavascriptReturningResult( + 'localStorage.getItem("myCat");', ); + expect(myCatItem, _webviewString('Tom')); await controller.clearCache(); + await pageLoadCompleter.future; - expect( - controller.runJavascriptReturningResult( + late final String? nullItem; + try { + nullItem = await controller.runJavascriptReturningResult( 'localStorage.getItem("myCat");', - ), - completion(_webviewNull()), - ); + ); + } catch (exception) { + if (defaultTargetPlatform == TargetPlatform.iOS && + exception is ArgumentError && + (exception.message as String).contains( + 'Result of JavaScript execution returned a `null` value.')) { + nullItem = ''; + } + } + expect(nullItem, _webviewNull()); }, - // TODO(bparrishMines): Unskip once https://github.com/flutter/plugins/pull/5086 lands and is published. - skip: Platform.isAndroid, ); } diff --git a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart index c5bf76d2c6cb..87507b424a7c 100644 --- a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart @@ -28,8 +28,6 @@ import 'package:webview_flutter_platform_interface/webview_flutter_platform_inte Future main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - const bool _skipDueToIssue86757 = true; - final HttpServer server = await HttpServer.bind(InternetAddress.anyIPv4, 0); server.forEach((HttpRequest request) { if (request.uri.path == '/hello.txt') { @@ -53,6 +51,7 @@ Future main() async { testWidgets('initialUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final Completer pageFinishedCompleter = Completer(); await tester.pumpWidget( MaterialApp( home: Directionality( @@ -63,19 +62,23 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageFinished: pageFinishedCompleter.complete, ), ), ), ); + final WebViewController controller = await controllerCompleter.future; + await pageFinishedCompleter.future; + final String? currentUrl = await controller.currentUrl(); expect(currentUrl, primaryUrl); - }, skip: _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('loadUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final StreamController pageLoads = StreamController(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -85,14 +88,20 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageFinished: (String url) { + pageLoads.add(url); + }, ), ), ); final WebViewController controller = await controllerCompleter.future; + await controller.loadUrl(secondaryUrl); - final String? currentUrl = await controller.currentUrl(); - expect(currentUrl, secondaryUrl); - }, skip: _skipDueToIssue86757); + await expectLater( + pageLoads.stream.firstWhere((String url) => url == secondaryUrl), + completion(secondaryUrl), + ); + }); testWidgets('evaluateJavascript', (WidgetTester tester) async { final Completer controllerCompleter = @@ -115,7 +124,6 @@ Future main() async { expect(result, equals('2')); }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('loadUrl with headers', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); @@ -154,15 +162,14 @@ Future main() async { final String content = await controller .runJavascriptReturningResult('document.documentElement.innerText'); expect(content.contains('flutter_test_header'), isTrue); - }, skip: _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('JavascriptChannel', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final List messagesReceived = []; + final Completer channelCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -179,7 +186,7 @@ Future main() async { JavascriptChannel( name: 'Echo', onMessageReceived: (JavascriptMessage message) { - messagesReceived.add(message.message); + channelCompleter.complete(message.message); }, ), }, @@ -196,10 +203,11 @@ Future main() async { await pageStarted.future; await pageLoaded.future; - expect(messagesReceived, isEmpty); + expect(channelCompleter.isCompleted, isFalse); await controller.runJavascript('Echo.postMessage("hello");'); - expect(messagesReceived, equals(['hello'])); - }, skip: _skipDueToIssue86757); + + await expectLater(channelCompleter.future, completion('hello')); + }); testWidgets('resize webview', (WidgetTester tester) async { final Completer initialResizeCompleter = Completer(); @@ -268,7 +276,6 @@ Future main() async { expect(customUserAgent2, 'Custom_User_Agent2'); }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('use default platform userAgent after webView is rebuilt', (WidgetTester tester) async { final Completer controllerCompleter = @@ -318,7 +325,7 @@ Future main() async { final String customUserAgent2 = await _getUserAgent(controller); expect(customUserAgent2, defaultPlatformUserAgent); - }, skip: _skipDueToIssue86757); + }); group('Video playback policy', () { late String videoTestBase64; @@ -744,7 +751,6 @@ Future main() async { }); group('Programmatic Scroll', () { - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('setAndGetScrollPosition', (WidgetTester tester) async { const String scrollTestPage = ''' @@ -819,7 +825,7 @@ Future main() async { scrollPosY = await controller.getScrollY(); expect(scrollPosX, X_SCROLL * 2); expect(scrollPosY, Y_SCROLL * 2); - }, skip: _skipDueToIssue86757); + }); }); group('SurfaceAndroidWebView', () { @@ -831,7 +837,6 @@ Future main() async { WebView.platform = AndroidWebView(); }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('setAndGetScrollPosition', (WidgetTester tester) async { const String scrollTestPage = ''' @@ -898,9 +903,8 @@ Future main() async { scrollPosY = await controller.getScrollY(); expect(X_SCROLL * 2, scrollPosX); expect(Y_SCROLL * 2, scrollPosY); - }, skip: _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets('inputs are scrolled into view when focused', (WidgetTester tester) async { const String scrollTestPage = ''' @@ -1006,7 +1010,7 @@ Future main() async { lastInputClientRectRelativeToViewport['right'] <= viewportRectRelativeToViewport['right'], isTrue); - }, skip: _skipDueToIssue86757); + }); }); group('NavigationDelegate', () { @@ -1266,11 +1270,8 @@ Future main() async { await pageLoaded.future; final String? currentUrl = await controller.currentUrl(); expect(currentUrl, primaryUrl); - }, - // Flaky on Android: https://github.com/flutter/flutter/issues/86757 - skip: _skipDueToIssue86757); + }); - // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757 testWidgets( 'can open new window and go back', (WidgetTester tester) async { @@ -1306,9 +1307,8 @@ Future main() async { expect(controller.canGoBack(), completion(true)); await controller.goBack(); await pageLoaded.future; - expect(controller.currentUrl(), completion(primaryUrl)); + await expectLater(controller.currentUrl(), completion(primaryUrl)); }, - skip: _skipDueToIssue86757, ); testWidgets( @@ -1369,13 +1369,14 @@ Future main() async { final WebViewController controller = await controllerCompleter.future; await pageLoadCompleter.future; - expect(controller.runJavascriptReturningResult('iframeLoaded'), - completion('true')); - expect( - controller.runJavascriptReturningResult( - 'document.querySelector("p") && document.querySelector("p").textContent'), - completion('null'), + final String iframeLoaded = + await controller.runJavascriptReturningResult('iframeLoaded'); + expect(iframeLoaded, 'true'); + + final String elementText = await controller.runJavascriptReturningResult( + 'document.querySelector("p") && document.querySelector("p").textContent', ); + expect(elementText, 'null'); }, ); @@ -1384,7 +1385,9 @@ Future main() async { (WidgetTester tester) async { final Completer controllerCompleter = Completer(); - final Completer onPageFinished = Completer(); + + Completer pageLoadCompleter = Completer(); + await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -1392,7 +1395,7 @@ Future main() async { key: GlobalKey(), initialUrl: primaryUrl, javascriptMode: JavascriptMode.unrestricted, - onPageFinished: (_) => onPageFinished.complete(), + onPageFinished: (_) => pageLoadCompleter.complete(), onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, @@ -1400,26 +1403,23 @@ Future main() async { ), ); - final WebViewController controller = await controllerCompleter.future; - await onPageFinished.future; + await pageLoadCompleter.future; + pageLoadCompleter = Completer(); + final WebViewController controller = await controllerCompleter.future; await controller.runJavascript('localStorage.setItem("myCat", "Tom");'); - - expect( - controller.runJavascriptReturningResult( - 'localStorage.getItem("myCat");', - ), - completion('"Tom"'), + final String myCatItem = await controller.runJavascriptReturningResult( + 'localStorage.getItem("myCat");', ); + expect(myCatItem, '"Tom"'); await controller.clearCache(); + await pageLoadCompleter.future; - expect( - controller.runJavascriptReturningResult( - 'localStorage.getItem("myCat");', - ), - completion('null'), + final String nullItem = await controller.runJavascriptReturningResult( + 'localStorage.getItem("myCat");', ); + expect(nullItem, 'null'); }, ); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart index 1119f7457bc9..dd642b373124 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart @@ -51,6 +51,7 @@ Future main() async { testWidgets('initialUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final Completer pageFinishedCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -60,10 +61,14 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageFinished: pageFinishedCompleter.complete, ), ), ); + final WebViewController controller = await controllerCompleter.future; + await pageFinishedCompleter.future; + final String? currentUrl = await controller.currentUrl(); expect(currentUrl, primaryUrl); }); @@ -86,12 +91,14 @@ Future main() async { await tester.pumpAndSettle(); }); - expect(gcCompleter.future, completion(0)); + final int gcIdentifier = await gcCompleter.future; + expect(gcIdentifier, 0); }, timeout: const Timeout(Duration(seconds: 10))); testWidgets('loadUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final StreamController pageLoads = StreamController(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -101,13 +108,19 @@ Future main() async { onWebViewCreated: (WebViewController controller) { controllerCompleter.complete(controller); }, + onPageFinished: (String url) { + pageLoads.add(url); + }, ), ), ); final WebViewController controller = await controllerCompleter.future; + await controller.loadUrl(secondaryUrl); - final String? currentUrl = await controller.currentUrl(); - expect(currentUrl, secondaryUrl); + await expectLater( + pageLoads.stream.firstWhere((String url) => url == secondaryUrl), + completion(secondaryUrl), + ); }); testWidgets('evaluateJavascript', (WidgetTester tester) async { @@ -176,7 +189,7 @@ Future main() async { Completer(); final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final List messagesReceived = []; + final Completer channelCompleter = Completer(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -193,7 +206,7 @@ Future main() async { JavascriptChannel( name: 'Echo', onMessageReceived: (JavascriptMessage message) { - messagesReceived.add(message.message); + channelCompleter.complete(message.message); }, ), }, @@ -210,9 +223,10 @@ Future main() async { await pageStarted.future; await pageLoaded.future; - expect(messagesReceived, isEmpty); + expect(channelCompleter.isCompleted, isFalse); await controller.runJavascript('Echo.postMessage("hello");'); - expect(messagesReceived, equals(['hello'])); + + await expectLater(channelCompleter.future, completion('hello')); }); testWidgets('resize webview', (WidgetTester tester) async { @@ -1183,10 +1197,8 @@ Future main() async { expect(controller.canGoBack(), completion(true)); await controller.goBack(); await pageLoaded.future; - expect(controller.currentUrl(), completion(primaryUrl)); + await expectLater(controller.currentUrl(), completion(primaryUrl)); }, - // Flaky; see https://github.com/flutter/flutter/issues/90976 - skip: true, ); }