diff --git a/example/integration_test/constants.dart b/example/integration_test/constants.dart index c5d3faba..8bcf7e4a 100644 --- a/example/integration_test/constants.dart +++ b/example/integration_test/constants.dart @@ -5,5 +5,9 @@ final TEST_URL_1 = Uri.parse('https://github.com/flutter'); final TEST_URL_2 = Uri.parse('https://www.google.com/'); final TEST_URL_3 = Uri.parse('https://github.com/pichillilorenzo/flutter_inappwebview'); final TEST_URL_4 = Uri.parse('https://www.youtube.com/'); -final TEST_WEB_PLATFORM_URL_1 = Uri.parse(Uri.base.toString().replaceFirst("/#/", "/") + 'page.html'); -final TEST_NOT_A_WEBSITE_URL = Uri.parse('https://www.notawebsite..com'); \ No newline at end of file +final TEST_URL_404 = Uri.parse('https://google.com/404'); +final TEST_WEB_PLATFORM_BASE_URL = Uri.parse(Uri.base.toString().replaceFirst("/#/", "/")); +final TEST_WEB_PLATFORM_URL_1 = Uri.parse(TEST_WEB_PLATFORM_BASE_URL.toString() + 'page.html'); +final TEST_NOT_A_WEBSITE_URL = Uri.parse('https://www.notawebsite..com'); +final TEST_CHROME_SAFE_BROWSING_MALWARE = Uri.parse('chrome://safe-browsing/match?type=malware'); +final TEST_PERMISSION_SITE = Uri.parse('https://permission.site/'); diff --git a/example/integration_test/in_app_webview/content_blocker.dart b/example/integration_test/in_app_webview/content_blocker.dart new file mode 100644 index 00000000..688ba964 --- /dev/null +++ b/example/integration_test/in_app_webview/content_blocker.dart @@ -0,0 +1,50 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void contentBlocker() { + final shouldSkip = kIsWeb || ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('Content Blocker', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + initialSettings: InAppWebViewSettings(clearCache: true, contentBlockers: [ + ContentBlocker( + trigger: + ContentBlockerTrigger(urlFilter: ".*", resourceType: [ + ContentBlockerTriggerResourceType.IMAGE, + ContentBlockerTriggerResourceType.STYLE_SHEET + ], ifTopUrl: [ + TEST_CROSS_PLATFORM_URL_1.toString() + ]), + action: ContentBlockerAction( + type: ContentBlockerActionType.BLOCK)) + ]), + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + await expectLater(pageLoaded.future, completes); + }, skip: shouldSkip); +} \ No newline at end of file diff --git a/example/integration_test/in_app_webview/http_auth_credential_database.dart b/example/integration_test/in_app_webview/http_auth_credential_database.dart new file mode 100644 index 00000000..2a1e9bcd --- /dev/null +++ b/example/integration_test/in_app_webview/http_auth_credential_database.dart @@ -0,0 +1,125 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../.env.dart'; + +void httpAuthCredentialDatabase() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('Http Auth Credential Database', () { + testWidgets('use saved credentials', (WidgetTester tester) async { + HttpAuthCredentialDatabase httpAuthCredentialDatabase = + HttpAuthCredentialDatabase.instance(); + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + + httpAuthCredentialDatabase.setHttpAuthCredential( + protectionSpace: URLProtectionSpace( + host: environment["NODE_SERVER_IP"]!, + protocol: "http", + realm: "Node", + port: 8081), + credential: + URLCredential(username: "USERNAME", password: "PASSWORD")); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest( + url: + Uri.parse("http://${environment["NODE_SERVER_IP"]}:8081/")), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + initialSettings: InAppWebViewSettings( + clearCache: true, + ), + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onReceivedHttpAuthRequest: (controller, challenge) async { + return new HttpAuthResponse( + action: + HttpAuthResponseAction.USE_SAVED_HTTP_AUTH_CREDENTIALS); + }, + ), + ), + ); + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final String h1Content = await controller.evaluateJavascript( + source: "document.body.querySelector('h1').textContent"); + expect(h1Content, "Authorized"); + + var credentials = await httpAuthCredentialDatabase.getHttpAuthCredentials( + protectionSpace: URLProtectionSpace( + host: environment["NODE_SERVER_IP"]!, + protocol: "http", + realm: "Node", + port: 8081)); + expect(credentials.length, 1); + + await httpAuthCredentialDatabase.clearAllAuthCredentials(); + credentials = await httpAuthCredentialDatabase.getHttpAuthCredentials( + protectionSpace: URLProtectionSpace( + host: environment["NODE_SERVER_IP"]!, + protocol: "http", + realm: "Node", + port: 8081)); + expect(credentials, isEmpty); + }); + + testWidgets('save credentials', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest( + url: + Uri.parse("http://${environment["NODE_SERVER_IP"]}:8081/")), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + initialSettings: InAppWebViewSettings( + clearCache: true, + ), + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onReceivedHttpAuthRequest: (controller, challenge) async { + return new HttpAuthResponse( + username: "USERNAME", + password: "PASSWORD", + action: HttpAuthResponseAction.PROCEED, + permanentPersistence: true); + }, + ), + ), + ); + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final String h1Content = await controller.evaluateJavascript( + source: "document.body.querySelector('h1').textContent"); + expect(h1Content, "Authorized"); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/intercept_fetch_request.dart b/example/integration_test/in_app_webview/intercept_fetch_request.dart new file mode 100644 index 00000000..bb7b1a87 --- /dev/null +++ b/example/integration_test/in_app_webview/intercept_fetch_request.dart @@ -0,0 +1,346 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../.env.dart'; + +void interceptFetchRequest() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('intercept fetch request', () { + testWidgets('send string data', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer> fetchPostCompleter = + Completer>(); + final Completer shouldInterceptFetchPostRequestCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + InAppWebViewFetchTest + + +

InAppWebViewFetchTest

+ + + + """), + initialSettings: InAppWebViewSettings( + clearCache: true, + useShouldInterceptFetchRequest: true, + ), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + + controller.addJavaScriptHandler( + handlerName: "fetchPost", + callback: (args) { + fetchPostCompleter + .complete(args[0] as Map); + }); + }, + shouldInterceptFetchRequest: (controller, fetchRequest) async { + assert(fetchRequest.body == "firstname=Foo&lastname=Bar"); + + fetchRequest.body = "firstname=Foo2&lastname=Bar2"; + shouldInterceptFetchPostRequestCompleter.complete(); + return fetchRequest; + }, + ), + ), + ); + + await shouldInterceptFetchPostRequestCompleter.future; + var fetchPostCompleterValue = await fetchPostCompleter.future; + + expect( + mapEquals(fetchPostCompleterValue, + {'firstname': 'Foo2', 'lastname': 'Bar2'}), + true); + }); + + testWidgets('send json data', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer> fetchPostCompleter = + Completer>(); + final Completer shouldInterceptFetchPostRequestCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + InAppWebViewFetchTest + + +

InAppWebViewFetchTest

+ + + + """), + initialSettings: InAppWebViewSettings( + clearCache: true, + useShouldInterceptFetchRequest: true, + ), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + + controller.addJavaScriptHandler( + handlerName: "fetchPost", + callback: (args) { + fetchPostCompleter + .complete(args[0] as Map); + }); + }, + shouldInterceptFetchRequest: (controller, fetchRequest) async { + String body = fetchRequest.body; + assert(body.contains('"firstname":"Foo"') && + body.contains('"lastname":"Bar"')); + + fetchRequest.body = '{"firstname": "Foo2", "lastname": "Bar2"}'; + shouldInterceptFetchPostRequestCompleter.complete(); + return fetchRequest; + }, + ), + ), + ); + + await shouldInterceptFetchPostRequestCompleter.future; + var fetchPostCompleterValue = await fetchPostCompleter.future; + + expect( + mapEquals(fetchPostCompleterValue, + {'firstname': 'Foo2', 'lastname': 'Bar2'}), + true); + }); + + testWidgets('send URLSearchParams data', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer> fetchPostCompleter = + Completer>(); + final Completer shouldInterceptFetchPostRequestCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + InAppWebViewFetchTest + + +

InAppWebViewFetchTest

+ + + + """), + initialSettings: InAppWebViewSettings( + clearCache: true, + useShouldInterceptFetchRequest: true, + ), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + + controller.addJavaScriptHandler( + handlerName: "fetchPost", + callback: (args) { + fetchPostCompleter + .complete(args[0] as Map); + }); + }, + shouldInterceptFetchRequest: (controller, fetchRequest) async { + assert(fetchRequest.body == "firstname=Foo&lastname=Bar"); + + fetchRequest.body = "firstname=Foo2&lastname=Bar2"; + shouldInterceptFetchPostRequestCompleter.complete(); + return fetchRequest; + }, + ), + ), + ); + + await shouldInterceptFetchPostRequestCompleter.future; + var fetchPostCompleterValue = await fetchPostCompleter.future; + + expect( + mapEquals(fetchPostCompleterValue, + {'firstname': 'Foo2', 'lastname': 'Bar2'}), + true); + }); + + testWidgets('send FormData', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer> fetchPostCompleter = + Completer>(); + final Completer shouldInterceptFetchPostRequestCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + InAppWebViewFetchTest + + +

InAppWebViewFetchTest

+ + + + """), + initialSettings: InAppWebViewSettings( + clearCache: true, + useShouldInterceptFetchRequest: true, + ), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + + controller.addJavaScriptHandler( + handlerName: "fetchPost", + callback: (args) { + fetchPostCompleter + .complete(args[0] as Map); + }); + }, + shouldInterceptFetchRequest: (controller, fetchRequest) async { + assert(fetchRequest.body != null); + + var body = fetchRequest.body.cast(); + var bodyString = String.fromCharCodes(body); + assert(bodyString.indexOf("WebKitFormBoundary") >= 0); + + fetchRequest.body = utf8.encode(bodyString + .replaceFirst("Foo", "Foo2") + .replaceFirst("Bar", "Bar2")); + shouldInterceptFetchPostRequestCompleter.complete(); + return fetchRequest; + }, + ), + ), + ); + + await shouldInterceptFetchPostRequestCompleter.future; + var fetchPostCompleterValue = await fetchPostCompleter.future; + + expect( + mapEquals(fetchPostCompleterValue, + {'firstname': 'Foo2', 'lastname': 'Bar2'}), + true); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/javascript_dialogs.dart b/example/integration_test/in_app_webview/javascript_dialogs.dart new file mode 100644 index 00000000..8d026c39 --- /dev/null +++ b/example/integration_test/in_app_webview/javascript_dialogs.dart @@ -0,0 +1,81 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void javascriptDialogs() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('javascript dialogs', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer alertCompleter = + Completer(); + final Completer confirmCompleter = Completer(); + final Completer promptCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialFile: "test_assets/in_app_webview_on_js_dialog_test.html", + initialSettings: InAppWebViewSettings( + clearCache: true, + ), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + + controller.addJavaScriptHandler( + handlerName: 'confirm', + callback: (args) { + confirmCompleter.complete(args[0] as bool); + }); + + controller.addJavaScriptHandler( + handlerName: 'prompt', + callback: (args) { + promptCompleter.complete(args[0] as String); + }); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onJsAlert: (controller, jsAlertRequest) async { + JsAlertResponseAction action = JsAlertResponseAction.CONFIRM; + alertCompleter.complete(jsAlertRequest); + return JsAlertResponse(handledByClient: true, action: action); + }, + onJsConfirm: (controller, jsConfirmRequest) async { + JsConfirmResponseAction action = JsConfirmResponseAction.CONFIRM; + return JsConfirmResponse(handledByClient: true, action: action); + }, + onJsPrompt: (controller, jsPromptRequest) async { + JsPromptResponseAction action = JsPromptResponseAction.CONFIRM; + return JsPromptResponse( + handledByClient: true, action: action, value: 'new value'); + }, + ), + ), + ); + + await pageLoaded.future; + + final JsAlertRequest jsAlertRequest = await alertCompleter.future; + expect(jsAlertRequest.message, 'alert message'); + + final bool onJsConfirmValue = await confirmCompleter.future; + expect(onJsConfirmValue, true); + + final String onJsPromptValue = await promptCompleter.future; + expect(onJsPromptValue, 'new value'); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/load_url.dart b/example/integration_test/in_app_webview/load_url.dart index c2f071f3..0b9d7553 100644 --- a/example/integration_test/in_app_webview/load_url.dart +++ b/example/integration_test/in_app_webview/load_url.dart @@ -8,11 +8,12 @@ import 'package:flutter_test/flutter_test.dart'; import '../constants.dart'; void loadUrl() { - final shouldSkip = !kIsWeb || ![ - TargetPlatform.android, - TargetPlatform.iOS, - TargetPlatform.macOS, - ].contains(defaultTargetPlatform); + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); group('load url', () { final shouldSkipTest1 = !kIsWeb || @@ -25,15 +26,14 @@ void loadUrl() { testWidgets('loadUrl', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final StreamController pageLoads = - StreamController.broadcast(); + StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: InAppWebView( key: GlobalKey(), - initialUrlRequest: - URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, @@ -44,7 +44,7 @@ void loadUrl() { ), ); final InAppWebViewController controller = - await controllerCompleter.future; + await controllerCompleter.future; var url = await pageLoads.stream.first; expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); @@ -66,22 +66,19 @@ void loadUrl() { testWidgets('loadUrl with headers', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final StreamController pageStarts = - StreamController.broadcast(); + StreamController.broadcast(); final StreamController pageLoads = - StreamController.broadcast(); + StreamController.broadcast(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: InAppWebView( key: GlobalKey(), - initialUrlRequest: - URLRequest(url: TEST_URL_1), + initialUrlRequest: URLRequest(url: TEST_URL_1), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, - initialSettings: InAppWebViewSettings( - javaScriptEnabled: true - ), + initialSettings: InAppWebViewSettings(javaScriptEnabled: true), onLoadStart: (controller, url) { pageStarts.add(url!.toString()); }, @@ -92,7 +89,7 @@ void loadUrl() { ), ); final InAppWebViewController controller = - await controllerCompleter.future; + await controllerCompleter.future; final Map headers = { 'test_header': 'flutter_test_header' }; @@ -114,4 +111,4 @@ void loadUrl() { pageLoads.close(); }, skip: shouldSkipTest2); }, skip: shouldSkip); -} \ No newline at end of file +} diff --git a/example/integration_test/in_app_webview/main.dart b/example/integration_test/in_app_webview/main.dart index 67d901c0..c20a2257 100644 --- a/example/integration_test/in_app_webview/main.dart +++ b/example/integration_test/in_app_webview/main.dart @@ -1,19 +1,45 @@ import 'package:flutter_test/flutter_test.dart'; import 'audio_playback_policy.dart'; +import 'content_blocker.dart'; import 'get_title.dart'; +import 'http_auth_credential_database.dart'; import 'initial_url_request.dart'; import 'intercept_ajax_request.dart'; +import 'intercept_fetch_request.dart'; import 'javascript_code_evaluation.dart'; +import 'javascript_dialogs.dart'; import 'javascript_handler.dart'; import 'load_file_url.dart'; import 'load_url.dart'; +import 'on_console_message.dart'; +import 'on_download_start_request.dart'; +import 'on_find_result_received.dart'; +import 'on_js_before_unload.dart'; import 'on_load_error.dart'; +import 'on_load_http_error.dart'; +import 'on_load_resource.dart'; +import 'on_load_resource_custom_scheme.dart'; +import 'on_page_commit_visible.dart'; +import 'on_permission_request.dart'; +import 'on_print.dart'; +import 'on_progress_changed.dart'; +import 'on_received_icon.dart'; +import 'on_received_touch_icon_url.dart'; +import 'on_safe_browsing_hit.dart'; +import 'on_scroll_changed.dart'; +import 'on_title_changed.dart'; +import 'on_update_visited_history.dart'; +import 'on_window_blur.dart'; +import 'on_window_focus.dart'; +import 'on_zoom_scale_changed.dart'; import 'programmatic_scroll.dart'; import 'resize_webview.dart'; import 'set_custom_useragent.dart'; import 'set_get_settings.dart'; +import 'should_intercept_request.dart'; import 'should_override_url_loading.dart'; +import 'ssl_request.dart'; import 'video_playback_policy.dart'; import 'webview_windows.dart'; @@ -35,5 +61,31 @@ void main() { onLoadError(); webViewWindows(); interceptAjaxRequest(); + interceptFetchRequest(); + contentBlocker(); + httpAuthCredentialDatabase(); + onConsoleMessage(); + onFindResultReceived(); + onDownloadStartRequest(); + javascriptDialogs(); + onLoadHttpError(); + onLoadResourceCustomScheme(); + onLoadResource(); + onUpdateVisitedHistory(); + onProgressChanged(); + onSafeBrowsingHit(); + onScrollChanged(); + sslRequest(); + onPrint(); + onWindowFocus(); + onWindowBlur(); + onPageCommitVisible(); + onTitleChanged(); + onZoomScaleChanged(); + onPermissionRequest(); + shouldInterceptRequest(); + onReceivedIcon(); + onReceivedTouchIconUrl(); + onJsBeforeUnload(); }); } \ No newline at end of file diff --git a/example/integration_test/in_app_webview/on_console_message.dart b/example/integration_test/in_app_webview/on_console_message.dart new file mode 100644 index 00000000..3275d683 --- /dev/null +++ b/example/integration_test/in_app_webview/on_console_message.dart @@ -0,0 +1,47 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onConsoleMessage() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onConsoleMessage', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer onConsoleMessageCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialFile: !kIsWeb + ? "test_assets/in_app_webview_on_console_message_test.html" + : null, + initialUrlRequest: + kIsWeb ? URLRequest(url: TEST_WEB_PLATFORM_URL_1) : null, + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onConsoleMessage: (controller, consoleMessage) { + onConsoleMessageCompleter.complete(consoleMessage); + }, + ), + ), + ); + + final ConsoleMessage consoleMessage = + await onConsoleMessageCompleter.future; + expect(consoleMessage.message, 'message'); + expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_download_start_request.dart b/example/integration_test/in_app_webview/on_download_start_request.dart new file mode 100644 index 00000000..85a9b080 --- /dev/null +++ b/example/integration_test/in_app_webview/on_download_start_request.dart @@ -0,0 +1,62 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../.env.dart'; + +void onDownloadStartRequest() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onDownloadStartRequest', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer onDownloadStartCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + InAppWebViewOnDownloadStartTest + + +

