diff --git a/example/integration_test/chrome_safari_browser/custom_action_button.dart b/example/integration_test/chrome_safari_browser/custom_action_button.dart new file mode 100644 index 00000000..1d65babd --- /dev/null +++ b/example/integration_test/chrome_safari_browser/custom_action_button.dart @@ -0,0 +1,42 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void customActionButton() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + test('add custom action button', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + var actionButtonIcon = + await rootBundle.load('test_assets/images/flutter-logo.png'); + chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton( + id: 1, + description: 'Action Button description', + icon: actionButtonIcon.buffer.asUint8List(), + action: (url, title) { + print('Action Button 1 clicked!'); + })); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: TEST_URL_1); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1); + }, throwsA(isInstanceOf())); + + await expectLater( + chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/chrome_safari_browser/custom_menu_item.dart b/example/integration_test/chrome_safari_browser/custom_menu_item.dart new file mode 100644 index 00000000..85238057 --- /dev/null +++ b/example/integration_test/chrome_safari_browser/custom_menu_item.dart @@ -0,0 +1,39 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void customMenuItem() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('add custom menu item', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + chromeSafariBrowser.addMenuItem(ChromeSafariBrowserMenuItem( + id: 2, + label: 'Custom item menu 1', + action: (url, title) { + print('Custom item menu 1 clicked!'); + })); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: TEST_URL_1); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/chrome_safari_browser/custom_tabs.dart b/example/integration_test/chrome_safari_browser/custom_tabs.dart new file mode 100644 index 00000000..feb333f1 --- /dev/null +++ b/example/integration_test/chrome_safari_browser/custom_tabs.dart @@ -0,0 +1,34 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void customTabs() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + group('Custom Tabs', () async { + test('single instance', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: TEST_URL_1, + settings: ChromeSafariBrowserSettings(isSingleInstance: true)); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/chrome_safari_browser/main.dart b/example/integration_test/chrome_safari_browser/main.dart new file mode 100644 index 00000000..6e31a08c --- /dev/null +++ b/example/integration_test/chrome_safari_browser/main.dart @@ -0,0 +1,17 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'custom_action_button.dart'; +import 'custom_menu_item.dart'; +import 'custom_tabs.dart'; +import 'open_and_close.dart'; +import 'trusted_web_activity.dart'; + +void main() { + group('ChromeSafariBrowser', () { + openAndClose(); + customMenuItem(); + customActionButton(); + customTabs(); + trustedWebActivity(); + }); +} diff --git a/example/integration_test/chrome_safari_browser/open_and_close.dart b/example/integration_test/chrome_safari_browser/open_and_close.dart new file mode 100644 index 00000000..1b5a3040 --- /dev/null +++ b/example/integration_test/chrome_safari_browser/open_and_close.dart @@ -0,0 +1,33 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void openAndClose() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('open and close', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: TEST_URL_1); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/chrome_safari_browser/trusted_web_activity.dart b/example/integration_test/chrome_safari_browser/trusted_web_activity.dart new file mode 100644 index 00000000..60eedc5d --- /dev/null +++ b/example/integration_test/chrome_safari_browser/trusted_web_activity.dart @@ -0,0 +1,54 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void trustedWebActivity() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + group('Trusted Web Activity', () async { + test('basic', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: TEST_URL_1, + settings: ChromeSafariBrowserSettings(isTrustedWebActivity: true)); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }); + + test('single instance', () async { + var chromeSafariBrowser = new MyChromeSafariBrowser(); + expect(chromeSafariBrowser.isOpened(), false); + + await chromeSafariBrowser.open( + url: TEST_URL_1, + settings: ChromeSafariBrowserSettings( + isTrustedWebActivity: true, isSingleInstance: true)); + await chromeSafariBrowser.browserCreated.future; + expect(chromeSafariBrowser.isOpened(), true); + expect(() async { + await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1); + }, throwsA(isInstanceOf())); + + await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); + await chromeSafariBrowser.close(); + await chromeSafariBrowser.browserClosed.future; + expect(chromeSafariBrowser.isOpened(), false); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/constants.dart b/example/integration_test/constants.dart index 8bcf7e4a..2c10848f 100644 --- a/example/integration_test/constants.dart +++ b/example/integration_test/constants.dart @@ -5,9 +5,13 @@ 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_URL_EXAMPLE = Uri.parse('https://www.example.com/'); 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_WEB_PLATFORM_URL_2 = Uri.parse(TEST_WEB_PLATFORM_BASE_URL.toString() + 'page-2.html'); +final TEST_WEB_PLATFORM_URL_3 = Uri.parse(TEST_WEB_PLATFORM_BASE_URL.toString() + 'heavy-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/'); +final TEST_SERVICE_WORKER_URL = Uri.parse('https://mdn.github.io/sw-test/'); diff --git a/example/integration_test/cookie_manager/main.dart b/example/integration_test/cookie_manager/main.dart new file mode 100644 index 00000000..791fc1d6 --- /dev/null +++ b/example/integration_test/cookie_manager/main.dart @@ -0,0 +1,9 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'set_get_delete.dart'; + +void main() { + group('Cookie Manager', () { + setGetDelete(); + }); +} diff --git a/example/integration_test/cookie_manager/set_get_delete.dart b/example/integration_test/cookie_manager/set_get_delete.dart new file mode 100644 index 00000000..e766e7ee --- /dev/null +++ b/example/integration_test/cookie_manager/set_get_delete.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 '../constants.dart'; + +void setGetDelete() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('set, get, delete', (WidgetTester tester) async { + CookieManager cookieManager = CookieManager.instance(); + 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); + }, + initialOptions: InAppWebViewGroupOptions( + crossPlatform: InAppWebViewOptions( + clearCache: true, + )), + onLoadStop: (controller, url) { + pageLoaded.complete(url!.toString()); + }, + ), + ), + ); + + final url = Uri.parse(await pageLoaded.future); + + await cookieManager.setCookie( + url: url, name: "myCookie", value: "myValue"); + List cookies = await cookieManager.getCookies(url: url); + expect(cookies, isNotEmpty); + + Cookie? cookie = + await cookieManager.getCookie(url: url, name: "myCookie"); + expect(cookie?.value.toString(), "myValue"); + + await cookieManager.deleteCookie(url: url, name: "myCookie"); + cookie = await cookieManager.getCookie(url: url, name: "myCookie"); + expect(cookie, isNull); + + await cookieManager.deleteCookies(url: url); + cookies = await cookieManager.getCookies(url: url); + expect(cookies, isEmpty); + }, skip: shouldSkip); +} diff --git a/example/integration_test/headless_in_app_webview/custom_size.dart b/example/integration_test/headless_in_app_webview/custom_size.dart new file mode 100644 index 00000000..ad0950eb --- /dev/null +++ b/example/integration_test/headless_in_app_webview/custom_size.dart @@ -0,0 +1,46 @@ +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 customSize() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('set and get custom size', () async { + final Completer controllerCompleter = Completer(); + + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: + URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + initialSize: Size(600, 800), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + ); + + await headlessWebView.run(); + expect(headlessWebView.isRunning(), true); + + final Size? size = await headlessWebView.getSize(); + expect(size, isNotNull); + expect(size, Size(600, 800)); + + await headlessWebView.setSize(Size(1080, 1920)); + final Size? newSize = await headlessWebView.getSize(); + expect(newSize, isNotNull); + expect(newSize, Size(1080, 1920)); + + await headlessWebView.dispose(); + + expect(headlessWebView.isRunning(), false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/headless_in_app_webview/main.dart b/example/integration_test/headless_in_app_webview/main.dart new file mode 100644 index 00000000..8c9fa2cd --- /dev/null +++ b/example/integration_test/headless_in_app_webview/main.dart @@ -0,0 +1,15 @@ +import 'package:flutter_test/flutter_test.dart'; + +import '../in_app_webview/take_screenshot.dart'; +import 'custom_size.dart'; +import 'run_and_dispose.dart'; +import 'set_get_settings.dart'; + +void main() { + group('HeadlessInAppWebView', () { + runAndDispose(); + takeScreenshot(); + customSize(); + setGetSettings(); + }); +} diff --git a/example/integration_test/headless_in_app_webview/run_and_dispose.dart b/example/integration_test/headless_in_app_webview/run_and_dispose.dart new file mode 100644 index 00000000..c7fc01d2 --- /dev/null +++ b/example/integration_test/headless_in_app_webview/run_and_dispose.dart @@ -0,0 +1,46 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void runAndDispose() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('run and dispose', () async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: + URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + ); + headlessWebView.onLoadStop = (controller, url) async { + pageLoaded.complete(); + }; + + await headlessWebView.run(); + expect(headlessWebView.isRunning(), true); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final String? url = (await controller.getUrl())?.toString(); + expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); + + await headlessWebView.dispose(); + + expect(headlessWebView.isRunning(), false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/headless_in_app_webview/set_get_settings.dart b/example/integration_test/headless_in_app_webview/set_get_settings.dart new file mode 100644 index 00000000..3182f944 --- /dev/null +++ b/example/integration_test/headless_in_app_webview/set_get_settings.dart @@ -0,0 +1,48 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void setGetSettings() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('set/get settings', () async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: + URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + initialSettings: InAppWebViewSettings(javaScriptEnabled: false), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) async { + pageLoaded.complete(); + }, + ); + + await headlessWebView.run(); + final InAppWebViewController controller = await controllerCompleter.future; + await pageLoaded.future; + + var settings = await controller.getSettings(); + expect(settings, isNotNull); + expect(settings!.javaScriptEnabled, false); + + await controller.setSettings( + settings: InAppWebViewSettings(javaScriptEnabled: true)); + + settings = await controller.getSettings(); + expect(settings, isNotNull); + expect(settings!.javaScriptEnabled, true); + }, skip: shouldSkip); +} diff --git a/example/integration_test/headless_in_app_webview/take_screenshot.dart b/example/integration_test/headless_in_app_webview/take_screenshot.dart new file mode 100644 index 00000000..8c25cc41 --- /dev/null +++ b/example/integration_test/headless_in_app_webview/take_screenshot.dart @@ -0,0 +1,53 @@ +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 takeScreenshot() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('take screenshot', () async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: + URLRequest(url: TEST_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) async { + pageLoaded.complete(); + }); + + await headlessWebView.run(); + expect(headlessWebView.isRunning(), true); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final String? url = (await controller.getUrl())?.toString(); + expect(url, TEST_URL_1.toString()); + + final Size? size = await headlessWebView.getSize(); + expect(size, isNotNull); + + final Uint8List? screenshot = await controller.takeScreenshot(); + expect(screenshot, isNotNull); + + await headlessWebView.dispose(); + + expect(headlessWebView.isRunning(), false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_browser/main.dart b/example/integration_test/in_app_browser/main.dart new file mode 100644 index 00000000..7ed359fa --- /dev/null +++ b/example/integration_test/in_app_browser/main.dart @@ -0,0 +1,15 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'open_data_and_close.dart'; +import 'open_file_and_close.dart'; +import 'open_url_and_close.dart'; +import 'set_get_settings.dart'; + +void main() { + group('InAppBrowser', () { + openUrlAndClose(); + openFileAndClose(); + openDataAndClose(); + setGetSettings(); + }); +} diff --git a/example/integration_test/in_app_browser/open_data_and_close.dart b/example/integration_test/in_app_browser/open_data_and_close.dart new file mode 100644 index 00000000..53d1968b --- /dev/null +++ b/example/integration_test/in_app_browser/open_data_and_close.dart @@ -0,0 +1,63 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void openDataAndClose() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('open data and close', () async { + var inAppBrowser = new MyInAppBrowser(); + expect(inAppBrowser.isOpened(), false); + expect(() async { + await inAppBrowser.show(); + }, throwsA(isInstanceOf())); + + await inAppBrowser.openData( + data: """ + + + + + + + + + + + placeholder 100x50 + + +""", + encoding: 'utf-8', + mimeType: 'text/html', + historyUrl: TEST_CROSS_PLATFORM_URL_1, + baseUrl: TEST_CROSS_PLATFORM_URL_1); + await inAppBrowser.browserCreated.future; + expect(inAppBrowser.isOpened(), true); + expect(() async { + await inAppBrowser.openUrlRequest( + urlRequest: + URLRequest(url: TEST_URL_1)); + }, throwsA(isInstanceOf())); + + await inAppBrowser.firstPageLoaded.future; + var controller = inAppBrowser.webViewController; + + final String? url = (await controller.getUrl())?.toString(); + expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); + + await inAppBrowser.close(); + expect(inAppBrowser.isOpened(), false); + expect(() async => await inAppBrowser.webViewController.getUrl(), + throwsA(isInstanceOf())); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_browser/open_file_and_close.dart b/example/integration_test/in_app_browser/open_file_and_close.dart new file mode 100644 index 00000000..d455caa7 --- /dev/null +++ b/example/integration_test/in_app_browser/open_file_and_close.dart @@ -0,0 +1,45 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void openFileAndClose() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('open file and close', () async { + var inAppBrowser = new MyInAppBrowser(); + expect(inAppBrowser.isOpened(), false); + expect(() async { + await inAppBrowser.show(); + }, throwsA(isInstanceOf())); + + await inAppBrowser.openFile( + assetFilePath: "test_assets/in_app_webview_initial_file_test.html"); + await inAppBrowser.browserCreated.future; + expect(inAppBrowser.isOpened(), true); + expect(() async { + await inAppBrowser.openUrlRequest( + urlRequest: + URLRequest(url: TEST_URL_1)); + }, throwsA(isInstanceOf())); + + await inAppBrowser.firstPageLoaded.future; + var controller = inAppBrowser.webViewController; + + final String? url = (await controller.getUrl())?.toString(); + expect(url, endsWith("in_app_webview_initial_file_test.html")); + + await inAppBrowser.close(); + expect(inAppBrowser.isOpened(), false); + expect(() async => await inAppBrowser.webViewController.getUrl(), + throwsA(isInstanceOf())); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_browser/open_url_and_close.dart b/example/integration_test/in_app_browser/open_url_and_close.dart new file mode 100644 index 00000000..add857f6 --- /dev/null +++ b/example/integration_test/in_app_browser/open_url_and_close.dart @@ -0,0 +1,44 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void openUrlAndClose() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('open url and close', () async { + var inAppBrowser = new MyInAppBrowser(); + expect(inAppBrowser.isOpened(), false); + expect(() async { + await inAppBrowser.show(); + }, throwsA(isInstanceOf())); + + await inAppBrowser.openUrlRequest( + urlRequest: URLRequest(url: TEST_URL_1)); + await inAppBrowser.browserCreated.future; + expect(inAppBrowser.isOpened(), true); + expect(() async { + await inAppBrowser.openUrlRequest( + urlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1)); + }, throwsA(isInstanceOf())); + + await inAppBrowser.firstPageLoaded.future; + var controller = inAppBrowser.webViewController; + + final String? url = (await controller.getUrl())?.toString(); + expect(url, TEST_URL_1.toString()); + + await inAppBrowser.close(); + expect(inAppBrowser.isOpened(), false); + expect(() async => await inAppBrowser.webViewController.getUrl(), + throwsA(isInstanceOf())); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_browser/set_get_settings.dart b/example/integration_test/in_app_browser/set_get_settings.dart new file mode 100644 index 00000000..66741fac --- /dev/null +++ b/example/integration_test/in_app_browser/set_get_settings.dart @@ -0,0 +1,37 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; +import '../util.dart'; + +void setGetSettings() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('set/get settings', () async { + var inAppBrowser = new MyInAppBrowser(); + await inAppBrowser.openUrlRequest( + urlRequest: URLRequest(url: TEST_URL_1), + settings: InAppBrowserClassSettings( + browserSettings: InAppBrowserSettings(hideToolbarTop: true))); + await inAppBrowser.browserCreated.future; + await inAppBrowser.firstPageLoaded.future; + + InAppBrowserClassSettings? settings = await inAppBrowser.getSettings(); + expect(settings, isNotNull); + expect(settings!.browserSettings.hideToolbarTop, true); + + await inAppBrowser.setSettings( + settings: InAppBrowserClassSettings( + browserSettings: InAppBrowserSettings(hideToolbarTop: false))); + + settings = await inAppBrowser.getSettings(); + expect(settings, isNotNull); + expect(settings!.browserSettings.hideToolbarTop, false); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_localhost_server/load_asset_file.dart b/example/integration_test/in_app_localhost_server/load_asset_file.dart new file mode 100644 index 00000000..5a834847 --- /dev/null +++ b/example/integration_test/in_app_localhost_server/load_asset_file.dart @@ -0,0 +1,38 @@ +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 loadAssetFile(InAppLocalhostServer localhostServer) { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('load asset file', (WidgetTester tester) async { + expect(localhostServer.isRunning(), true); + + final Completer controllerCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest( + url: Uri.parse('http://localhost:8080/test_assets/index.html')), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + ), + ), + ); + final InAppWebViewController controller = + await controllerCompleter.future; + final String? currentUrl = (await controller.getUrl())?.toString(); + expect(currentUrl, 'http://localhost:8080/test_assets/index.html'); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_localhost_server/main.dart b/example/integration_test/in_app_localhost_server/main.dart new file mode 100644 index 00000000..1609b72e --- /dev/null +++ b/example/integration_test/in_app_localhost_server/main.dart @@ -0,0 +1,20 @@ +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'load_asset_file.dart'; + +void main() { + group('InAppLocalhostServer', () { + final InAppLocalhostServer localhostServer = InAppLocalhostServer(); + + setUpAll(() async { + await localhostServer.start(); + }); + + loadAssetFile(localhostServer); + + tearDownAll(() async { + await localhostServer.close(); + }); + }); +} diff --git a/example/integration_test/in_app_webview/apple_pay_api.dart b/example/integration_test/in_app_webview/apple_pay_api.dart new file mode 100644 index 00000000..eab58079 --- /dev/null +++ b/example/integration_test/in_app_webview/apple_pay_api.dart @@ -0,0 +1,57 @@ +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 applePayAPI() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('Apple Pay API enabled', (WidgetTester tester) async { + final Completer pageLoaded = Completer(); + final Completer alertMessageCompleter = Completer(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + + + Apple Pay API + + + + + + """), + initialSettings: InAppWebViewSettings( + applePayAPIEnabled: true, + ), + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + onJsAlert: (controller, jsAlertRequest) async { + alertMessageCompleter.complete(jsAlertRequest.message); + return null; + }, + ), + ), + ); + await pageLoaded.future; + final message = await alertMessageCompleter.future; + expect(message, 'true'); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/clear_cache.dart b/example/integration_test/in_app_webview/clear_cache.dart new file mode 100644 index 00000000..0f66a508 --- /dev/null +++ b/example/integration_test/in_app_webview/clear_cache.dart @@ -0,0 +1,44 @@ +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 clearCache() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('clearCache', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + await expectLater(controller.clearCache(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/clear_client_cert_preferences.dart b/example/integration_test/in_app_webview/clear_client_cert_preferences.dart new file mode 100644 index 00000000..ba730321 --- /dev/null +++ b/example/integration_test/in_app_webview/clear_client_cert_preferences.dart @@ -0,0 +1,17 @@ +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 clearClientCertPreferences() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + test('clearClientCertPreferences', () async { + await expectLater( + InAppWebViewController.clearClientCertPreferences(), + completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/clear_focus.dart b/example/integration_test/in_app_webview/clear_focus.dart new file mode 100644 index 00000000..28c5b2f0 --- /dev/null +++ b/example/integration_test/in_app_webview/clear_focus.dart @@ -0,0 +1,45 @@ +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 clearFocus() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('clearFocus', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await expectLater(controller.clearFocus(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/clear_ssl_preferences.dart b/example/integration_test/in_app_webview/clear_ssl_preferences.dart new file mode 100644 index 00000000..601a0acb --- /dev/null +++ b/example/integration_test/in_app_webview/clear_ssl_preferences.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 clearSslPreferences() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('clearSslPreferences', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + await expectLater(controller.clearSslPreferences(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/create_pdf.dart b/example/integration_test/in_app_webview/create_pdf.dart new file mode 100644 index 00000000..f90cf0b8 --- /dev/null +++ b/example/integration_test/in_app_webview/create_pdf.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 createPdf() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('createPdf', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + var pdfConfiguration = PDFConfiguration( + rect: InAppWebViewRect(width: 100, height: 100, x: 50, y: 50)); + var pdf = await controller.createPdf(pdfConfiguration: pdfConfiguration); + expect(pdf, isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_certificate.dart b/example/integration_test/in_app_webview/get_certificate.dart new file mode 100644 index 00000000..1b64e580 --- /dev/null +++ b/example/integration_test/in_app_webview/get_certificate.dart @@ -0,0 +1,51 @@ +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 getCertificate() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('getCertificate', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + var sslCertificate = await controller.getCertificate(); + expect(sslCertificate, isNotNull); + expect(sslCertificate!.x509Certificate, isNotNull); + expect(sslCertificate.issuedBy, isNotNull); + expect(sslCertificate.issuedTo, isNotNull); + expect(sslCertificate.validNotAfterDate, isNotNull); + expect(sslCertificate.validNotBeforeDate, isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_content_height.dart b/example/integration_test/in_app_webview/get_content_height.dart new file mode 100644 index 00000000..991ef373 --- /dev/null +++ b/example/integration_test/in_app_webview/get_content_height.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 getContentHeight() { + 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('getContentHeight', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final contentHeight = await controller.getContentHeight(); + expect(contentHeight, isNonZero); + expect(contentHeight, isPositive); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_current_web_view_package.dart b/example/integration_test/in_app_webview/get_current_web_view_package.dart new file mode 100644 index 00000000..d58532e4 --- /dev/null +++ b/example/integration_test/in_app_webview/get_current_web_view_package.dart @@ -0,0 +1,15 @@ +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 getCurrentWebViewPackage() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + test('getCurrentWebViewPackage', () async { + expect(await InAppWebViewController.getCurrentWebViewPackage(), isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_default_user_agent.dart b/example/integration_test/in_app_webview/get_default_user_agent.dart new file mode 100644 index 00000000..30d9256d --- /dev/null +++ b/example/integration_test/in_app_webview/get_default_user_agent.dart @@ -0,0 +1,17 @@ +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 getDefaultUserAgent() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('getDefaultUserAgent', () async { + expect(await InAppWebViewController.getDefaultUserAgent(), isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_favicons.dart b/example/integration_test/in_app_webview/get_favicons.dart new file mode 100644 index 00000000..df018340 --- /dev/null +++ b/example/integration_test/in_app_webview/get_favicons.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 getFavicons() { + 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('getFavicons', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final List? favicons = await controller.getFavicons(); + expect(favicons, isNotNull); + expect(favicons, isNotEmpty); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_html.dart b/example/integration_test/in_app_webview/get_html.dart new file mode 100644 index 00000000..192176cf --- /dev/null +++ b/example/integration_test/in_app_webview/get_html.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 getHtml() { + 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('getHtml', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final String? html = await controller.getHtml(); + expect(html, isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_meta_tags.dart b/example/integration_test/in_app_webview/get_meta_tags.dart new file mode 100644 index 00000000..a89fed38 --- /dev/null +++ b/example/integration_test/in_app_webview/get_meta_tags.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 getMetaTags() { + 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('getMetaTags', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + List metaTags = await controller.getMetaTags(); + expect(metaTags, isNotEmpty); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_meta_theme_color.dart b/example/integration_test/in_app_webview/get_meta_theme_color.dart new file mode 100644 index 00000000..e9105d33 --- /dev/null +++ b/example/integration_test/in_app_webview/get_meta_theme_color.dart @@ -0,0 +1,46 @@ +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 getMetaThemeColor() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('getMetaThemeColor', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + expect(await controller.getMetaThemeColor(), isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_original_url.dart b/example/integration_test/in_app_webview/get_original_url.dart new file mode 100644 index 00000000..35b1d19e --- /dev/null +++ b/example/integration_test/in_app_webview/get_original_url.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 getOriginalUrl() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; + + testWidgets('getOriginalUrl', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + var originUrl = (await controller.getOriginalUrl())?.toString(); + expect(originUrl, url.toString()); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/get_progress.dart b/example/integration_test/in_app_webview/get_progress.dart new file mode 100644 index 00000000..e0072bd8 --- /dev/null +++ b/example/integration_test/in_app_webview/get_progress.dart @@ -0,0 +1,46 @@ +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 getProgress() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('getProgress', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final int? progress = await controller.getProgress(); + expect(progress, 100); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/handles_url_scheme.dart b/example/integration_test/in_app_webview/handles_url_scheme.dart new file mode 100644 index 00000000..5cf0ada9 --- /dev/null +++ b/example/integration_test/in_app_webview/handles_url_scheme.dart @@ -0,0 +1,16 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void handlesURLScheme() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + test('handlesURLScheme', () async { + expect(await InAppWebViewController.handlesURLScheme("http"), true); + expect(await InAppWebViewController.handlesURLScheme("https"), true); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/initial_url_request.dart b/example/integration_test/in_app_webview/initial_url_request.dart index fd15aba7..ec0fbcb7 100644 --- a/example/integration_test/in_app_webview/initial_url_request.dart +++ b/example/integration_test/in_app_webview/initial_url_request.dart @@ -78,5 +78,5 @@ void initialUrlRequest() { final String? currentUrl = (await controller.getUrl())?.toString(); expect(currentUrl, TEST_URL_1.toString()); }, skip: shouldSkipTest2); - }); + }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_webview/initial_user_scripts.dart b/example/integration_test/in_app_webview/initial_user_scripts.dart deleted file mode 100644 index 2e9a349b..00000000 --- a/example/integration_test/in_app_webview/initial_user_scripts.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; - -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 initialUserScripts() { - final shouldSkip = kIsWeb || - ![ - TargetPlatform.android, - TargetPlatform.iOS, - TargetPlatform.macOS, - ].contains(defaultTargetPlatform); - - testWidgets('initialUserScripts', (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), - initialUserScripts: UnmodifiableListView([ - UserScript( - source: "var foo = 49;", - injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START), - UserScript( - source: "var foo2 = 19;", - injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START, - contentWorld: ContentWorld.PAGE), - UserScript( - source: "var bar = 2;", - injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END, - contentWorld: ContentWorld.DEFAULT_CLIENT), - UserScript( - source: "var bar2 = 12;", - injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END, - contentWorld: ContentWorld.world(name: "test")), - ]), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) async { - pageLoaded.complete(); - }, - ), - ), - ); - final InAppWebViewController controller = await controllerCompleter.future; - await pageLoaded.future; - - expect(await controller.evaluateJavascript(source: "foo;"), 49); - expect(await controller.evaluateJavascript(source: "foo2;"), 19); - expect( - await controller.evaluateJavascript( - source: "foo2;", contentWorld: ContentWorld.PAGE), - 19); - expect(await controller.evaluateJavascript(source: "bar;"), isNull); - expect(await controller.evaluateJavascript(source: "bar2;"), isNull); - expect( - await controller.evaluateJavascript( - source: "bar;", contentWorld: ContentWorld.DEFAULT_CLIENT), - 2); - expect( - await controller.evaluateJavascript( - source: "bar2;", contentWorld: ContentWorld.world(name: "test")), - 12); - }, skip: shouldSkip); -} diff --git a/example/integration_test/in_app_webview/inject_css.dart b/example/integration_test/in_app_webview/inject_css.dart new file mode 100644 index 00000000..e436de2e --- /dev/null +++ b/example/integration_test/in_app_webview/inject_css.dart @@ -0,0 +1,129 @@ +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 injectCSS() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_ABOUT_BLANK : TEST_WEB_PLATFORM_URL_1; + + group('inject CSS', () { + testWidgets('code', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await controller.injectCSSCode(source: """ + body { + background-color: rgb(0, 0, 255); + } + """); + + String? backgroundColor = await controller.evaluateJavascript(source: """ + var element = document.body; + var style = getComputedStyle(element); + style.backgroundColor; + """); + expect(backgroundColor, 'rgb(0, 0, 255)'); + }); + + testWidgets('file from url', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await controller.injectCSSFileFromUrl( + urlFile: Uri.parse( + 'https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css'), + cssLinkHtmlTagAttributes: CSSLinkHtmlTagAttributes(id: 'bootstrap')); + await Future.delayed(Duration(seconds: 2)); + expect( + await controller.evaluateJavascript( + source: "document.head.querySelector('#bootstrap') == null;"), + false); + }); + + testWidgets('file from asset', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await controller.injectCSSFileFromAsset( + assetFilePath: 'test_assets/css/blue-body.css'); + + String? backgroundColor = await controller.evaluateJavascript(source: """ + var element = document.body; + var style = getComputedStyle(element); + style.backgroundColor; + """); + expect(backgroundColor, 'rgb(0, 0, 255)'); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/inject_javascript_file.dart b/example/integration_test/in_app_webview/inject_javascript_file.dart new file mode 100644 index 00000000..8edf6974 --- /dev/null +++ b/example/integration_test/in_app_webview/inject_javascript_file.dart @@ -0,0 +1,114 @@ +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 injectJavascriptFile() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + var url = !kIsWeb ? TEST_URL_ABOUT_BLANK : TEST_WEB_PLATFORM_URL_1; + + group('inject javascript file', () { + testWidgets('from url', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer jQueryLoaded = Completer(); + final Completer jQueryLoadError = 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(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await controller.injectJavascriptFileFromUrl( + urlFile: + Uri.parse('https://www.notawebsite..com/jquery-3.3.1.min.js'), + scriptHtmlTagAttributes: ScriptHtmlTagAttributes( + id: 'jquery-error', + onError: () { + jQueryLoadError.complete(); + }, + )); + await jQueryLoadError.future; + expect( + await controller.evaluateJavascript( + source: "document.body.querySelector('#jquery-error') == null;"), + false); + expect( + await controller.evaluateJavascript(source: "window.jQuery == null;"), + true); + + await controller.injectJavascriptFileFromUrl( + urlFile: Uri.parse('https://code.jquery.com/jquery-3.3.1.min.js'), + scriptHtmlTagAttributes: ScriptHtmlTagAttributes( + id: 'jquery', + onLoad: () { + jQueryLoaded.complete(); + }, + )); + await jQueryLoaded.future; + expect( + await controller.evaluateJavascript( + source: "document.body.querySelector('#jquery') == null;"), + false); + expect( + await controller.evaluateJavascript(source: "window.jQuery == null;"), + false); + }); + + testWidgets('from asset', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await controller.injectJavascriptFileFromAsset( + assetFilePath: 'test_assets/js/jquery-3.3.1.min.js'); + expect( + await controller.evaluateJavascript(source: "window.jQuery == null;"), + false); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/on_zoom_scale_changed.dart b/example/integration_test/in_app_webview/is_loading.dart similarity index 66% rename from example/integration_test/in_app_webview/on_zoom_scale_changed.dart rename to example/integration_test/in_app_webview/is_loading.dart index df73fe66..b0630bf4 100644 --- a/example/integration_test/in_app_webview/on_zoom_scale_changed.dart +++ b/example/integration_test/in_app_webview/is_loading.dart @@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart'; import '../constants.dart'; -void onZoomScaleChanged() { +void isLoading() { final shouldSkip = kIsWeb || ![ TargetPlatform.android, @@ -15,12 +15,10 @@ void onZoomScaleChanged() { TargetPlatform.macOS, ].contains(defaultTargetPlatform); - testWidgets('onZoomScaleChanged', (WidgetTester tester) async { + testWidgets('isLoading', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); + final Completer pageStarted = Completer(); final Completer pageLoaded = Completer(); - final Completer onZoomScaleChangedCompleter = Completer(); - - var listenForScaleChange = false; await tester.pumpWidget( Directionality( @@ -28,29 +26,27 @@ void onZoomScaleChanged() { child: InAppWebView( key: GlobalKey(), initialUrlRequest: - URLRequest(url: TEST_URL_1), + URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + initialSettings: InAppWebViewSettings(clearCache: true), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, + onLoadStart: (controller, url) { + pageStarted.complete(); + }, onLoadStop: (controller, url) { pageLoaded.complete(); }, - onZoomScaleChanged: (controller, oldScale, newScale) { - if (listenForScaleChange) { - onZoomScaleChangedCompleter.complete(); - } - }, ), ), ); final InAppWebViewController controller = await controllerCompleter.future; + await pageStarted.future; + expect(await controller.isLoading(), true); + await pageLoaded.future; - listenForScaleChange = true; - - await controller.zoomBy(zoomFactor: 2); - - await expectLater(onZoomScaleChangedCompleter.future, completes); + expect(await controller.isLoading(), false); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_webview/is_secure_context.dart b/example/integration_test/in_app_webview/is_secure_context.dart new file mode 100644 index 00000000..b0b26b50 --- /dev/null +++ b/example/integration_test/in_app_webview/is_secure_context.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 isSecureContext() { + 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('isSecureContext', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = + StreamController.broadcast(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoads.add(url!.toString()); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoads.stream.first; + expect(await controller.isSecureContext(), true); + + if (!kIsWeb) { + await controller.loadUrl( + urlRequest: URLRequest(url: Uri.parse('http://example.com/'))); + await pageLoads.stream.first; + expect(await controller.isSecureContext(), false); + } + + pageLoads.close(); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/main.dart b/example/integration_test/in_app_webview/main.dart index 3cd61cd0..14b4735c 100644 --- a/example/integration_test/in_app_webview/main.dart +++ b/example/integration_test/in_app_webview/main.dart @@ -1,13 +1,33 @@ import 'package:flutter_test/flutter_test.dart'; +import 'apple_pay_api.dart'; import 'audio_playback_policy.dart'; +import 'clear_cache.dart'; +import 'clear_client_cert_preferences.dart'; +import 'clear_focus.dart'; +import 'clear_ssl_preferences.dart'; import 'content_blocker.dart'; +import 'create_pdf.dart'; +import 'get_certificate.dart'; +import 'get_content_height.dart'; +import 'get_current_web_view_package.dart'; +import 'get_default_user_agent.dart'; +import 'get_favicons.dart'; +import 'get_html.dart'; +import 'get_meta_tags.dart'; +import 'get_meta_theme_color.dart'; +import 'get_original_url.dart'; +import 'get_progress.dart'; import 'get_title.dart'; +import 'handles_url_scheme.dart'; import 'http_auth_credential_database.dart'; import 'initial_url_request.dart'; -import 'initial_user_scripts.dart'; +import 'inject_css.dart'; +import 'inject_javascript_file.dart'; import 'intercept_ajax_request.dart'; import 'intercept_fetch_request.dart'; +import 'is_loading.dart'; +import 'is_secure_context.dart'; import 'javascript_code_evaluation.dart'; import 'javascript_dialogs.dart'; import 'javascript_handler.dart'; @@ -30,23 +50,38 @@ 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 'safe_browsing.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 'page_down_up.dart'; +import 'pause_resume.dart'; +import 'programmatic_zoom_scale.dart'; +import 'pause_resume_timers.dart'; import 'post_requests.dart'; +import 'print_current_page.dart'; import 'programmatic_scroll.dart'; +import 'pull_to_refresh.dart'; import 'reload.dart'; +import 'request_focus_node_href.dart'; +import 'request_image_ref.dart'; import 'resize_webview.dart'; +import 'web_archive.dart'; import 'set_custom_useragent.dart'; import 'set_get_settings.dart'; +import 'set_web_contents_debugging_enabled.dart'; import 'should_intercept_request.dart'; import 'should_override_url_loading.dart'; import 'ssl_request.dart'; +import 'stop_loading.dart'; +import 't_rex_runner_game.dart'; +import 'take_screenshot.dart'; +import 'user_scripts.dart'; import 'video_playback_policy.dart'; +import 'web_history.dart'; +import 'web_message.dart'; import 'webview_windows.dart'; void main() { @@ -79,7 +114,7 @@ void main() { onLoadResource(); onUpdateVisitedHistory(); onProgressChanged(); - onSafeBrowsingHit(); + safeBrowsing(); onScrollChanged(); sslRequest(); onPrint(); @@ -87,17 +122,52 @@ void main() { onWindowBlur(); onPageCommitVisible(); onTitleChanged(); - onZoomScaleChanged(); + programmaticZoomScale(); onPermissionRequest(); shouldInterceptRequest(); onReceivedIcon(); onReceivedTouchIconUrl(); onJsBeforeUnload(); onNavigationResponse(); - initialUserScripts(); postRequests(); loadData(); loadFile(); reload(); + webHistory(); + getProgress(); + getHtml(); + getFavicons(); + isLoading(); + stopLoading(); + injectJavascriptFile(); + injectCSS(); + takeScreenshot(); + clearCache(); + tRexRunnerGame(); + pauseResumeTimers(); + printCurrentPage(); + getContentHeight(); + clearFocus(); + requestFocusNodeHref(); + requestImageRef(); + getMetaTags(); + getMetaThemeColor(); + getCertificate(); + userScripts(); + webArchive(); + isSecureContext(); + getDefaultUserAgent(); + pullToRefresh(); + webMessage(); + clearSslPreferences(); + pauseResume(); + getOriginalUrl(); + pageDownUp(); + clearClientCertPreferences(); + getCurrentWebViewPackage(); + setWebContentsDebuggingEnabled(); + createPdf(); + applePayAPI(); + handlesURLScheme(); }); } \ No newline at end of file diff --git a/example/integration_test/in_app_webview/page_down_up.dart b/example/integration_test/in_app_webview/page_down_up.dart new file mode 100644 index 00000000..3d286acc --- /dev/null +++ b/example/integration_test/in_app_webview/page_down_up.dart @@ -0,0 +1,45 @@ +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 pageDownUp() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('pageDown/pageUp', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + expect(await controller.pageDown(bottom: false), true); + await Future.delayed(Duration(seconds: 1)); + expect(await controller.pageUp(top: false), true); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/pause_resume.dart b/example/integration_test/in_app_webview/pause_resume.dart new file mode 100644 index 00000000..aed90e54 --- /dev/null +++ b/example/integration_test/in_app_webview/pause_resume.dart @@ -0,0 +1,45 @@ +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 pauseResume() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('pause/resume', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + await expectLater(controller.pause(), completes); + await Future.delayed(Duration(seconds: 1)); + await expectLater(controller.resume(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/pause_resume_timers.dart b/example/integration_test/in_app_webview/pause_resume_timers.dart new file mode 100644 index 00000000..64eb080d --- /dev/null +++ b/example/integration_test/in_app_webview/pause_resume_timers.dart @@ -0,0 +1,58 @@ +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 pauseResumeTimers() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('pause/resume timers', (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_URL_ABOUT_BLANK), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await controller.evaluateJavascript(source: """ + var count = 0; + setInterval(function() { + count = count + 10; + }, 20); + """); + + await controller.pauseTimers(); + await Future.delayed(Duration(seconds: 2)); + await controller.resumeTimers(); + expect( + await controller.evaluateJavascript(source: "count;"), lessThan(50)); + await Future.delayed(Duration(seconds: 4)); + expect(await controller.evaluateJavascript(source: "count;"), + greaterThan(50)); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/print_current_page.dart b/example/integration_test/in_app_webview/print_current_page.dart new file mode 100644 index 00000000..db200416 --- /dev/null +++ b/example/integration_test/in_app_webview/print_current_page.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 printCurrentPage() { + 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('printCurrentPage', (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: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await expectLater(controller.printCurrentPage(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/programmatic_zoom_scale.dart b/example/integration_test/in_app_webview/programmatic_zoom_scale.dart new file mode 100644 index 00000000..429b2589 --- /dev/null +++ b/example/integration_test/in_app_webview/programmatic_zoom_scale.dart @@ -0,0 +1,152 @@ +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 programmaticZoomScale() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('programmatic zoom scale', () { + final shouldSkipTest1 = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('zoomIn/zoomOut', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + expect(await controller.zoomIn(), true); + await Future.delayed(Duration(seconds: 1)); + expect(await controller.zoomOut(), true); + }, skip: shouldSkipTest1); + + 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); + }); + + testWidgets('zoomBy', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await expectLater( + controller.zoomBy(zoomFactor: 3.0, animated: true), completes); + }); + + testWidgets('getZoomScale', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + final scale = await controller.getZoomScale(); + expect(scale, isNonZero); + expect(scale, isPositive); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/pull_to_refresh.dart b/example/integration_test/in_app_webview/pull_to_refresh.dart new file mode 100644 index 00000000..af6d7ccf --- /dev/null +++ b/example/integration_test/in_app_webview/pull_to_refresh.dart @@ -0,0 +1,52 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../constants.dart'; + +void pullToRefresh() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('launches with pull-to-refresh feature', + (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final pullToRefreshController = PullToRefreshController( + settings: PullToRefreshSettings( + color: Colors.blue, + size: PullToRefreshSize.DEFAULT, + backgroundColor: Colors.grey, + enabled: true, + slingshotDistance: 150, + distanceToTriggerSync: 150, + attributedTitle: AttributedString(string: "test")), + onRefresh: () {}, + ); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_URL_1), + pullToRefreshController: pullToRefreshController, + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + ), + ), + ); + final InAppWebViewController controller = await controllerCompleter.future; + final String? currentUrl = (await controller.getUrl())?.toString(); + expect(currentUrl, TEST_URL_1.toString()); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/reload.dart b/example/integration_test/in_app_webview/reload.dart index 64163c4f..3063091b 100644 --- a/example/integration_test/in_app_webview/reload.dart +++ b/example/integration_test/in_app_webview/reload.dart @@ -17,36 +17,69 @@ void reload() { var url = !kIsWeb ? TEST_URL_1 : TEST_WEB_PLATFORM_URL_1; - testWidgets('reload', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = - StreamController.broadcast(); + group('reload', () { + final shouldSkipTest1 = kIsWeb || + ![ + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: url), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoads.add(url!.toString()); - }, + testWidgets('reload from origin', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), ), - ), - ); - final InAppWebViewController controller = - await controllerCompleter.future; - String? reloadUrl = await pageLoads.stream.first; - expect(reloadUrl, url.toString()); + ); - await controller.reload(); - reloadUrl = await pageLoads.stream.first; - expect(reloadUrl, url.toString()); + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + await expectLater(controller.reloadFromOrigin(), completes); + }, skip: shouldSkipTest1); - pageLoads.close(); + testWidgets('basic', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = + StreamController.broadcast(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: url), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoads.add(url!.toString()); + }, + ), + ), + ); + final InAppWebViewController controller = + await controllerCompleter.future; + String? reloadUrl = await pageLoads.stream.first; + expect(reloadUrl, url.toString()); + + await controller.reload(); + reloadUrl = await pageLoads.stream.first; + expect(reloadUrl, url.toString()); + + pageLoads.close(); + }); }, skip: shouldSkip); } diff --git a/example/integration_test/in_app_webview/request_focus_node_href.dart b/example/integration_test/in_app_webview/request_focus_node_href.dart new file mode 100644 index 00000000..c26f2e8a --- /dev/null +++ b/example/integration_test/in_app_webview/request_focus_node_href.dart @@ -0,0 +1,45 @@ +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 requestFocusNodeHref() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('requestFocusNodeHref', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await expectLater(controller.requestFocusNodeHref(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/request_image_ref.dart b/example/integration_test/in_app_webview/request_image_ref.dart new file mode 100644 index 00000000..35eca2e8 --- /dev/null +++ b/example/integration_test/in_app_webview/request_image_ref.dart @@ -0,0 +1,45 @@ +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 requestImageRef() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('requestImageRef', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + await expectLater(controller.requestImageRef(), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/safe_browsing.dart b/example/integration_test/in_app_webview/safe_browsing.dart new file mode 100644 index 00000000..48ee97dd --- /dev/null +++ b/example/integration_test/in_app_webview/safe_browsing.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 '../constants.dart'; + +void safeBrowsing() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + group('safe browsing', () { + 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()); + }); + + test('getSafeBrowsingPrivacyPolicyUrl', () async { + expect(await InAppWebViewController.getSafeBrowsingPrivacyPolicyUrl(), + isNotNull); + }); + + test('setSafeBrowsingWhitelist', () async { + expect( + await InAppWebViewController.setSafeBrowsingWhitelist( + hosts: ["flutter.dev", "github.com"]), + true); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/set_web_contents_debugging_enabled.dart b/example/integration_test/in_app_webview/set_web_contents_debugging_enabled.dart new file mode 100644 index 00000000..5c1fa637 --- /dev/null +++ b/example/integration_test/in_app_webview/set_web_contents_debugging_enabled.dart @@ -0,0 +1,16 @@ +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 setWebContentsDebuggingEnabled() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + test('setWebContentsDebuggingEnabled', () async { + expect( + InAppWebViewController.setWebContentsDebuggingEnabled(true), completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/stop_loading.dart b/example/integration_test/in_app_webview/stop_loading.dart new file mode 100644 index 00000000..101c2f76 --- /dev/null +++ b/example/integration_test/in_app_webview/stop_loading.dart @@ -0,0 +1,53 @@ +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'; +import '../util.dart'; + +void stopLoading() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('stopLoading', (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), + initialSettings: InAppWebViewSettings(clearCache: true), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStart: (controller, url) { + controller.stopLoading(); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = await controllerCompleter.future; + + if (defaultTargetPlatform == TargetPlatform.android) { + await pageLoaded.future; + expect(await controller.evaluateJavascript(source: "document.body"), + isNullOrEmpty); + } else if (defaultTargetPlatform == TargetPlatform.iOS) { + expect(pageLoaded.future, doesNotComplete); + } + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/t_rex_runner_game.dart b/example/integration_test/in_app_webview/t_rex_runner_game.dart new file mode 100644 index 00000000..3aa280aa --- /dev/null +++ b/example/integration_test/in_app_webview/t_rex_runner_game.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 tRexRunnerGame() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('T-Rex Runner game', (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_URL_ABOUT_BLANK), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + var html = await controller.getTRexRunnerHtml(); + var css = await controller.getTRexRunnerCss(); + + expect(html, isNotNull); + expect(css, isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/take_screenshot.dart b/example/integration_test/in_app_webview/take_screenshot.dart new file mode 100644 index 00000000..b8b74874 --- /dev/null +++ b/example/integration_test/in_app_webview/take_screenshot.dart @@ -0,0 +1,51 @@ +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 takeScreenshot() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('takeScreenshot', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + var screenshotConfiguration = ScreenshotConfiguration( + compressFormat: CompressFormat.JPEG, + quality: 20, + rect: InAppWebViewRect(width: 100, height: 100, x: 50, y: 50)); + var screenshot = await controller.takeScreenshot( + screenshotConfiguration: screenshotConfiguration); + expect(screenshot, isNotNull); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/user_scripts.dart b/example/integration_test/in_app_webview/user_scripts.dart new file mode 100644 index 00000000..a39f8848 --- /dev/null +++ b/example/integration_test/in_app_webview/user_scripts.dart @@ -0,0 +1,136 @@ +import 'dart:async'; +import 'dart:collection'; + +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 userScripts() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('user scripts', () { + testWidgets('initialUserScripts', (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), + initialUserScripts: UnmodifiableListView([ + UserScript( + source: "var foo = 49;", + injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START), + UserScript( + source: "var foo2 = 19;", + injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START, + contentWorld: ContentWorld.PAGE), + UserScript( + source: "var bar = 2;", + injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END, + contentWorld: ContentWorld.DEFAULT_CLIENT), + UserScript( + source: "var bar2 = 12;", + injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END, + contentWorld: ContentWorld.world(name: "test")), + ]), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) async { + pageLoaded.complete(); + }, + ), + ), + ); + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + expect(await controller.evaluateJavascript(source: "foo;"), 49); + expect(await controller.evaluateJavascript(source: "foo2;"), 19); + expect( + await controller.evaluateJavascript( + source: "foo2;", contentWorld: ContentWorld.PAGE), + 19); + expect(await controller.evaluateJavascript(source: "bar;"), isNull); + expect(await controller.evaluateJavascript(source: "bar2;"), isNull); + expect( + await controller.evaluateJavascript( + source: "bar;", contentWorld: ContentWorld.DEFAULT_CLIENT), + 2); + expect( + await controller.evaluateJavascript( + source: "bar2;", contentWorld: ContentWorld.world(name: "test")), + 12); + }); + + testWidgets('add/remove user scripts', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = + StreamController.broadcast(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoads.add(url!.toString()); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoads.stream.first; + + var userScript1 = UserScript( + source: "window.foo = 49;", + injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START); + var userScript2 = UserScript( + source: "window.bar = 19;", + injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END); + await controller.addUserScripts(userScripts: [userScript1, userScript2]); + await controller.reload(); + await pageLoads.stream.first; + var value = await controller.evaluateJavascript(source: "window.foo;"); + expect(value, 49); + value = await controller.evaluateJavascript(source: "window.bar;"); + expect(value, 19); + + await controller.removeUserScript(userScript: userScript1); + await controller.reload(); + await pageLoads.stream.first; + value = await controller.evaluateJavascript(source: "window.foo;"); + expect(value, isNull); + value = await controller.evaluateJavascript(source: "window.bar;"); + expect(value, 19); + + await controller.removeAllUserScripts(); + await controller.reload(); + await pageLoads.stream.first; + value = await controller.evaluateJavascript(source: "window.foo;"); + expect(value, isNull); + value = await controller.evaluateJavascript(source: "window.bar;"); + expect(value, isNull); + + pageLoads.close(); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/web_archive.dart b/example/integration_test/in_app_webview/web_archive.dart new file mode 100644 index 00000000..951a06a8 --- /dev/null +++ b/example/integration_test/in_app_webview/web_archive.dart @@ -0,0 +1,104 @@ +import 'dart:async'; +import 'dart:io'; + +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 'package:path_provider/path_provider.dart'; + +import '../constants.dart'; + +void webArchive() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('web archive', () { + + final shouldSkipTest1 = kIsWeb || + ![ + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('create data', (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); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + expect(await controller.createWebArchiveData(), isNotNull); + }, skip: shouldSkipTest1); + + testWidgets('save', (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_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoaded.complete(); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoaded.future; + + // wait a little bit after page load otherwise Android will not save the web archive + await Future.delayed(Duration(seconds: 1)); + + var supportDir = await getApplicationSupportDirectory(); + + var fileName = "flutter-website."; + if (defaultTargetPlatform == TargetPlatform.android) { + fileName = fileName + WebArchiveFormat.MHT.toValue(); + } else if (defaultTargetPlatform == TargetPlatform.iOS) { + fileName = fileName + WebArchiveFormat.WEBARCHIVE.toValue(); + } + + var fullPath = supportDir.path + Platform.pathSeparator + fileName; + var path = await controller.saveWebArchive(filePath: fullPath); + expect(path, isNotNull); + expect(path, endsWith(fileName)); + + path = await controller.saveWebArchive( + filePath: supportDir.path, autoname: true); + expect(path, isNotNull); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/web_history.dart b/example/integration_test/in_app_webview/web_history.dart new file mode 100644 index 00000000..629fb2cd --- /dev/null +++ b/example/integration_test/in_app_webview/web_history.dart @@ -0,0 +1,213 @@ +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 webHistory() { + final shouldSkip = !kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('web history', () { + final shouldSkipTest1 = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + testWidgets('get history list and go back/forward', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = + StreamController.broadcast(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoads.add(url!.toString()); + }, + ), + ), + ); + + final InAppWebViewController controller = await controllerCompleter.future; + + var url = await pageLoads.stream.first; + var webHistory = await controller.getCopyBackForwardList(); + expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); + expect(webHistory!.currentIndex, 0); + expect(webHistory.list!.length, 1); + expect(webHistory.list![0].url.toString(), TEST_CROSS_PLATFORM_URL_1.toString()); + + await controller.loadUrl( + urlRequest: URLRequest(url: TEST_URL_1)); + url = await pageLoads.stream.first; + webHistory = await controller.getCopyBackForwardList(); + expect(url, TEST_URL_1.toString()); + expect(await controller.canGoBack(), true); + expect(await controller.canGoForward(), false); + expect(await controller.canGoBackOrForward(steps: -1), true); + expect(await controller.canGoBackOrForward(steps: 1), false); + expect(webHistory!.currentIndex, 1); + expect(webHistory.list!.length, 2); + expect(webHistory.list![0].url.toString(), TEST_CROSS_PLATFORM_URL_1.toString()); + expect(webHistory.list![1].url.toString(), TEST_URL_1.toString()); + + await Future.delayed(Duration(seconds: 1)); + await controller.goBack(); + url = await pageLoads.stream.first; + webHistory = await controller.getCopyBackForwardList(); + expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); + expect(await controller.canGoBack(), false); + expect(await controller.canGoForward(), true); + expect(await controller.canGoBackOrForward(steps: -1), false); + expect(await controller.canGoBackOrForward(steps: 1), true); + expect(webHistory!.currentIndex, 0); + expect(webHistory.list!.length, 2); + expect(webHistory.list![0].url.toString(), TEST_CROSS_PLATFORM_URL_1.toString()); + expect(webHistory.list![1].url.toString(), TEST_URL_1.toString()); + + await Future.delayed(Duration(seconds: 1)); + await controller.goForward(); + url = await pageLoads.stream.first; + webHistory = await controller.getCopyBackForwardList(); + expect(url, TEST_URL_1.toString()); + expect(await controller.canGoBack(), true); + expect(await controller.canGoForward(), false); + expect(await controller.canGoBackOrForward(steps: -1), true); + expect(await controller.canGoBackOrForward(steps: 1), false); + expect(webHistory!.currentIndex, 1); + expect(webHistory.list!.length, 2); + expect(webHistory.list![0].url.toString(), TEST_CROSS_PLATFORM_URL_1.toString()); + expect(webHistory.list![1].url.toString(), TEST_URL_1.toString()); + + await Future.delayed(Duration(seconds: 1)); + await controller.goTo(historyItem: webHistory.list![0]); + url = await pageLoads.stream.first; + webHistory = await controller.getCopyBackForwardList(); + expect(url, TEST_CROSS_PLATFORM_URL_1.toString()); + expect(await controller.canGoBack(), false); + expect(await controller.canGoForward(), true); + expect(await controller.canGoBackOrForward(steps: -1), false); + expect(await controller.canGoBackOrForward(steps: 1), true); + expect(webHistory!.currentIndex, 0); + expect(webHistory.list!.length, 2); + expect(webHistory.list![0].url.toString(), TEST_CROSS_PLATFORM_URL_1.toString()); + expect(webHistory.list![1].url.toString(), TEST_URL_1.toString()); + + pageLoads.close(); + }, skip: shouldSkipTest1); + + final shouldSkipTest2 = !kIsWeb; + + testWidgets('go back/forward on web platform', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final StreamController pageLoads = + StreamController.broadcast(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: TEST_WEB_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoads.add(url!.toString()); + }, + ), + ), + ); + + final InAppWebViewController controller = await controllerCompleter.future; + + var url = await pageLoads.stream.first; + expect(url, TEST_WEB_PLATFORM_URL_1.toString()); + + await controller.loadUrl( + urlRequest: URLRequest(url: TEST_WEB_PLATFORM_URL_2)); + url = await pageLoads.stream.first; + expect(url, TEST_WEB_PLATFORM_URL_2.toString()); + + await Future.delayed(Duration(seconds: 1)); + await controller.goBack(); + url = await pageLoads.stream.first; + expect(url, TEST_WEB_PLATFORM_URL_1.toString()); + + await Future.delayed(Duration(seconds: 1)); + await controller.goForward(); + url = await pageLoads.stream.first; + expect(url, TEST_WEB_PLATFORM_URL_2.toString()); + + await Future.delayed(Duration(seconds: 1)); + await controller.goBackOrForward(steps: -1); + url = await pageLoads.stream.first; + expect(url, TEST_WEB_PLATFORM_URL_1.toString()); + + pageLoads.close(); + }, skip: shouldSkipTest2); + + final shouldSkipTest3 = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('clearHistory', (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + final StreamController pageLoads = + StreamController.broadcast(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: + URLRequest(url: TEST_CROSS_PLATFORM_URL_1), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onLoadStop: (controller, url) { + pageLoads.add(url!.toString()); + }, + ), + ), + ); + + final InAppWebViewController controller = + await controllerCompleter.future; + await pageLoads.stream.first; + await controller.loadUrl( + urlRequest: + URLRequest(url: TEST_URL_1)); + await pageLoads.stream.first; + + var webHistory = await controller.getCopyBackForwardList(); + expect(webHistory!.list!.length, 2); + + await controller.clearHistory(); + + webHistory = await controller.getCopyBackForwardList(); + expect(webHistory!.list!.length, 1); + + pageLoads.close(); + }, skip: shouldSkipTest3); + }, skip: shouldSkip); +} diff --git a/example/integration_test/in_app_webview/web_message.dart b/example/integration_test/in_app_webview/web_message.dart new file mode 100644 index 00000000..1edbcce2 --- /dev/null +++ b/example/integration_test/in_app_webview/web_message.dart @@ -0,0 +1,136 @@ +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 webMessage() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + TargetPlatform.iOS, + TargetPlatform.macOS, + ].contains(defaultTargetPlatform); + + group('WebMessage', () { + testWidgets('WebMessageChannel', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer webMessageCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialData: InAppWebViewInitialData(data: """ + + + + + WebMessageChannel Test + + + +
+ + + + + + """), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + onConsoleMessage: (controller, consoleMessage) { + webMessageCompleter.complete(consoleMessage.message); + }, + onLoadStop: (controller, url) async { + var webMessageChannel = + await controller.createWebMessageChannel(); + var port1 = webMessageChannel!.port1; + var port2 = webMessageChannel.port2; + + await port1.setWebMessageCallback((message) async { + await port1 + .postMessage(WebMessage(data: message! + " and back")); + }); + await controller.postWebMessage( + message: WebMessage(data: "capturePort", ports: [port2]), + targetOrigin: Uri.parse("*")); + await controller.evaluateJavascript( + source: "document.getElementById('button').click();"); + }, + ), + ), + ); + await controllerCompleter.future; + + final String message = await webMessageCompleter.future; + expect(message, 'JavaScript To Native and back'); + }); + + testWidgets('WebMessageListener', (WidgetTester tester) async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + final Completer webMessageCompleter = Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + onWebViewCreated: (controller) async { + await controller.addWebMessageListener(WebMessageListener( + jsObjectName: "myTestObj", + allowedOriginRules: Set.from(["https://*.example.com"]), + onPostMessage: + (message, sourceOrigin, isMainFrame, replyProxy) { + assert( + sourceOrigin.toString() == TEST_URL_EXAMPLE.toString()); + assert(isMainFrame); + + replyProxy.postMessage(message! + " and back"); + }, + )); + controllerCompleter.complete(controller); + }, + onConsoleMessage: (controller, consoleMessage) { + webMessageCompleter.complete(consoleMessage.message); + }, + onLoadStop: (controller, url) async { + if (url.toString() == TEST_URL_EXAMPLE.toString()) { + pageLoaded.complete(); + } + }, + ), + ), + ); + final controller = await controllerCompleter.future; + await controller.loadUrl(urlRequest: URLRequest(url: TEST_URL_EXAMPLE)); + await pageLoaded.future; + + await controller.evaluateJavascript(source: """ + myTestObj.addEventListener('message', function(event) { + console.log(event.data); + }); + myTestObj.postMessage('JavaScript To Native'); + """); + + final String message = await webMessageCompleter.future; + expect(message, 'JavaScript To Native and back'); + }); + }, skip: shouldSkip); +} diff --git a/example/integration_test/service_worker/main.dart b/example/integration_test/service_worker/main.dart new file mode 100644 index 00000000..c4f255f0 --- /dev/null +++ b/example/integration_test/service_worker/main.dart @@ -0,0 +1,11 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'set_service_worker_client.dart'; +import 'should_intercept_request.dart'; + +void main() { + group('Service Worker', () { + shouldInterceptRequest(); + setServiceWorkerClient(); + }); +} \ No newline at end of file diff --git a/example/integration_test/in_app_webview/on_safe_browsing_hit.dart b/example/integration_test/service_worker/set_service_worker_client.dart similarity index 50% rename from example/integration_test/in_app_webview/on_safe_browsing_hit.dart rename to example/integration_test/service_worker/set_service_worker_client.dart index e8e86af8..c880fd80 100644 --- a/example/integration_test/in_app_webview/on_safe_browsing_hit.dart +++ b/example/integration_test/service_worker/set_service_worker_client.dart @@ -7,42 +7,42 @@ import 'package:flutter_test/flutter_test.dart'; import '../constants.dart'; -void onSafeBrowsingHit() { +void setServiceWorkerClient() { final shouldSkip = kIsWeb || ![ TargetPlatform.android, ].contains(defaultTargetPlatform); - testWidgets('onSafeBrowsingHit', (WidgetTester tester) async { + testWidgets('setServiceWorkerClient to null', (WidgetTester tester) async { final Completer pageLoaded = Completer(); + + var swAvailable = await WebViewFeature.isFeatureSupported( + WebViewFeature.SERVICE_WORKER_BASIC_USAGE); + var swInterceptAvailable = await WebViewFeature.isFeatureSupported( + WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST); + + if (swAvailable && swInterceptAvailable) { + ServiceWorkerController serviceWorkerController = + ServiceWorkerController.instance(); + + await serviceWorkerController.setServiceWorkerClient(null); + } + 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(); - }, + initialUrlRequest: + URLRequest(url: TEST_SERVICE_WORKER_URL), 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()); + expect(url, TEST_SERVICE_WORKER_URL.toString()); }, skip: shouldSkip); } diff --git a/example/integration_test/service_worker/should_intercept_request.dart b/example/integration_test/service_worker/should_intercept_request.dart new file mode 100644 index 00000000..915c1826 --- /dev/null +++ b/example/integration_test/service_worker/should_intercept_request.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 shouldInterceptRequest() { + final shouldSkip = kIsWeb || + ![ + TargetPlatform.android, + ].contains(defaultTargetPlatform); + + testWidgets('shouldInterceptRequest', (WidgetTester tester) async { + final Completer completer = Completer(); + + var swAvailable = await WebViewFeature.isFeatureSupported( + WebViewFeature.SERVICE_WORKER_BASIC_USAGE); + var swInterceptAvailable = await WebViewFeature.isFeatureSupported( + WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST); + + if (swAvailable && swInterceptAvailable) { + ServiceWorkerController serviceWorkerController = + ServiceWorkerController.instance(); + + await serviceWorkerController.setServiceWorkerClient(ServiceWorkerClient( + shouldInterceptRequest: (request) async { + if (!completer.isCompleted) { + completer.complete(); + } + return null; + }, + )); + } else { + completer.complete(); + } + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: InAppWebView( + key: GlobalKey(), + initialUrlRequest: URLRequest(url: TEST_SERVICE_WORKER_URL), + ), + ), + ); + + expect(completer.future, completes); + }, skip: shouldSkip); +} diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index 22af6eb8..9711bdbc 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -1,20 +1,14 @@ -import 'dart:async'; -import 'dart:collection'; -import 'dart:convert'; -import 'dart:typed_data'; - import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; -import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'in_app_webview/main.dart' as in_app_webview_tests; - -import '.env.dart'; - -import 'util.dart'; +import 'service_worker/main.dart' as service_worker_tests; +import 'headless_in_app_webview/main.dart' as headless_in_app_webview_tests; +import 'cookie_manager/main.dart' as cookie_manager_tests; +import 'in_app_browser/main.dart' as in_app_browser_tests; +import 'chrome_safari_browser/main.dart' as chrome_safari_browser_tests; +import 'in_app_localhost_server/main.dart' as in_app_localhost_server_tests; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -24,2110 +18,10 @@ void main() { } in_app_webview_tests.main(); - - group('InAppWebView', () { - - - testWidgets('web history - go back and forward', - (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = - StreamController.broadcast(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://flutter.dev/')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoads.add(url!.toString()); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - - var url = await pageLoads.stream.first; - var webHistory = await controller.getCopyBackForwardList(); - expect(url, 'https://flutter.dev/'); - expect(webHistory!.currentIndex, 0); - expect(webHistory.list!.length, 1); - expect(webHistory.list![0].url.toString(), 'https://flutter.dev/'); - - await controller.loadUrl( - urlRequest: URLRequest(url: Uri.parse('https://github.com/flutter'))); - url = await pageLoads.stream.first; - webHistory = await controller.getCopyBackForwardList(); - expect(url, 'https://github.com/flutter'); - expect(await controller.canGoBack(), true); - expect(await controller.canGoForward(), false); - expect(await controller.canGoBackOrForward(steps: -1), true); - expect(await controller.canGoBackOrForward(steps: 1), false); - expect(webHistory!.currentIndex, 1); - expect(webHistory.list!.length, 2); - expect(webHistory.list![0].url.toString(), 'https://flutter.dev/'); - expect(webHistory.list![1].url.toString(), 'https://github.com/flutter'); - - await Future.delayed(Duration(seconds: 1)); - await controller.goBack(); - url = await pageLoads.stream.first; - webHistory = await controller.getCopyBackForwardList(); - expect(url, 'https://flutter.dev/'); - expect(await controller.canGoBack(), false); - expect(await controller.canGoForward(), true); - expect(await controller.canGoBackOrForward(steps: -1), false); - expect(await controller.canGoBackOrForward(steps: 1), true); - expect(webHistory!.currentIndex, 0); - expect(webHistory.list!.length, 2); - expect(webHistory.list![0].url.toString(), 'https://flutter.dev/'); - expect(webHistory.list![1].url.toString(), 'https://github.com/flutter'); - - await Future.delayed(Duration(seconds: 1)); - await controller.goForward(); - url = await pageLoads.stream.first; - webHistory = await controller.getCopyBackForwardList(); - expect(url, 'https://github.com/flutter'); - expect(await controller.canGoBack(), true); - expect(await controller.canGoForward(), false); - expect(await controller.canGoBackOrForward(steps: -1), true); - expect(await controller.canGoBackOrForward(steps: 1), false); - expect(webHistory!.currentIndex, 1); - expect(webHistory.list!.length, 2); - expect(webHistory.list![0].url.toString(), 'https://flutter.dev/'); - expect(webHistory.list![1].url.toString(), 'https://github.com/flutter'); - - await Future.delayed(Duration(seconds: 1)); - await controller.goTo(historyItem: webHistory.list![0]); - url = await pageLoads.stream.first; - webHistory = await controller.getCopyBackForwardList(); - expect(url, 'https://flutter.dev/'); - expect(await controller.canGoBack(), false); - expect(await controller.canGoForward(), true); - expect(await controller.canGoBackOrForward(steps: -1), false); - expect(await controller.canGoBackOrForward(steps: 1), true); - expect(webHistory!.currentIndex, 0); - expect(webHistory.list!.length, 2); - expect(webHistory.list![0].url.toString(), 'https://flutter.dev/'); - expect(webHistory.list![1].url.toString(), 'https://github.com/flutter'); - - pageLoads.close(); - }); - - testWidgets('getProgress', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final int? progress = await controller.getProgress(); - expect(progress, 100); - }); - - testWidgets('getHtml', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final String? html = await controller.getHtml(); - expect(html, isNotNull); - }); - - testWidgets('getFavicons', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final List? favicons = await controller.getFavicons(); - expect(favicons, isNotNull); - expect(favicons, isNotEmpty); - }); - - testWidgets('isLoading', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageStarted = 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); - }, - onLoadStart: (controller, url) { - pageStarted.complete(); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageStarted.future; - expect(await controller.isLoading(), true); - - await pageLoaded.future; - expect(await controller.isLoading(), false); - }); - - testWidgets('stopLoading', (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')), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions(clearCache: true)), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStart: (controller, url) { - controller.stopLoading(); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - - if (defaultTargetPlatform == TargetPlatform.android) { - await pageLoaded.future; - expect(await controller.evaluateJavascript(source: "document.body"), - isNullOrEmpty); - } else if (defaultTargetPlatform == TargetPlatform.iOS) { - expect(pageLoaded.future, doesNotComplete); - } - }); - - testWidgets('injectJavascriptFileFromUrl', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - final Completer jQueryLoaded = Completer(); - final Completer jQueryLoadError = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest(url: Uri.parse('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.injectJavascriptFileFromUrl( - urlFile: - Uri.parse('https://www.notawebsite..com/jquery-3.3.1.min.js'), - scriptHtmlTagAttributes: ScriptHtmlTagAttributes( - id: 'jquery-error', - onError: () { - jQueryLoadError.complete(); - }, - )); - await jQueryLoadError.future; - expect( - await controller.evaluateJavascript( - source: "document.body.querySelector('#jquery-error') == null;"), - false); - expect( - await controller.evaluateJavascript(source: "window.jQuery == null;"), - true); - - await controller.injectJavascriptFileFromUrl( - urlFile: Uri.parse('https://code.jquery.com/jquery-3.3.1.min.js'), - scriptHtmlTagAttributes: ScriptHtmlTagAttributes( - id: 'jquery', - onLoad: () { - jQueryLoaded.complete(); - }, - )); - await jQueryLoaded.future; - expect( - await controller.evaluateJavascript( - source: "document.body.querySelector('#jquery') == null;"), - false); - expect( - await controller.evaluateJavascript(source: "window.jQuery == null;"), - false); - }); - - testWidgets('injectJavascriptFileFromAsset', (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('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.injectJavascriptFileFromAsset( - assetFilePath: 'test_assets/js/jquery-3.3.1.min.js'); - expect( - await controller.evaluateJavascript(source: "window.jQuery == null;"), - false); - }); - - testWidgets('injectCSSCode', (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('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.injectCSSCode(source: """ - body { - background-color: rgb(0, 0, 255); - } - """); - - String? backgroundColor = await controller.evaluateJavascript(source: """ - var element = document.body; - var style = getComputedStyle(element); - style.backgroundColor; - """); - expect(backgroundColor, 'rgb(0, 0, 255)'); - }); - - testWidgets('injectCSSFileFromUrl', (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('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.injectCSSFileFromUrl( - urlFile: Uri.parse( - 'https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css'), - cssLinkHtmlTagAttributes: CSSLinkHtmlTagAttributes(id: 'bootstrap')); - await Future.delayed(Duration(seconds: 2)); - expect( - await controller.evaluateJavascript( - source: "document.head.querySelector('#bootstrap') == null;"), - false); - }); - - testWidgets('injectCSSFileFromAsset', (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('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.injectCSSFileFromAsset( - assetFilePath: 'test_assets/css/blue-body.css'); - - String? backgroundColor = await controller.evaluateJavascript(source: """ - var element = document.body; - var style = getComputedStyle(element); - style.backgroundColor; - """); - expect(backgroundColor, 'rgb(0, 0, 255)'); - }); - - testWidgets('takeScreenshot', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - var screenshotConfiguration = ScreenshotConfiguration( - compressFormat: CompressFormat.JPEG, - quality: 20, - rect: InAppWebViewRect(width: 100, height: 100, x: 50, y: 50)); - var screenshot = await controller.takeScreenshot( - screenshotConfiguration: screenshotConfiguration); - expect(screenshot, isNotNull); - }); - - testWidgets('clearCache', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await expectLater(controller.clearCache(), completes); - }); - - testWidgets('T-Rex Runner game', (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('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - var html = await controller.getTRexRunnerHtml(); - var css = await controller.getTRexRunnerCss(); - - expect(html, isNotNull); - expect(css, isNotNull); - }); - - testWidgets('pause/resume timers', (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('about:blank')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await controller.evaluateJavascript(source: """ - var count = 0; - setInterval(function() { - count = count + 10; - }, 20); - """); - - await controller.pauseTimers(); - await Future.delayed(Duration(seconds: 2)); - await controller.resumeTimers(); - expect( - await controller.evaluateJavascript(source: "count;"), lessThan(50)); - await Future.delayed(Duration(seconds: 4)); - expect(await controller.evaluateJavascript(source: "count;"), - greaterThan(50)); - }); - - testWidgets('printCurrentPage', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await expectLater(controller.printCurrentPage(), completes); - }, skip: true); - - testWidgets('getContentHeight', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final contentHeight = await controller.getContentHeight(); - expect(contentHeight, isNonZero); - expect(contentHeight, isPositive); - }); - - testWidgets('zoomBy', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await expectLater( - controller.zoomBy(zoomFactor: 3.0, animated: true), completes); - }); - - testWidgets('getZoomScale', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final scale = await controller.getZoomScale(); - expect(scale, isNonZero); - expect(scale, isPositive); - }); - - testWidgets('clearFocus', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await expectLater(controller.clearFocus(), completes); - }); - - testWidgets('requestFocusNodeHref', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await expectLater(controller.requestFocusNodeHref(), completes); - }); - - testWidgets('requestImageRef', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - await expectLater(controller.requestImageRef(), completes); - }); - - testWidgets('getMetaTags', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - List metaTags = await controller.getMetaTags(); - expect(metaTags, isNotEmpty); - }); - - testWidgets('getMetaThemeColor', (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://github.com')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - expect(await controller.getMetaThemeColor(), isNotNull); - }); - - testWidgets('getCertificate', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - var sslCertificate = await controller.getCertificate(); - expect(sslCertificate, isNotNull); - expect(sslCertificate!.x509Certificate, isNotNull); - expect(sslCertificate.issuedBy, isNotNull); - expect(sslCertificate.issuedTo, isNotNull); - expect(sslCertificate.validNotAfterDate, isNotNull); - expect(sslCertificate.validNotBeforeDate, isNotNull); - }); - - testWidgets('add/remove user scripts', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = - StreamController.broadcast(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://flutter.dev')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoads.add(url!.toString()); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoads.stream.first; - - var userScript1 = UserScript( - source: "window.foo = 49;", - injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START); - var userScript2 = UserScript( - source: "window.bar = 19;", - injectionTime: UserScriptInjectionTime.AT_DOCUMENT_END); - await controller.addUserScripts(userScripts: [userScript1, userScript2]); - await controller.reload(); - await pageLoads.stream.first; - var value = await controller.evaluateJavascript(source: "window.foo;"); - expect(value, 49); - value = await controller.evaluateJavascript(source: "window.bar;"); - expect(value, 19); - - await controller.removeUserScript(userScript: userScript1); - await controller.reload(); - await pageLoads.stream.first; - value = await controller.evaluateJavascript(source: "window.foo;"); - expect(value, isNull); - value = await controller.evaluateJavascript(source: "window.bar;"); - expect(value, 19); - - await controller.removeAllUserScripts(); - await controller.reload(); - await pageLoads.stream.first; - value = await controller.evaluateJavascript(source: "window.foo;"); - expect(value, isNull); - value = await controller.evaluateJavascript(source: "window.bar;"); - expect(value, isNull); - - pageLoads.close(); - }); - - // testWidgets('saveWebArchive', (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://github.com/flutter')), - // onWebViewCreated: (controller) { - // controllerCompleter.complete(controller); - // }, - // onLoadStop: (controller, url) { - // pageLoaded.complete(); - // }, - // ), - // ), - // ); - // - // final InAppWebViewController controller = - // await controllerCompleter.future; - // await pageLoaded.future; - // - // // wait a little bit after page load otherwise Android will not save the web archive - // await Future.delayed(Duration(seconds: 1)); - // - // var supportDir = await getApplicationSupportDirectory(); - // - // var fileName = "flutter-website."; - // if (defaultTargetPlatform == TargetPlatform.android) { - // fileName = fileName + WebArchiveFormat.MHT.toValue(); - // } else if (defaultTargetPlatform == TargetPlatform.iOS) { - // fileName = fileName + WebArchiveFormat.WEBARCHIVE.toValue(); - // } - // - // var fullPath = supportDir.path + Platform.pathSeparator + fileName; - // var path = await controller.saveWebArchive(filePath: fullPath); - // expect(path, isNotNull); - // expect(path, endsWith(fileName)); - // - // path = await controller.saveWebArchive( - // filePath: supportDir.path, autoname: true); - // expect(path, isNotNull); - // }); - - testWidgets('isSecureContext', (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final StreamController pageLoads = - StreamController.broadcast(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://flutter.dev')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoads.add(url!.toString()); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoads.stream.first; - expect(await controller.isSecureContext(), true); - - await controller.loadUrl( - urlRequest: URLRequest(url: Uri.parse('http://example.com/'))); - await pageLoads.stream.first; - expect(await controller.isSecureContext(), false); - - pageLoads.close(); - }); - - test('getDefaultUserAgent', () async { - expect(await InAppWebViewController.getDefaultUserAgent(), isNotNull); - }); - - testWidgets('launches with pull-to-refresh feature', - (WidgetTester tester) async { - final Completer controllerCompleter = Completer(); - final pullToRefreshController = PullToRefreshController( - options: PullToRefreshOptions( - color: Colors.blue, - size: AndroidPullToRefreshSize.DEFAULT, - backgroundColor: Colors.grey, - enabled: true, - slingshotDistance: 150, - distanceToTriggerSync: 150, - attributedTitle: IOSNSAttributedString(string: "test")), - onRefresh: () {}, - ); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter')), - initialOptions: InAppWebViewGroupOptions( - android: - AndroidInAppWebViewOptions(useHybridComposition: true)), - pullToRefreshController: pullToRefreshController, - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - ), - ), - ); - final InAppWebViewController controller = - await controllerCompleter.future; - final String? currentUrl = (await controller.getUrl())?.toString(); - expect(currentUrl, 'https://github.com/flutter'); - }); - - group('WebMessage', () { - testWidgets('WebMessageChannel', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer webMessageCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - WebMessageChannel Test - - - -
- - - - - - """), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onConsoleMessage: (controller, consoleMessage) { - webMessageCompleter.complete(consoleMessage.message); - }, - onLoadStop: (controller, url) async { - var webMessageChannel = - await controller.createWebMessageChannel(); - var port1 = webMessageChannel!.port1; - var port2 = webMessageChannel.port2; - - await port1.setWebMessageCallback((message) async { - await port1 - .postMessage(WebMessage(data: message! + " and back")); - }); - await controller.postWebMessage( - message: WebMessage(data: "capturePort", ports: [port2]), - targetOrigin: Uri.parse("*")); - await controller.evaluateJavascript( - source: "document.getElementById('button').click();"); - }, - ), - ), - ); - await controllerCompleter.future; - - final String message = await webMessageCompleter.future; - expect(message, 'JavaScript To Native and back'); - }); - - testWidgets('WebMessageListener', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final Completer pageLoaded = Completer(); - final Completer webMessageCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - onWebViewCreated: (controller) async { - await controller.addWebMessageListener(WebMessageListener( - jsObjectName: "myTestObj", - allowedOriginRules: Set.from(["https://*.example.com"]), - onPostMessage: - (message, sourceOrigin, isMainFrame, replyProxy) { - assert( - sourceOrigin.toString() == "https://www.example.com"); - assert(isMainFrame); - - replyProxy.postMessage(message! + " and back"); - }, - )); - controllerCompleter.complete(controller); - }, - onConsoleMessage: (controller, consoleMessage) { - webMessageCompleter.complete(consoleMessage.message); - }, - onLoadStop: (controller, url) async { - if (url.toString() == "https://www.example.com/") { - pageLoaded.complete(); - } - }, - ), - ), - ); - final controller = await controllerCompleter.future; - await controller.loadUrl( - urlRequest: URLRequest(url: Uri.parse("https://www.example.com/"))); - await pageLoaded.future; - - await controller.evaluateJavascript(source: """ - myTestObj.addEventListener('message', function(event) { - console.log(event.data); - }); - myTestObj.postMessage('JavaScript To Native'); - """); - - final String message = await webMessageCompleter.future; - expect(message, 'JavaScript To Native and back'); - }); - }); - - group('android methods', () { - testWidgets('clearSslPreferences', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await expectLater(controller.android.clearSslPreferences(), completes); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('pause/resume', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await expectLater(controller.android.pause(), completes); - await Future.delayed(Duration(seconds: 1)); - await expectLater(controller.android.resume(), completes); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('getOriginalUrl', (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://github.com/flutter')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - var originUrl = (await controller.getOriginalUrl())?.toString(); - expect(originUrl, 'https://github.com/flutter'); - }); - - testWidgets('pageDown/pageUp', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - expect(await controller.android.pageDown(bottom: false), true); - await Future.delayed(Duration(seconds: 1)); - expect(await controller.android.pageUp(top: false), true); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('zoomIn/zoomOut', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - expect(await controller.android.zoomIn(), true); - await Future.delayed(Duration(seconds: 1)); - expect(await controller.android.zoomOut(), true); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('clearHistory', (WidgetTester tester) async { - final Completer controllerCompleter = - Completer(); - final StreamController pageLoads = - StreamController.broadcast(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://flutter.dev')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) { - pageLoads.add(url!.toString()); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoads.stream.first; - await controller.loadUrl( - urlRequest: - URLRequest(url: Uri.parse('https://github.com/flutter'))); - await pageLoads.stream.first; - - var webHistory = await controller.getCopyBackForwardList(); - expect(webHistory!.list!.length, 2); - - await controller.android.clearHistory(); - - webHistory = await controller.getCopyBackForwardList(); - expect(webHistory!.list!.length, 1); - - pageLoads.close(); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - test('clearClientCertPreferences', () async { - await expectLater( - AndroidInAppWebViewController.clearClientCertPreferences(), - completes); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - test('getSafeBrowsingPrivacyPolicyUrl', () async { - expect( - await AndroidInAppWebViewController - .getSafeBrowsingPrivacyPolicyUrl(), - isNotNull); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - test('setSafeBrowsingWhitelist', () async { - expect( - await AndroidInAppWebViewController.setSafeBrowsingWhitelist( - hosts: ["flutter.dev", "github.com"]), - true); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - test('getCurrentWebViewPackage', () async { - expect(await AndroidInAppWebViewController.getCurrentWebViewPackage(), - isNotNull); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - test('setWebContentsDebuggingEnabled', () async { - expect( - AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true), - completes); - }, skip: defaultTargetPlatform != TargetPlatform.android); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - group('ios methods', () { - testWidgets('reloadFromOrigin', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - await expectLater(controller.ios.reloadFromOrigin(), completes); - }, skip: defaultTargetPlatform != TargetPlatform.iOS); - - testWidgets('createPdf', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - var iosWKPdfConfiguration = IOSWKPDFConfiguration( - rect: InAppWebViewRect(width: 100, height: 100, x: 50, y: 50)); - var pdf = await controller.ios - .createPdf(iosWKPdfConfiguration: iosWKPdfConfiguration); - expect(pdf, isNotNull); - }, skip: defaultTargetPlatform != TargetPlatform.iOS); - - testWidgets('createWebArchiveData', (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); - }, - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - ), - ), - ); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - expect(await controller.ios.createWebArchiveData(), isNotNull); - }, skip: defaultTargetPlatform != TargetPlatform.iOS); - - testWidgets('Apple Pay API enabled', (WidgetTester tester) async { - final Completer pageLoaded = Completer(); - final Completer alertMessageCompleter = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialData: InAppWebViewInitialData(data: """ - - - - - - - Apple Pay API - - - - - - """), - initialOptions: InAppWebViewGroupOptions( - ios: IOSInAppWebViewOptions( - applePayAPIEnabled: true, - ), - ), - onLoadStop: (controller, url) { - pageLoaded.complete(); - }, - onJsAlert: (controller, jsAlertRequest) async { - alertMessageCompleter.complete(jsAlertRequest.message); - }, - ), - ), - ); - await pageLoaded.future; - final message = await alertMessageCompleter.future; - expect(message, 'true'); - }, skip: defaultTargetPlatform != TargetPlatform.iOS); - - test('handlesURLScheme', () async { - expect(await IOSInAppWebViewController.handlesURLScheme("http"), true); - expect(await IOSInAppWebViewController.handlesURLScheme("https"), true); - }, skip: defaultTargetPlatform != TargetPlatform.iOS); - }, skip: defaultTargetPlatform != TargetPlatform.iOS); - }); - - group('Service Worker', () { - testWidgets('shouldInterceptRequest', (WidgetTester tester) async { - final Completer completer = Completer(); - - var swAvailable = await AndroidWebViewFeature.isFeatureSupported( - AndroidWebViewFeature.SERVICE_WORKER_BASIC_USAGE); - var swInterceptAvailable = await AndroidWebViewFeature.isFeatureSupported( - AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST); - - if (swAvailable && swInterceptAvailable) { - AndroidServiceWorkerController serviceWorkerController = - AndroidServiceWorkerController.instance(); - - await serviceWorkerController - .setServiceWorkerClient(AndroidServiceWorkerClient( - shouldInterceptRequest: (request) async { - if (!completer.isCompleted) { - completer.complete(); - } - return null; - }, - )); - } else { - completer.complete(); - } - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://mdn.github.io/sw-test/')), - ), - ), - ); - - expect(completer.future, completes); - }, skip: defaultTargetPlatform != TargetPlatform.android); - - testWidgets('setServiceWorkerClient to null', (WidgetTester tester) async { - final Completer pageLoaded = Completer(); - - var swAvailable = await AndroidWebViewFeature.isFeatureSupported( - AndroidWebViewFeature.SERVICE_WORKER_BASIC_USAGE); - var swInterceptAvailable = await AndroidWebViewFeature.isFeatureSupported( - AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST); - - if (swAvailable && swInterceptAvailable) { - AndroidServiceWorkerController serviceWorkerController = - AndroidServiceWorkerController.instance(); - - await serviceWorkerController.setServiceWorkerClient(null); - } - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: - URLRequest(url: Uri.parse('https://mdn.github.io/sw-test/')), - onLoadStop: (controller, url) { - pageLoaded.complete(url!.toString()); - }, - ), - ), - ); - - final String url = await pageLoaded.future; - expect(url, "https://mdn.github.io/sw-test/"); - }, skip: defaultTargetPlatform != TargetPlatform.android); - }); - - group('Cookie Manager', () { - testWidgets('set, get, delete', (WidgetTester tester) async { - CookieManager cookieManager = CookieManager.instance(); - 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, - )), - onLoadStop: (controller, url) { - pageLoaded.complete(url!.toString()); - }, - ), - ), - ); - - final url = Uri.parse(await pageLoaded.future); - - await cookieManager.setCookie( - url: url, name: "myCookie", value: "myValue"); - List cookies = await cookieManager.getCookies(url: url); - expect(cookies, isNotEmpty); - - Cookie? cookie = - await cookieManager.getCookie(url: url, name: "myCookie"); - expect(cookie?.value.toString(), "myValue"); - - await cookieManager.deleteCookie(url: url, name: "myCookie"); - cookie = await cookieManager.getCookie(url: url, name: "myCookie"); - expect(cookie, isNull); - - await cookieManager.deleteCookies(url: url); - cookies = await cookieManager.getCookies(url: url); - expect(cookies, isEmpty); - }); - }); - - group('HeadlessInAppWebView', () { - test('run and dispose', () async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - - var headlessWebView = new HeadlessInAppWebView( - initialUrlRequest: - URLRequest(url: Uri.parse("https://github.com/flutter")), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - ); - headlessWebView.onLoadStop = (controller, url) async { - pageLoaded.complete(); - }; - - await headlessWebView.run(); - expect(headlessWebView.isRunning(), true); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final String? url = (await controller.getUrl())?.toString(); - expect(url, 'https://github.com/flutter'); - - await headlessWebView.dispose(); - - expect(headlessWebView.isRunning(), false); - }); - - test('take screenshot', () async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - - var headlessWebView = new HeadlessInAppWebView( - initialUrlRequest: - URLRequest(url: Uri.parse("https://github.com/flutter")), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) async { - pageLoaded.complete(); - }); - - await headlessWebView.run(); - expect(headlessWebView.isRunning(), true); - - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - final String? url = (await controller.getUrl())?.toString(); - expect(url, 'https://github.com/flutter'); - - final Size? size = await headlessWebView.getSize(); - expect(size, isNotNull); - - final Uint8List? screenshot = await controller.takeScreenshot(); - expect(screenshot, isNotNull); - - await headlessWebView.dispose(); - - expect(headlessWebView.isRunning(), false); - }); - - test('set and get custom size', () async { - final Completer controllerCompleter = Completer(); - - var headlessWebView = new HeadlessInAppWebView( - initialUrlRequest: - URLRequest(url: Uri.parse("https://github.com/flutter")), - initialSize: Size(600, 800), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - ); - - await headlessWebView.run(); - expect(headlessWebView.isRunning(), true); - - final Size? size = await headlessWebView.getSize(); - expect(size, isNotNull); - expect(size, Size(600, 800)); - - await headlessWebView.setSize(Size(1080, 1920)); - final Size? newSize = await headlessWebView.getSize(); - expect(newSize, isNotNull); - expect(newSize, Size(1080, 1920)); - - await headlessWebView.dispose(); - - expect(headlessWebView.isRunning(), false); - }); - - test('set/get options', () async { - final Completer controllerCompleter = Completer(); - final Completer pageLoaded = Completer(); - - var headlessWebView = new HeadlessInAppWebView( - initialUrlRequest: - URLRequest(url: Uri.parse("https://github.com/flutter")), - initialOptions: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions(javaScriptEnabled: false)), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - onLoadStop: (controller, url) async { - pageLoaded.complete(); - }, - ); - - await headlessWebView.run(); - final InAppWebViewController controller = - await controllerCompleter.future; - await pageLoaded.future; - - InAppWebViewGroupOptions? options = await controller.getOptions(); - expect(options, isNotNull); - expect(options!.crossPlatform.javaScriptEnabled, false); - - await controller.setOptions( - options: InAppWebViewGroupOptions( - crossPlatform: InAppWebViewOptions(javaScriptEnabled: true))); - - options = await controller.getOptions(); - expect(options, isNotNull); - expect(options!.crossPlatform.javaScriptEnabled, true); - }); - }); - - group('InAppBrowser', () { - test('openUrlRequest and close', () async { - var inAppBrowser = new MyInAppBrowser(); - expect(inAppBrowser.isOpened(), false); - expect(() async { - await inAppBrowser.show(); - }, throwsA(isInstanceOf())); - - await inAppBrowser.openUrlRequest( - urlRequest: URLRequest(url: Uri.parse("https://github.com/flutter"))); - await inAppBrowser.browserCreated.future; - expect(inAppBrowser.isOpened(), true); - expect(() async { - await inAppBrowser.openUrlRequest( - urlRequest: URLRequest(url: Uri.parse("https://flutter.dev"))); - }, throwsA(isInstanceOf())); - - await inAppBrowser.firstPageLoaded.future; - var controller = inAppBrowser.webViewController; - - final String? url = (await controller.getUrl())?.toString(); - expect(url, 'https://github.com/flutter'); - - await inAppBrowser.close(); - expect(inAppBrowser.isOpened(), false); - expect(() async => await inAppBrowser.webViewController.getUrl(), - throwsA(isInstanceOf())); - }); - - test('openFile and close', () async { - var inAppBrowser = new MyInAppBrowser(); - expect(inAppBrowser.isOpened(), false); - expect(() async { - await inAppBrowser.show(); - }, throwsA(isInstanceOf())); - - await inAppBrowser.openFile( - assetFilePath: "test_assets/in_app_webview_initial_file_test.html"); - await inAppBrowser.browserCreated.future; - expect(inAppBrowser.isOpened(), true); - expect(() async { - await inAppBrowser.openUrlRequest( - urlRequest: - URLRequest(url: Uri.parse("https://github.com/flutter"))); - }, throwsA(isInstanceOf())); - - await inAppBrowser.firstPageLoaded.future; - var controller = inAppBrowser.webViewController; - - final String? url = (await controller.getUrl())?.toString(); - expect(url, endsWith("in_app_webview_initial_file_test.html")); - - await inAppBrowser.close(); - expect(inAppBrowser.isOpened(), false); - expect(() async => await inAppBrowser.webViewController.getUrl(), - throwsA(isInstanceOf())); - }); - - test('openData and close', () async { - var inAppBrowser = new MyInAppBrowser(); - expect(inAppBrowser.isOpened(), false); - expect(() async { - await inAppBrowser.show(); - }, throwsA(isInstanceOf())); - - await inAppBrowser.openData( - data: """ - - - - - - - - - - - placeholder 100x50 - - -""", - encoding: 'utf-8', - mimeType: 'text/html', - androidHistoryUrl: Uri.parse("https://flutter.dev"), - baseUrl: Uri.parse("https://flutter.dev")); - await inAppBrowser.browserCreated.future; - expect(inAppBrowser.isOpened(), true); - expect(() async { - await inAppBrowser.openUrlRequest( - urlRequest: - URLRequest(url: Uri.parse("https://github.com/flutter"))); - }, throwsA(isInstanceOf())); - - await inAppBrowser.firstPageLoaded.future; - var controller = inAppBrowser.webViewController; - - final String? url = (await controller.getUrl())?.toString(); - expect(url, 'https://flutter.dev/'); - - await inAppBrowser.close(); - expect(inAppBrowser.isOpened(), false); - expect(() async => await inAppBrowser.webViewController.getUrl(), - throwsA(isInstanceOf())); - }); - - test('set/get options', () async { - var inAppBrowser = new MyInAppBrowser(); - await inAppBrowser.openUrlRequest( - urlRequest: URLRequest(url: Uri.parse("https://github.com/flutter")), - options: InAppBrowserClassOptions( - crossPlatform: InAppBrowserOptions(hideToolbarTop: true))); - await inAppBrowser.browserCreated.future; - await inAppBrowser.firstPageLoaded.future; - - InAppBrowserClassOptions? options = await inAppBrowser.getOptions(); - expect(options, isNotNull); - expect(options!.crossPlatform.hideToolbarTop, true); - - await inAppBrowser.setOptions( - options: InAppBrowserClassOptions( - crossPlatform: InAppBrowserOptions(hideToolbarTop: false))); - - options = await inAppBrowser.getOptions(); - expect(options, isNotNull); - expect(options!.crossPlatform.hideToolbarTop, false); - }); - }); - - group('ChromeSafariBrowser', () { - test('open and close', () async { - var chromeSafariBrowser = new MyChromeSafariBrowser(); - expect(chromeSafariBrowser.isOpened(), false); - - await chromeSafariBrowser.open( - url: Uri.parse("https://github.com/flutter")); - await chromeSafariBrowser.browserCreated.future; - expect(chromeSafariBrowser.isOpened(), true); - expect(() async { - await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); - }, throwsA(isInstanceOf())); - - await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); - await chromeSafariBrowser.close(); - await chromeSafariBrowser.browserClosed.future; - expect(chromeSafariBrowser.isOpened(), false); - }); - - test('add custom menu item', () async { - var chromeSafariBrowser = new MyChromeSafariBrowser(); - chromeSafariBrowser.addMenuItem(ChromeSafariBrowserMenuItem( - id: 2, - label: 'Custom item menu 1', - action: (url, title) { - print('Custom item menu 1 clicked!'); - })); - expect(chromeSafariBrowser.isOpened(), false); - - await chromeSafariBrowser.open( - url: Uri.parse("https://github.com/flutter")); - await chromeSafariBrowser.browserCreated.future; - expect(chromeSafariBrowser.isOpened(), true); - expect(() async { - await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); - }, throwsA(isInstanceOf())); - - await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes); - await chromeSafariBrowser.close(); - await chromeSafariBrowser.browserClosed.future; - expect(chromeSafariBrowser.isOpened(), false); - }); - - group('Android Custom Tabs', () { - test('add custom action button', () async { - var chromeSafariBrowser = new MyChromeSafariBrowser(); - var actionButtonIcon = - await rootBundle.load('test_assets/images/flutter-logo.png'); - chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton( - id: 1, - description: 'Action Button description', - icon: actionButtonIcon.buffer.asUint8List(), - action: (url, title) { - print('Action Button 1 clicked!'); - })); - expect(chromeSafariBrowser.isOpened(), false); - - await chromeSafariBrowser.open( - url: Uri.parse("https://github.com/flutter")); - await chromeSafariBrowser.browserCreated.future; - expect(chromeSafariBrowser.isOpened(), true); - expect(() async { - await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); - }, throwsA(isInstanceOf())); - - await expectLater( - chromeSafariBrowser.firstPageLoaded.future, completes); - await chromeSafariBrowser.close(); - await chromeSafariBrowser.browserClosed.future; - expect(chromeSafariBrowser.isOpened(), false); - }); - - test('Custom Tabs single instance', () async { - var chromeSafariBrowser = new MyChromeSafariBrowser(); - expect(chromeSafariBrowser.isOpened(), false); - - await chromeSafariBrowser.open( - url: Uri.parse("https://github.com/flutter"), - options: ChromeSafariBrowserClassOptions( - android: - AndroidChromeCustomTabsOptions(isSingleInstance: true))); - await chromeSafariBrowser.browserCreated.future; - expect(chromeSafariBrowser.isOpened(), true); - expect(() async { - await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); - }, throwsA(isInstanceOf())); - - await expectLater( - chromeSafariBrowser.firstPageLoaded.future, completes); - await chromeSafariBrowser.close(); - await chromeSafariBrowser.browserClosed.future; - expect(chromeSafariBrowser.isOpened(), false); - }); - - test('Trusted Web Activity', () async { - var chromeSafariBrowser = new MyChromeSafariBrowser(); - expect(chromeSafariBrowser.isOpened(), false); - - await chromeSafariBrowser.open( - url: Uri.parse("https://github.com/flutter"), - options: ChromeSafariBrowserClassOptions( - android: AndroidChromeCustomTabsOptions( - isTrustedWebActivity: true))); - await chromeSafariBrowser.browserCreated.future; - expect(chromeSafariBrowser.isOpened(), true); - expect(() async { - await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); - }, throwsA(isInstanceOf())); - - await expectLater( - chromeSafariBrowser.firstPageLoaded.future, completes); - await chromeSafariBrowser.close(); - await chromeSafariBrowser.browserClosed.future; - expect(chromeSafariBrowser.isOpened(), false); - }); - - test('Trusted Web Activity single instance', () async { - var chromeSafariBrowser = new MyChromeSafariBrowser(); - expect(chromeSafariBrowser.isOpened(), false); - - await chromeSafariBrowser.open( - url: Uri.parse("https://github.com/flutter"), - options: ChromeSafariBrowserClassOptions( - android: AndroidChromeCustomTabsOptions( - isTrustedWebActivity: true, isSingleInstance: true))); - await chromeSafariBrowser.browserCreated.future; - expect(chromeSafariBrowser.isOpened(), true); - expect(() async { - await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev")); - }, throwsA(isInstanceOf())); - - await expectLater( - chromeSafariBrowser.firstPageLoaded.future, completes); - await chromeSafariBrowser.close(); - await chromeSafariBrowser.browserClosed.future; - expect(chromeSafariBrowser.isOpened(), false); - }); - }, skip: defaultTargetPlatform != TargetPlatform.android); - }); - - group('InAppLocalhostServer', () { - final InAppLocalhostServer localhostServer = InAppLocalhostServer(); - - setUpAll(() async { - await localhostServer.start(); - }); - - testWidgets('load asset file', (WidgetTester tester) async { - expect(localhostServer.isRunning(), true); - - final Completer controllerCompleter = Completer(); - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest( - url: Uri.parse('http://localhost:8080/test_assets/index.html')), - onWebViewCreated: (controller) { - controllerCompleter.complete(controller); - }, - ), - ), - ); - final InAppWebViewController controller = - await controllerCompleter.future; - final String? currentUrl = (await controller.getUrl())?.toString(); - expect(currentUrl, 'http://localhost:8080/test_assets/index.html'); - }); - - tearDownAll(() async { - await localhostServer.close(); - }); - }); + service_worker_tests.main(); + headless_in_app_webview_tests.main(); + cookie_manager_tests.main(); + in_app_browser_tests.main(); + chrome_safari_browser_tests.main(); + in_app_localhost_server_tests.main(); } diff --git a/lib/src/in_app_webview/headless_in_app_webview.dart b/lib/src/in_app_webview/headless_in_app_webview.dart index 8cdaef19..a6354488 100644 --- a/lib/src/in_app_webview/headless_in_app_webview.dart +++ b/lib/src/in_app_webview/headless_in_app_webview.dart @@ -168,6 +168,13 @@ class HeadlessInAppWebView implements WebView { } ///Runs the headless WebView. + /// + ///**NOTE for Web**: it will append a new `iframe` to the body. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- Web Future run() async { if (_started) { return; @@ -207,6 +214,11 @@ class HeadlessInAppWebView implements WebView { } ///Disposes the headless WebView. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- Web Future dispose() async { if (!_running) { return; @@ -218,6 +230,11 @@ class HeadlessInAppWebView implements WebView { } ///Indicates if the headless WebView is running or not. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- Web bool isRunning() { return _running; } @@ -230,6 +247,11 @@ class HeadlessInAppWebView implements WebView { ///Note that if the [HeadlessInAppWebView] is not running, this method won't have effect. /// ///**NOTE for Android**: `Size` width and height values will be converted to `int` values because they cannot have `double` values. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- Web Future setSize(Size size) async { if (!_running) { return; @@ -243,6 +265,11 @@ class HeadlessInAppWebView implements WebView { ///Gets the current size in pixels of the WebView. /// ///Note that if the [HeadlessInAppWebView] is not running, this method will return `null`. + /// + ///**Supported Platforms/Implementations**: + ///- Android native WebView + ///- iOS + ///- Web Future getSize() async { if (!_running) { return null;