InAppWebViewOnDownloadStartTest

+ download file + + + + """), + initialSettings: + InAppWebViewSettings(clearCache: true, useOnDownloadStart: true), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onDownloadStartRequest: (controller, request) { + onDownloadStartCompleter.complete(request.url.toString()); + }, + ), + ), + ); + + final String url = await onDownloadStartCompleter.future; + expect( + url, "http://${environment["NODE_SERVER_IP"]}:8082/test-download-file"); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_find_result_received.dart b/example/integration_test/in_app_webview/on_find_result_received.dart new file mode 100644 index 00000000..00bfd2b6 --- /dev/null +++ b/example/integration_test/in_app_webview/on_find_result_received.dart @@ -0,0 +1,49 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onFindResultReceived() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onFindResultReceived', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer numberOfMatchesCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialFile: "test_assets/in_app_webview_initial_file_test.html", + initialSettings: InAppWebViewSettings( + clearCache: true, + ), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + controller.findAllAsync(find: "InAppWebViewInitialFileTest"); + }, + onFindResultReceived: (controller, int activeMatchOrdinal, + int numberOfMatches, bool isDoneCounting) async { + if (isDoneCounting && !numberOfMatchesCompleter.isCompleted) { + numberOfMatchesCompleter.complete(numberOfMatches); + } + }, + ), + ), + ); + + final int numberOfMatches = await numberOfMatchesCompleter.future; + expect(numberOfMatches, 2); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_js_before_unload.dart b/example/integration_test/in_app_webview/on_js_before_unload.dart new file mode 100644 index 00000000..e0da3d38 --- /dev/null +++ b/example/integration_test/in_app_webview/on_js_before_unload.dart @@ -0,0 +1,59 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onJsBeforeUnload() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('onJsBeforeUnload', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer onJsBeforeUnloadCompleter = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) async { + await controller.evaluateJavascript(source: """ + window.addEventListener('beforeunload', function (e) { + e.preventDefault(); + e.returnValue = ''; + }); + """); + if (!pageLoaded.isCompleted) { + pageLoaded.complete(); + } + }, + onJsBeforeUnload: (controller, jsBeforeUnloadRequest) async { + onJsBeforeUnloadCompleter + .complete(jsBeforeUnloadRequest.url.toString()); + return null; + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + await controller.evaluateJavascript( + source: "window.location.href = '$TEST_URL_1';"); + final String url = await onJsBeforeUnloadCompleter.future; + expect(url, TEST_URL_1.toString()); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_load_http_error.dart b/example/integration_test/in_app_webview/on_load_http_error.dart new file mode 100644 index 00000000..e423bd94 --- /dev/null +++ b/example/integration_test/in_app_webview/on_load_http_error.dart @@ -0,0 +1,42 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onLoadHttpError() { + final shouldSkip = kIsWeb || ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onLoadHttpError', (WidgetTester tester) async { + final Completer errorUrlCompleter = Completer(); + final Completer statusCodeCompleter = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_404), + onLoadHttpError: (controller, url, statusCode, description) async { + errorUrlCompleter.complete(url.toString()); + statusCodeCompleter.complete(statusCode); + }, + ), + ), + ); + + final String url = await errorUrlCompleter.future; + final int code = await statusCodeCompleter.future; + + expect(url, TEST_URL_404.toString()); + expect(code, 404); + }, skip: shouldSkip); +} \ No newline at end of file diff --git a/example/integration_test/in_app_webview/on_load_resource.dart b/example/integration_test/in_app_webview/on_load_resource.dart new file mode 100644 index 00000000..2578c57f --- /dev/null +++ b/example/integration_test/in_app_webview/on_load_resource.dart @@ -0,0 +1,55 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onLoadResource() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onLoadResource', (WidgetTester tester) async { + List resourceList = [ + "https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css", + "https://code.jquery.com/jquery-3.3.1.min.js", + "https://via.placeholder.com/100x50" + ]; + List resourceLoaded = []; + + final Completer loadedResourceCompleter = Completer(); + final Completer pageLoaded = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialFile: + "test_assets/in_app_webview_on_load_resource_test.html", + initialSettings: + InAppWebViewSettings(clearCache: true, useOnLoadResource: true), + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onLoadResource: (controller, response) async { + resourceLoaded.add(response.url!.toString()); + if (resourceLoaded.length == resourceList.length) { + loadedResourceCompleter.complete(); + } + }), + ), + ); + + await pageLoaded.future; + await loadedResourceCompleter.future; + + expect(resourceLoaded, unorderedEquals(resourceList)); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_load_resource_custom_scheme.dart b/example/integration_test/in_app_webview/on_load_resource_custom_scheme.dart new file mode 100644 index 00000000..76196ad6 --- /dev/null +++ b/example/integration_test/in_app_webview/on_load_resource_custom_scheme.dart @@ -0,0 +1,60 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void onLoadResourceCustomScheme() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onLoadResourceCustomScheme', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer imageLoaded = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialFile: + "test_assets/in_app_webview_on_load_resource_custom_scheme_test.html", + initialSettings: InAppWebViewSettings( + clearCache: true, + resourceCustomSchemes: ["my-special-custom-scheme"]), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + + controller.addJavaScriptHandler( + handlerName: "imageLoaded", + callback: (args) { + imageLoaded.complete(); + }); + }, + onLoadResourceCustomScheme: (controller, url) async { + if (url.scheme == "my-special-custom-scheme") { + var bytes = await rootBundle.load("test_assets/" + + url + .toString() + .replaceFirst("my-special-custom-scheme://", "", 0)); + var response = CustomSchemeResponse( + data: bytes.buffer.asUint8List(), + contentType: "image/svg+xml", + contentEncoding: "utf-8"); + return response; + } + return null; + }, + ), + ), + ); + + await expectLater(imageLoaded.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_page_commit_visible.dart b/example/integration_test/in_app_webview/on_page_commit_visible.dart new file mode 100644 index 00000000..f3b1ae10 --- /dev/null +++ b/example/integration_test/in_app_webview/on_page_commit_visible.dart @@ -0,0 +1,43 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onPageCommitVisible() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onPageCommitVisible', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer onPageCommitVisibleCompleter = + Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onPageCommitVisible: (controller, url) { + onPageCommitVisibleCompleter.complete(url?.toString()); + }, + ), + ), + ); + + final String? url = await onPageCommitVisibleCompleter.future; + expect(url, TEST_URL_1.toString()); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_permission_request.dart b/example/integration_test/in_app_webview/on_permission_request.dart new file mode 100644 index 00000000..e9520d54 --- /dev/null +++ b/example/integration_test/in_app_webview/on_permission_request.dart @@ -0,0 +1,61 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onPermissionRequest() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var expectedValue = []; + if (defaultTargetPlatform == TargetPlatform.android) { + expectedValue = [PermissionResourceType.RESOURCE_VIDEO_CAPTURE]; + } else if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { + expectedValue = [PermissionResourceType.CAMERA]; + } + + testWidgets('onPermissionRequest', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer> onPermissionRequestCompleter = + Completer>(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: TEST_PERMISSION_SITE), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onPermissionRequest: + (controller, PermissionRequest permissionRequest) async { + onPermissionRequestCompleter.complete(permissionRequest.resources); + }, + ), + ), + ); + + final InAppWebViewController controller = await controllerCompleter.future; + await pageLoaded.future; + await controller.evaluateJavascript( + source: "document.querySelector('#camera').click();"); + final List resources = + await onPermissionRequestCompleter.future; + + expect(listEquals(resources, expectedValue), true); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_print.dart b/example/integration_test/in_app_webview/on_print.dart new file mode 100644 index 00000000..c4e19d36 --- /dev/null +++ b/example/integration_test/in_app_webview/on_print.dart @@ -0,0 +1,40 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onPrint() { + final shouldSkip = !kIsWeb || ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('onPrint', (WidgetTester tester) async { + final Completer onPrintCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: url), + onLoadStop: (controller, url) async { + await controller.evaluateJavascript(source: "window.print();"); + }, + onPrint: (controller, url) { + onPrintCompleter.complete(url?.toString()); + }, + ), + ), + ); + final String printUrl = await onPrintCompleter.future; + expect(printUrl, url.toString()); + }, skip: shouldSkip); +} \ No newline at end of file diff --git a/example/integration_test/in_app_webview/on_progress_changed.dart b/example/integration_test/in_app_webview/on_progress_changed.dart new file mode 100644 index 00000000..61709200 --- /dev/null +++ b/example/integration_test/in_app_webview/on_progress_changed.dart @@ -0,0 +1,40 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onProgressChanged() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onProgressChanged', (WidgetTester tester) async { + final Completer onProgressChangedCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_1), + initialSettings: InAppWebViewSettings( + clearCache: true, + ), + onProgressChanged: (controller, progress) { + if (progress == 100) { + onProgressChangedCompleter.complete(); + } + }, + ), + ), + ); + await expectLater(onProgressChangedCompleter.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_received_icon.dart b/example/integration_test/in_app_webview/on_received_icon.dart new file mode 100644 index 00000000..b92f0926 --- /dev/null +++ b/example/integration_test/in_app_webview/on_received_icon.dart @@ -0,0 +1,47 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onReceivedIcon() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('onReceivedIcon', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer onReceivedIconCompleter = + Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onReceivedIcon: (controller, icon) { + onReceivedIconCompleter.complete(icon); + }, + ), + ), + ); + + await pageLoaded.future; + final Uint8List icon = await onReceivedIconCompleter.future; + expect(icon, isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_received_touch_icon_url.dart b/example/integration_test/in_app_webview/on_received_touch_icon_url.dart new file mode 100644 index 00000000..80978ea5 --- /dev/null +++ b/example/integration_test/in_app_webview/on_received_touch_icon_url.dart @@ -0,0 +1,52 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onReceivedTouchIconUrl() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('onReceivedTouchIconUrl', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer onReceivedTouchIconUrlCompleter = + Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + + + + + """), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onReceivedTouchIconUrl: (controller, url, precomposed) { + onReceivedTouchIconUrlCompleter.complete(url.toString()); + }, + ), + ), + ); + + final String url = await onReceivedTouchIconUrlCompleter.future; + + expect(url, "https://placehold.it/72x72"); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_safe_browsing_hit.dart b/example/integration_test/in_app_webview/on_safe_browsing_hit.dart new file mode 100644 index 00000000..e8e86af8 --- /dev/null +++ b/example/integration_test/in_app_webview/on_safe_browsing_hit.dart @@ -0,0 +1,48 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onSafeBrowsingHit() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('onSafeBrowsingHit', (WidgetTester tester) async { + final Completer pageLoaded = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest( + url: TEST_CHROME_SAFE_BROWSING_MALWARE), + initialSettings: InAppWebViewSettings( + // if I set javaScriptEnabled to true, it will crash! + javaScriptEnabled: false, + clearCache: true, + safeBrowsingEnabled: true, + ), + onWebViewCreated: (controller) { + controller.startSafeBrowsing(); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(url!.toString()); + }, + onSafeBrowsingHit: (controller, url, threatType) async { + return SafeBrowsingResponse( + report: true, action: SafeBrowsingResponseAction.PROCEED); + }, + ), + ), + ); + + final String url = await pageLoaded.future; + expect(url, TEST_CHROME_SAFE_BROWSING_MALWARE.toString()); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_scroll_changed.dart b/example/integration_test/in_app_webview/on_scroll_changed.dart new file mode 100644 index 00000000..261809bc --- /dev/null +++ b/example/integration_test/in_app_webview/on_scroll_changed.dart @@ -0,0 +1,54 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onScrollChanged() { + final shouldSkip = !kIsWeb || ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('onScrollChanged', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer onScrollChangedCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onScrollChanged: (controller, x, y) { + if (x == 0 && y == 500) { + onScrollChangedCompleter.complete(); + } + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + controller.scrollTo(x: 0, y: 500); + await tester.pumpAndSettle(Duration(seconds: 1)); + + await expectLater(onScrollChangedCompleter.future, completes); + }, skip: shouldSkip); +} \ No newline at end of file diff --git a/example/integration_test/in_app_webview/on_title_changed.dart b/example/integration_test/in_app_webview/on_title_changed.dart new file mode 100644 index 00000000..b3ae6235 --- /dev/null +++ b/example/integration_test/in_app_webview/on_title_changed.dart @@ -0,0 +1,54 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onTitleChanged() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('onTitleChanged', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer onTitleChangedCompleter = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onTitleChanged: (controller, title) { + if (title == "title test") { + onTitleChangedCompleter.complete(); + } + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + await controller.evaluateJavascript( + source: "document.title = 'title test';"); + await expectLater(onTitleChangedCompleter.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_update_visited_history.dart b/example/integration_test/in_app_webview/on_update_visited_history.dart new file mode 100644 index 00000000..d2d09b39 --- /dev/null +++ b/example/integration_test/in_app_webview/on_update_visited_history.dart @@ -0,0 +1,73 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onUpdateVisitedHistory() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('onUpdateVisitedHistory', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer firstPushCompleter = Completer(); + final Completer secondPushCompleter = Completer(); + final Completer pageLoaded = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: url), + initialSettings: InAppWebViewSettings(clearCache: true), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onUpdateVisitedHistory: (controller, url, androidIsReload) async { + if (url!.toString().endsWith("second-push")) { + secondPushCompleter.complete(); + } else if (url.toString().endsWith("first-push")) { + firstPushCompleter.complete(); + } + }, + ), + ), + ); + + final InAppWebViewController controller = await controllerCompleter.future; + await pageLoaded.future; + + await controller.evaluateJavascript(source: """ +var state = {} +var title = '' +var url = 'first-push'; +history.pushState(state, title, url); + +setTimeout(function() { + var url = 'second-push'; + history.pushState(state, title, url); +}, 500); +"""); + + await firstPushCompleter.future; + expect((await controller.getUrl())?.toString(), + '${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}/first-push'); + + await secondPushCompleter.future; + expect((await controller.getUrl())?.toString(), + '${!kIsWeb ? TEST_CROSS_PLATFORM_URL_1 : TEST_WEB_PLATFORM_BASE_URL}/second-push'); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_window_blur.dart b/example/integration_test/in_app_webview/on_window_blur.dart new file mode 100644 index 00000000..f8f145ed --- /dev/null +++ b/example/integration_test/in_app_webview/on_window_blur.dart @@ -0,0 +1,40 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onWindowBlur() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('onWindowBlur', (WidgetTester tester) async { + final Completer onWindowBlurCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: url), + onLoadStop: (controller, url) async { + await controller.evaluateJavascript( + source: 'window.dispatchEvent(new Event("blur"));'); + }, + onWindowBlur: (controller) { + onWindowBlurCompleter.complete(); + }, + ), + ), + ); + await expectLater(onWindowBlurCompleter.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_window_focus.dart b/example/integration_test/in_app_webview/on_window_focus.dart new file mode 100644 index 00000000..f0e1bb1d --- /dev/null +++ b/example/integration_test/in_app_webview/on_window_focus.dart @@ -0,0 +1,40 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onWindowFocus() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('onWindowFocus', (WidgetTester tester) async { + final Completer onWindowFocusCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: url), + onLoadStop: (controller, url) async { + await controller.evaluateJavascript( + source: 'window.dispatchEvent(new Event("focus"));'); + }, + onWindowFocus: (controller) { + onWindowFocusCompleter.complete(); + }, + ), + ), + ); + await expectLater(onWindowFocusCompleter.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_zoom_scale_changed.dart b/example/integration_test/in_app_webview/on_zoom_scale_changed.dart new file mode 100644 index 00000000..df73fe66 --- /dev/null +++ b/example/integration_test/in_app_webview/on_zoom_scale_changed.dart @@ -0,0 +1,56 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void onZoomScaleChanged() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('onZoomScaleChanged', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer onZoomScaleChangedCompleter = Completer(); + + var listenForScaleChange = false; + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onZoomScaleChanged: (controller, oldScale, newScale) { + if (listenForScaleChange) { + onZoomScaleChangedCompleter.complete(); + } + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + listenForScaleChange = true; + + await controller.zoomBy(zoomFactor: 2); + + await expectLater(onZoomScaleChangedCompleter.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/should_intercept_request.dart b/example/integration_test/in_app_webview/should_intercept_request.dart new file mode 100644 index 00000000..9acaede8 --- /dev/null +++ b/example/integration_test/in_app_webview/should_intercept_request.dart @@ -0,0 +1,69 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void shouldInterceptRequest() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('shouldInterceptRequest', (WidgetTester tester) async { + List resourceList = [ + "https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css", + "https://code.jquery.com/jquery-3.3.1.min.js", + "https://via.placeholder.com/100x50" + ]; + List resourceLoaded = []; + + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer loadedResourceCompleter = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + + + + + placeholder 100x50 + + + """), + initialSettings: + InAppWebViewSettings(useShouldInterceptRequest: true), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + shouldInterceptRequest: (controller, request) async { + resourceLoaded.add(request.url.toString()); + if (resourceLoaded.length == resourceList.length) { + loadedResourceCompleter.complete(); + } + return null; + }, + ), + ), + ); + + await pageLoaded.future; + await loadedResourceCompleter.future; + expect(resourceLoaded, containsAll(resourceList)); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/ssl_request.dart b/example/integration_test/in_app_webview/ssl_request.dart new file mode 100644 index 00000000..122bbdeb --- /dev/null +++ b/example/integration_test/in_app_webview/ssl_request.dart @@ -0,0 +1,56 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../.env.dart'; + +void sslRequest() { + final shouldSkip = kIsWeb || ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('SSL request', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest( + url: Uri.parse( + "https://${environment["NODE_SERVER_IP"]}:4433/")), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onReceivedServerTrustAuthRequest: (controller, challenge) async { + return new ServerTrustAuthResponse( + action: ServerTrustAuthResponseAction.PROCEED); + }, + onReceivedClientCertRequest: (controller, challenge) async { + return new ClientCertResponse( + certificatePath: "test_assets/certificate.pfx", + certificatePassword: "", + keyStoreType: "PKCS12", + action: ClientCertResponseAction.PROCEED); + }, + ), + ), + ); + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final String h1Content = await controller.evaluateJavascript( + source: "document.body.querySelector('h1').textContent"); + expect(h1Content, "Authorized"); + }, skip: shouldSkip); +} \ No newline at end of file diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index 1484d972..7b423351 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -28,1338 +28,6 @@ void main() { group('InAppWebView', () { - - group('intercept fetch request', () { - testWidgets('send string data', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer> fetchPostCompleter = - Completer>(); - final Completer shouldInterceptFetchPostRequestCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - InAppWebViewFetchTest - - -

InAppWebViewFetchTest

- - - - """), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - useShouldInterceptFetchRequest: true, - )), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - - controller.addJavaScriptHandler( - handlerName: "fetchPost", - callback: (args) { - fetchPostCompleter - .complete(args[0] as Map); - }); - }, - shouldInterceptFetchRequest: (controller, fetchRequest) async { - assert(fetchRequest.body == "firstname=Foo&lastname=Bar"); - - fetchRequest.body = "firstname=Foo2&lastname=Bar2"; - shouldInterceptFetchPostRequestCompleter.complete(); - return fetchRequest; - }, - ), - ), - ); - - await shouldInterceptFetchPostRequestCompleter.future; - var fetchPostCompleterValue = await fetchPostCompleter.future; - - expect( - mapEquals(fetchPostCompleterValue, - {'firstname': 'Foo2', 'lastname': 'Bar2'}), - true); - }); - - testWidgets('send json data', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer> fetchPostCompleter = - Completer>(); - final Completer shouldInterceptFetchPostRequestCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - InAppWebViewFetchTest - - -

InAppWebViewFetchTest

- - - - """), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - useShouldInterceptFetchRequest: true, - )), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - - controller.addJavaScriptHandler( - handlerName: "fetchPost", - callback: (args) { - fetchPostCompleter - .complete(args[0] as Map); - }); - }, - shouldInterceptFetchRequest: (controller, fetchRequest) async { - String body = fetchRequest.body; - assert(body.contains('"firstname":"Foo"') && - body.contains('"lastname":"Bar"')); - - fetchRequest.body = '{"firstname": "Foo2", "lastname": "Bar2"}'; - shouldInterceptFetchPostRequestCompleter.complete(); - return fetchRequest; - }, - ), - ), - ); - - await shouldInterceptFetchPostRequestCompleter.future; - var fetchPostCompleterValue = await fetchPostCompleter.future; - - expect( - mapEquals(fetchPostCompleterValue, - {'firstname': 'Foo2', 'lastname': 'Bar2'}), - true); - }); - - testWidgets('send URLSearchParams data', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer> fetchPostCompleter = - Completer>(); - final Completer shouldInterceptFetchPostRequestCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - InAppWebViewFetchTest - - -

InAppWebViewFetchTest

- - - - """), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - useShouldInterceptFetchRequest: true, - )), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - - controller.addJavaScriptHandler( - handlerName: "fetchPost", - callback: (args) { - fetchPostCompleter - .complete(args[0] as Map); - }); - }, - shouldInterceptFetchRequest: (controller, fetchRequest) async { - assert(fetchRequest.body == "firstname=Foo&lastname=Bar"); - - fetchRequest.body = "firstname=Foo2&lastname=Bar2"; - shouldInterceptFetchPostRequestCompleter.complete(); - return fetchRequest; - }, - ), - ), - ); - - await shouldInterceptFetchPostRequestCompleter.future; - var fetchPostCompleterValue = await fetchPostCompleter.future; - - expect( - mapEquals(fetchPostCompleterValue, - {'firstname': 'Foo2', 'lastname': 'Bar2'}), - true); - }); - - testWidgets('send FormData', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer> fetchPostCompleter = - Completer>(); - final Completer shouldInterceptFetchPostRequestCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - InAppWebViewFetchTest - - -

InAppWebViewFetchTest

- - - - """), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - useShouldInterceptFetchRequest: true, - )), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - - controller.addJavaScriptHandler( - handlerName: "fetchPost", - callback: (args) { - fetchPostCompleter - .complete(args[0] as Map); - }); - }, - shouldInterceptFetchRequest: (controller, fetchRequest) async { - assert(fetchRequest.body != null); - - var body = fetchRequest.body.cast(); - var bodyString = String.fromCharCodes(body); - assert(bodyString.indexOf("WebKitFormBoundary") >= 0); - - fetchRequest.body = utf8.encode(bodyString - .replaceFirst("Foo", "Foo2") - .replaceFirst("Bar", "Bar2")); - shouldInterceptFetchPostRequestCompleter.complete(); - return fetchRequest; - }, - ), - ), - ); - - await shouldInterceptFetchPostRequestCompleter.future; - var fetchPostCompleterValue = await fetchPostCompleter.future; - - expect( - mapEquals(fetchPostCompleterValue, - {'firstname': 'Foo2', 'lastname': 'Bar2'}), - true); - }); - }); - - testWidgets('Content Blocker', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://flutter.dev/')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - initialOptions: InAppWebViewGroupOptions( - crossPlatform: - InAppWebViewOptions(clearCache: true, contentBlockers: [ - ContentBlocker( - trigger: - ContentBlockerTrigger(urlFilter: ".*", resourceType: [ - ContentBlockerTriggerResourceType.IMAGE, - ContentBlockerTriggerResourceType.STYLE_SHEET - ], ifTopUrl: [ - "https://flutter.dev/" - ]), - action: ContentBlockerAction( - type: ContentBlockerActionType.BLOCK)) - ])), - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - await expectLater(pageLoaded.future, completes); - }); - - testWidgets('Http Auth Credential Database', (WidgetTester tester) async { - HttpAuthCredentialDatabase httpAuthCredentialDatabase = - HttpAuthCredentialDatabase.instance(); - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - - httpAuthCredentialDatabase.setHttpAuthCredential( - protectionSpace: URLProtectionSpace( - host: environment["NODE_SERVER_IP"]!, - protocol: "http", - realm: "Node", - port: 8081), - credential: - URLCredential(username: "USERNAME", password: "PASSWORD")); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest( - url: - Uri.parse("http://${environment["NODE_SERVER_IP"]}:8081/")), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - )), - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onReceivedHttpAuthRequest: (controller, challenge) async { - return new HttpAuthResponse( - action: - HttpAuthResponseAction.USE_SAVED_HTTP_AUTH_CREDENTIALS); - }, - ), - ), - ); - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final String h1Content = await controller.evaluateJavascript( - source: "document.body.querySelector('h1').textContent"); - expect(h1Content, "Authorized"); - - var credentials = await httpAuthCredentialDatabase.getHttpAuthCredentials( - protectionSpace: URLProtectionSpace( - host: environment["NODE_SERVER_IP"]!, - protocol: "http", - realm: "Node", - port: 8081)); - expect(credentials.length, 1); - - await httpAuthCredentialDatabase.clearAllAuthCredentials(); - credentials = await httpAuthCredentialDatabase.getHttpAuthCredentials( - protectionSpace: URLProtectionSpace( - host: environment["NODE_SERVER_IP"]!, - protocol: "http", - realm: "Node", - port: 8081)); - expect(credentials, isEmpty); - }); - - testWidgets('onReceivedHttpAuthRequest', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest( - url: - Uri.parse("http://${environment["NODE_SERVER_IP"]}:8081/")), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - )), - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onReceivedHttpAuthRequest: (controller, challenge) async { - return new HttpAuthResponse( - username: "USERNAME", - password: "PASSWORD", - action: HttpAuthResponseAction.PROCEED, - permanentPersistence: true); - }, - ), - ), - ); - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final String h1Content = await controller.evaluateJavascript( - source: "document.body.querySelector('h1').textContent"); - expect(h1Content, "Authorized"); - }); - - testWidgets('onConsoleMessage', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer onConsoleMessageCompleter = - Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialFile: - "test_assets/in_app_webview_on_console_message_test.html", - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onConsoleMessage: (controller, consoleMessage) { - onConsoleMessageCompleter.complete(consoleMessage); - }, - ), - ), - ); - - final ConsoleMessage consoleMessage = - await onConsoleMessageCompleter.future; - expect(consoleMessage.message, 'message'); - expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG); - }); - - - - testWidgets('onFindResultReceived', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer numberOfMatchesCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialFile: "test_assets/in_app_webview_initial_file_test.html", - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - )), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - controller.findAllAsync(find: "InAppWebViewInitialFileTest"); - }, - onFindResultReceived: (controller, int activeMatchOrdinal, - int numberOfMatches, bool isDoneCounting) async { - if (isDoneCounting && !numberOfMatchesCompleter.isCompleted) { - numberOfMatchesCompleter.complete(numberOfMatches); - } - }, - ), - ), - ); - - final int numberOfMatches = await numberOfMatchesCompleter.future; - expect(numberOfMatches, 2); - }); - - testWidgets('onDownloadStartRequest', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer onDownloadStartCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - InAppWebViewOnDownloadStartTest - - -

InAppWebViewOnDownloadStartTest

- download file - - - - """), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, useOnDownloadStart: true)), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onDownloadStartRequest: (controller, request) { - onDownloadStartCompleter.complete(request.url.toString()); - }, - ), - ), - ); - - final String url = await onDownloadStartCompleter.future; - expect(url, - "http://${environment["NODE_SERVER_IP"]}:8082/test-download-file"); - }); - - testWidgets('javascript dialogs', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer alertCompleter = - Completer(); - final Completer confirmCompleter = Completer(); - final Completer promptCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialFile: "test_assets/in_app_webview_on_js_dialog_test.html", - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - )), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - - controller.addJavaScriptHandler( - handlerName: 'confirm', - callback: (args) { - confirmCompleter.complete(args[0] as bool); - }); - - controller.addJavaScriptHandler( - handlerName: 'prompt', - callback: (args) { - promptCompleter.complete(args[0] as String); - }); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onJsAlert: (controller, jsAlertRequest) async { - JsAlertResponseAction action = JsAlertResponseAction.CONFIRM; - alertCompleter.complete(jsAlertRequest); - return JsAlertResponse(handledByClient: true, action: action); - }, - onJsConfirm: (controller, jsConfirmRequest) async { - JsConfirmResponseAction action = JsConfirmResponseAction.CONFIRM; - return JsConfirmResponse(handledByClient: true, action: action); - }, - onJsPrompt: (controller, jsPromptRequest) async { - JsPromptResponseAction action = JsPromptResponseAction.CONFIRM; - return JsPromptResponse( - handledByClient: true, action: action, value: 'new value'); - }, - ), - ), - ); - - await pageLoaded.future; - - final JsAlertRequest jsAlertRequest = await alertCompleter.future; - expect(jsAlertRequest.message, 'alert message'); - - final bool onJsConfirmValue = await confirmCompleter.future; - expect(onJsConfirmValue, true); - - final String onJsPromptValue = await promptCompleter.future; - expect(onJsPromptValue, 'new value'); - }); - - testWidgets('onLoadHttpError', (WidgetTester tester) async { - final Completer errorUrlCompleter = Completer(); - final Completer statusCodeCompleter = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://google.com/404')), - onLoadHttpError: (controller, url, statusCode, description) async { - errorUrlCompleter.complete(url.toString()); - statusCodeCompleter.complete(statusCode); - }, - ), - ), - ); - - final String url = await errorUrlCompleter.future; - final int code = await statusCodeCompleter.future; - - expect(url, 'https://google.com/404'); - expect(code, 404); - }); - - testWidgets('onLoadResourceCustomScheme', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer imageLoaded = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialFile: - "test_assets/in_app_webview_on_load_resource_custom_scheme_test.html", - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - resourceCustomSchemes: ["my-special-custom-scheme"])), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - - controller.addJavaScriptHandler( - handlerName: "imageLoaded", - callback: (args) { - imageLoaded.complete(); - }); - }, - onLoadResourceCustomScheme: (controller, url) async { - if (url.scheme == "my-special-custom-scheme") { - var bytes = await rootBundle.load("test_assets/" + - url - .toString() - .replaceFirst("my-special-custom-scheme://", "", 0)); - var response = CustomSchemeResponse( - data: bytes.buffer.asUint8List(), - contentType: "image/svg+xml", - contentEncoding: "utf-8"); - return response; - } - return null; - }, - ), - ), - ); - - await expectLater(imageLoaded.future, completes); - }); - - testWidgets('onLoadResource', (WidgetTester tester) async { - List resourceList = [ - "https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css", - "https://code.jquery.com/jquery-3.3.1.min.js", - "https://via.placeholder.com/100x50" - ]; - List resourceLoaded = []; - - final Completer loadedResourceCompleter = Completer(); - final Completer pageLoaded = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialFile: - "test_assets/in_app_webview_on_load_resource_test.html", - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, useOnLoadResource: true)), - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onLoadResource: (controller, response) async { - resourceLoaded.add(response.url!.toString()); - if (resourceLoaded.length == resourceList.length) { - loadedResourceCompleter.complete(); - } - }), - ), - ); - - await pageLoaded.future; - await loadedResourceCompleter.future; - - expect(resourceLoaded, unorderedEquals(resourceList)); - }); - - testWidgets('onUpdateVisitedHistory', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer firstPushCompleter = Completer(); - final Completer secondPushCompleter = Completer(); - final Completer pageLoaded = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse("https://flutter.dev/")), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions(clearCache: true)), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onUpdateVisitedHistory: (controller, url, androidIsReload) async { - if (url!.toString().endsWith("second-push")) { - secondPushCompleter.complete(); - } else if (url.toString().endsWith("first-push")) { - firstPushCompleter.complete(); - } - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.evaluateJavascript(source: """ -var state = {} -var title = '' -var url = 'first-push'; -history.pushState(state, title, url); - -setTimeout(function() { - var url = 'second-push'; - history.pushState(state, title, url); -}, 500); -"""); - - await firstPushCompleter.future; - expect((await controller.getUrl())?.toString(), - 'https://flutter.dev/first-push'); - - await secondPushCompleter.future; - expect((await controller.getUrl())?.toString(), - 'https://flutter.dev/second-push'); - }); - - testWidgets('onProgressChanged', (WidgetTester tester) async { - final Completer onProgressChangedCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - clearCache: true, - )), - onProgressChanged: (controller, progress) { - if (progress == 100) { - onProgressChangedCompleter.complete(); - } - }, - ), - ), - ); - await expectLater(onProgressChangedCompleter.future, completes); - }); - - testWidgets('androidOnSafeBrowsingHit', (WidgetTester tester) async { - final Completer pageLoaded = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest( - url: Uri.parse('chrome://safe-browsing/match?type=malware')), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions( - // if I set javaScriptEnabled to true, it will crash! - javaScriptEnabled: false, - clearCache: true, - ), - android: AndroidInAppWebViewOptions( - safeBrowsingEnabled: true, - ), - ), - onWebViewCreated: (controller) { - controller.android.startSafeBrowsing(); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(url!.toString()); - }, - androidOnSafeBrowsingHit: (controller, url, threatType) async { - return SafeBrowsingResponse( - report: true, action: SafeBrowsingResponseAction.PROCEED); - }, - ), - ), - ); - - final String url = await pageLoaded.future; - expect(url, "chrome://safe-browsing/match?type=malware"); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('onScrollChanged', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer onScrollChangedCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onScrollChanged: (controller, x, y) { - if (x == 0 && y == 500) { - onScrollChangedCompleter.complete(); - } - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - controller.scrollTo(x: 0, y: 500); - await tester.pumpAndSettle(Duration(seconds: 1)); - - await expectLater(onScrollChangedCompleter.future, completes); - }); - - testWidgets('SSL request', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest( - url: Uri.parse( - "https://${environment["NODE_SERVER_IP"]}:4433/")), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onReceivedServerTrustAuthRequest: (controller, challenge) async { - return new ServerTrustAuthResponse( - action: ServerTrustAuthResponseAction.PROCEED); - }, - onReceivedClientCertRequest: (controller, challenge) async { - return new ClientCertResponse( - certificatePath: "test_assets/certificate.pfx", - certificatePassword: "", - androidKeyStoreType: "PKCS12", - action: ClientCertResponseAction.PROCEED); - }, - ), - ), - ); - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final String h1Content = await controller.evaluateJavascript( - source: "document.body.querySelector('h1').textContent"); - expect(h1Content, "Authorized"); - }); - - testWidgets('onPrint', (WidgetTester tester) async { - final Completer onPrintCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onLoadStop: (controller, url) async { - await controller.evaluateJavascript(source: "window.print();"); - }, - onPrint: (controller, url) { - onPrintCompleter.complete(url?.toString()); - }, - ), - ), - ); - final String url = await onPrintCompleter.future; - expect(url, 'https://github.com/flutter'); - }, skip: true); - - testWidgets('onWindowFocus', (WidgetTester tester) async { - final Completer onWindowFocusCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onLoadStop: (controller, url) async { - await controller.evaluateJavascript( - source: 'window.dispatchEvent(new Event("focus"));'); - }, - onWindowFocus: (controller) { - onWindowFocusCompleter.complete(); - }, - ), - ), - ); - await expectLater(onWindowFocusCompleter.future, completes); - }); - - testWidgets('onWindowBlur', (WidgetTester tester) async { - final Completer onWindowBlurCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onLoadStop: (controller, url) async { - await controller.evaluateJavascript( - source: 'window.dispatchEvent(new Event("blur"));'); - }, - onWindowBlur: (controller) { - onWindowBlurCompleter.complete(); - }, - ), - ), - ); - await expectLater(onWindowBlurCompleter.future, completes); - }); - - testWidgets('onPageCommitVisible', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer onPageCommitVisibleCompleter = - Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onPageCommitVisible: (controller, url) { - onPageCommitVisibleCompleter.complete(url?.toString()); - }, - ), - ), - ); - - final String? url = await onPageCommitVisibleCompleter.future; - expect(url, 'https://github.com/flutter'); - }); - - testWidgets('onTitleChanged', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer onTitleChangedCompleter = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onTitleChanged: (controller, title) { - if (title == "title test") { - onTitleChangedCompleter.complete(); - } - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await controller.evaluateJavascript( - source: "document.title = 'title test';"); - await expectLater(onTitleChangedCompleter.future, completes); - }); - - testWidgets('onZoomScaleChanged', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer onZoomScaleChangedCompleter = Completer(); - - var listenForScaleChange = false; - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onZoomScaleChanged: (controller, oldScale, newScale) { - if (listenForScaleChange) { - onZoomScaleChangedCompleter.complete(); - } - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - listenForScaleChange = true; - - await controller.zoomBy(zoomFactor: 2); - - await expectLater(onZoomScaleChangedCompleter.future, completes); - }); - - testWidgets('androidOnPermissionRequest', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer> onPermissionRequestCompleter = - Completer>(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://permission.site/')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - androidOnPermissionRequest: (controller, origin, resources) async { - onPermissionRequestCompleter.complete(resources); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await controller.evaluateJavascript( - source: "document.querySelector('#camera').click();"); - final List resources = await onPermissionRequestCompleter.future; - - expect(listEquals(resources, ['android.webkit.resource.VIDEO_CAPTURE']), - true); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('androidShouldInterceptRequest', (WidgetTester tester) async { - List resourceList = [ - "https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css", - "https://code.jquery.com/jquery-3.3.1.min.js", - "https://via.placeholder.com/100x50" - ]; - List resourceLoaded = []; - - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer loadedResourceCompleter = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - - - - - placeholder 100x50 - - - """), - initialOptions: InAppWebViewGroupOptions( - android: AndroidInAppWebViewOptions( - useShouldInterceptRequest: true)), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - androidShouldInterceptRequest: (controller, request) async { - resourceLoaded.add(request.url.toString()); - if (resourceLoaded.length == resourceList.length) { - loadedResourceCompleter.complete(); - } - return null; - }, - ), - ), - ); - - await pageLoaded.future; - await loadedResourceCompleter.future; - expect(resourceLoaded, containsAll(resourceList)); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('androidOnReceivedIcon', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer onReceivedIconCompleter = - Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - androidOnReceivedIcon: (controller, icon) { - onReceivedIconCompleter.complete(icon); - }, - ), - ), - ); - - await pageLoaded.future; - final Uint8List icon = await onReceivedIconCompleter.future; - expect(icon, isNotNull); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('androidOnReceivedTouchIconUrl', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer onReceivedTouchIconUrlCompleter = - Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - - - - - """), - initialOptions: InAppWebViewGroupOptions( - android: AndroidInAppWebViewOptions( - useShouldInterceptRequest: true)), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - androidOnReceivedTouchIconUrl: (controller, url, precomposed) { - onReceivedTouchIconUrlCompleter.complete(url.toString()); - }, - ), - ), - ); - - final String url = await onReceivedTouchIconUrlCompleter.future; - - expect(url, "https://placehold.it/72x72"); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('androidOnJsBeforeUnload', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer onJsBeforeUnloadCompleter = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) async { - await controller.evaluateJavascript(source: """ - window.addEventListener('beforeunload', function (e) { - e.preventDefault(); - e.returnValue = ''; - }); - """); - if (!pageLoaded.isCompleted) { - pageLoaded.complete(); - } - }, - androidOnJsBeforeUnload: (controller, jsBeforeUnloadRequest) async { - onJsBeforeUnloadCompleter - .complete(jsBeforeUnloadRequest.url.toString()); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await controller.evaluateJavascript( - source: "window.location.href = 'https://github.com/flutter';"); - final String url = await onJsBeforeUnloadCompleter.future; - expect(url, 'https://github.com/flutter'); - }, skip: true /*defaultTargetPlatform != TargetPlatform.android*/); - group("iosOnNavigationResponse", () { testWidgets('allow navigation', (WidgetTester tester) async { final Completer controllerCompleter = diff --git a/example/web/page.html b/example/web/page.html index 33d8aecb..0a0ee06d 100644 --- a/example/web/page.html +++ b/example/web/page.html @@ -27,7 +27,7 @@