[webview_flutter] Update Widget Unit Tests to be platform agnostic (#4489)

diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml
index b64e1b4..4450837 100644
--- a/packages/webview_flutter/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter/pubspec.yaml
@@ -24,8 +24,10 @@
   webview_flutter_wkwebview: ^2.2.0
 
 dev_dependencies:
+  build_runner: ^2.1.5
   flutter_driver:
     sdk: flutter
   flutter_test:
     sdk: flutter
+  mockito: ^5.0.16
   pedantic: ^1.10.0
diff --git a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
index e325f68..69d4142 100644
--- a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
+++ b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
@@ -2,37 +2,47 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:math';
-import 'dart:typed_data';
-
-import 'package:flutter/services.dart';
 import 'package:flutter/src/foundation/basic_types.dart';
 import 'package:flutter/src/gestures/recognizer.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
 import 'package:webview_flutter/webview_flutter.dart';
 import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
 
+import 'webview_flutter_test.mocks.dart';
+
 typedef void VoidCallback();
 
+@GenerateMocks([WebViewPlatform, WebViewPlatformController])
 void main() {
   TestWidgetsFlutterBinding.ensureInitialized();
 
-  final _FakePlatformViewsController fakePlatformViewsController =
-      _FakePlatformViewsController();
-
-  final _FakeCookieManager _fakeCookieManager = _FakeCookieManager();
-
-  setUpAll(() {
-    SystemChannels.platform_views.setMockMethodCallHandler(
-        fakePlatformViewsController.fakePlatformViewsMethodHandler);
-    SystemChannels.platform
-        .setMockMethodCallHandler(_fakeCookieManager.onMethodCall);
-  });
+  late MockWebViewPlatform mockWebViewPlatform;
+  late MockWebViewPlatformController mockWebViewPlatformController;
 
   setUp(() {
-    fakePlatformViewsController.reset();
-    _fakeCookieManager.reset();
+    mockWebViewPlatformController = MockWebViewPlatformController();
+    mockWebViewPlatform = MockWebViewPlatform();
+    when(mockWebViewPlatform.build(
+      context: anyNamed('context'),
+      creationParams: anyNamed('creationParams'),
+      webViewPlatformCallbacksHandler:
+          anyNamed('webViewPlatformCallbacksHandler'),
+      javascriptChannelRegistry: anyNamed('javascriptChannelRegistry'),
+      onWebViewPlatformCreated: anyNamed('onWebViewPlatformCreated'),
+      gestureRecognizers: anyNamed('gestureRecognizers'),
+    )).thenAnswer((Invocation invocation) {
+      final WebViewPlatformCreatedCallback onWebViewPlatformCreated =
+          invocation.namedArguments[Symbol('onWebViewPlatformCreated')];
+      return TestPlatformWebView(
+        mockWebViewPlatformController: mockWebViewPlatformController,
+        onWebViewPlatformCreated: onWebViewPlatformCreated,
+      );
+    });
+
+    WebView.platform = mockWebViewPlatform;
   });
 
   testWidgets('Create WebView', (WidgetTester tester) async {
@@ -40,35 +50,41 @@
   });
 
   testWidgets('Initial url', (WidgetTester tester) async {
-    late WebViewController controller;
-    await tester.pumpWidget(
-      WebView(
-        initialUrl: 'https://youtube.com',
-        onWebViewCreated: (WebViewController webViewController) {
-          controller = webViewController;
-        },
-      ),
-    );
+    await tester.pumpWidget(WebView(initialUrl: 'https://youtube.com'));
 
-    expect(await controller.currentUrl(), 'https://youtube.com');
+    final CreationParams params = captureBuildArgs(
+      mockWebViewPlatform,
+      creationParams: true,
+    ).single;
+
+    expect(params.initialUrl, 'https://youtube.com');
   });
 
   testWidgets('Javascript mode', (WidgetTester tester) async {
     await tester.pumpWidget(const WebView(
-      initialUrl: 'https://youtube.com',
       javascriptMode: JavascriptMode.unrestricted,
     ));
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
+    final CreationParams unrestrictedparams = captureBuildArgs(
+      mockWebViewPlatform,
+      creationParams: true,
+    ).single;
 
-    expect(platformWebView.javascriptMode, JavascriptMode.unrestricted);
+    expect(
+      unrestrictedparams.webSettings!.javascriptMode,
+      JavascriptMode.unrestricted,
+    );
 
     await tester.pumpWidget(const WebView(
-      initialUrl: 'https://youtube.com',
       javascriptMode: JavascriptMode.disabled,
     ));
-    expect(platformWebView.javascriptMode, JavascriptMode.disabled);
+
+    final CreationParams disabledparams = captureBuildArgs(
+      mockWebViewPlatform,
+      creationParams: true,
+    ).single;
+
+    expect(disabledparams.webSettings!.javascriptMode, JavascriptMode.disabled);
   });
 
   testWidgets('Load url', (WidgetTester tester) async {
@@ -85,7 +101,10 @@
 
     await controller!.loadUrl('https://flutter.io');
 
-    expect(await controller!.currentUrl(), 'https://flutter.io');
+    verify(mockWebViewPlatformController.loadUrl(
+      'https://flutter.io',
+      argThat(isNull),
+    ));
   });
 
   testWidgets('Invalid urls', (WidgetTester tester) async {
@@ -100,14 +119,15 @@
 
     expect(controller, isNotNull);
 
-    expect(await controller!.currentUrl(), isNull);
+    final CreationParams params = captureBuildArgs(
+      mockWebViewPlatform,
+      creationParams: true,
+    ).single;
+
+    expect(params.initialUrl, isNull);
 
     expect(() => controller!.loadUrl(''), throwsA(anything));
-    expect(await controller!.currentUrl(), isNull);
-
-    // Missing schema.
     expect(() => controller!.loadUrl('flutter.io'), throwsA(anything));
-    expect(await controller!.currentUrl(), isNull);
   });
 
   testWidgets('Headers in loadUrl', (WidgetTester tester) async {
@@ -126,25 +146,11 @@
       'CACHE-CONTROL': 'ABC'
     };
     await controller!.loadUrl('https://flutter.io', headers: headers);
-    expect(await controller!.currentUrl(), equals('https://flutter.io'));
-  });
 
-  testWidgets("Can't go back before loading a page",
-      (WidgetTester tester) async {
-    WebViewController? controller;
-    await tester.pumpWidget(
-      WebView(
-        onWebViewCreated: (WebViewController webViewController) {
-          controller = webViewController;
-        },
-      ),
-    );
-
-    expect(controller, isNotNull);
-
-    final bool canGoBackNoPageLoaded = await controller!.canGoBack();
-
-    expect(canGoBackNoPageLoaded, false);
+    verify(mockWebViewPlatformController.loadUrl(
+      'https://flutter.io',
+      <String, String>{'CACHE-CONTROL': 'ABC'},
+    ));
   });
 
   testWidgets("Clear Cache", (WidgetTester tester) async {
@@ -158,31 +164,16 @@
     );
 
     expect(controller, isNotNull);
-    expect(fakePlatformViewsController.lastCreatedView!.hasCache, true);
 
     await controller!.clearCache();
 
-    expect(fakePlatformViewsController.lastCreatedView!.hasCache, false);
-  });
-
-  testWidgets("Can't go back with no history", (WidgetTester tester) async {
-    WebViewController? controller;
-    await tester.pumpWidget(
-      WebView(
-        initialUrl: 'https://flutter.io',
-        onWebViewCreated: (WebViewController webViewController) {
-          controller = webViewController;
-        },
-      ),
-    );
-
-    expect(controller, isNotNull);
-    final bool canGoBackFirstPageLoaded = await controller!.canGoBack();
-
-    expect(canGoBackFirstPageLoaded, false);
+    verify(mockWebViewPlatformController.clearCache());
   });
 
   testWidgets('Can go back', (WidgetTester tester) async {
+    when(mockWebViewPlatformController.canGoBack())
+        .thenAnswer((_) => Future<bool>.value(true));
+
     WebViewController? controller;
     await tester.pumpWidget(
       WebView(
@@ -194,15 +185,13 @@
     );
 
     expect(controller, isNotNull);
-
-    await controller!.loadUrl('https://www.google.com');
-    final bool canGoBackSecondPageLoaded = await controller!.canGoBack();
-
-    expect(canGoBackSecondPageLoaded, true);
+    expect(controller!.canGoBack(), completion(true));
   });
 
-  testWidgets("Can't go forward before loading a page",
-      (WidgetTester tester) async {
+  testWidgets("Can't go forward", (WidgetTester tester) async {
+    when(mockWebViewPlatformController.canGoForward())
+        .thenAnswer((_) => Future<bool>.value(false));
+
     WebViewController? controller;
     await tester.pumpWidget(
       WebView(
@@ -213,47 +202,7 @@
     );
 
     expect(controller, isNotNull);
-
-    final bool canGoForwardNoPageLoaded = await controller!.canGoForward();
-
-    expect(canGoForwardNoPageLoaded, false);
-  });
-
-  testWidgets("Can't go forward with no history", (WidgetTester tester) async {
-    WebViewController? controller;
-    await tester.pumpWidget(
-      WebView(
-        initialUrl: 'https://flutter.io',
-        onWebViewCreated: (WebViewController webViewController) {
-          controller = webViewController;
-        },
-      ),
-    );
-
-    expect(controller, isNotNull);
-    final bool canGoForwardFirstPageLoaded = await controller!.canGoForward();
-
-    expect(canGoForwardFirstPageLoaded, false);
-  });
-
-  testWidgets('Can go forward', (WidgetTester tester) async {
-    WebViewController? controller;
-    await tester.pumpWidget(
-      WebView(
-        initialUrl: 'https://flutter.io',
-        onWebViewCreated: (WebViewController webViewController) {
-          controller = webViewController;
-        },
-      ),
-    );
-
-    expect(controller, isNotNull);
-
-    await controller!.loadUrl('https://youtube.com');
-    await controller!.goBack();
-    final bool canGoForwardFirstPageBacked = await controller!.canGoForward();
-
-    expect(canGoForwardFirstPageBacked, true);
+    expect(controller!.canGoForward(), completion(false));
   });
 
   testWidgets('Go back', (WidgetTester tester) async {
@@ -267,17 +216,8 @@
       ),
     );
 
-    expect(controller, isNotNull);
-
-    expect(await controller!.currentUrl(), 'https://youtube.com');
-
-    await controller!.loadUrl('https://flutter.io');
-
-    expect(await controller!.currentUrl(), 'https://flutter.io');
-
     await controller!.goBack();
-
-    expect(await controller!.currentUrl(), 'https://youtube.com');
+    verify(mockWebViewPlatformController.goBack());
   });
 
   testWidgets('Go forward', (WidgetTester tester) async {
@@ -292,23 +232,14 @@
     );
 
     expect(controller, isNotNull);
-
-    expect(await controller!.currentUrl(), 'https://youtube.com');
-
-    await controller!.loadUrl('https://flutter.io');
-
-    expect(await controller!.currentUrl(), 'https://flutter.io');
-
-    await controller!.goBack();
-
-    expect(await controller!.currentUrl(), 'https://youtube.com');
-
     await controller!.goForward();
-
-    expect(await controller!.currentUrl(), 'https://flutter.io');
+    verify(mockWebViewPlatformController.goForward());
   });
 
   testWidgets('Current URL', (WidgetTester tester) async {
+    when(mockWebViewPlatformController.currentUrl())
+        .thenAnswer((_) => Future<String>.value('https://youtube.com'));
+
     WebViewController? controller;
     await tester.pumpWidget(
       WebView(
@@ -319,17 +250,6 @@
     );
 
     expect(controller, isNotNull);
-
-    // Test a WebView without an explicitly set first URL.
-    expect(await controller!.currentUrl(), isNull);
-
-    await controller!.loadUrl('https://youtube.com');
-    expect(await controller!.currentUrl(), 'https://youtube.com');
-
-    await controller!.loadUrl('https://flutter.io');
-    expect(await controller!.currentUrl(), 'https://flutter.io');
-
-    await controller!.goBack();
     expect(await controller!.currentUrl(), 'https://youtube.com');
   });
 
@@ -344,23 +264,14 @@
       ),
     );
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
-
-    expect(platformWebView.currentUrl, 'https://flutter.io');
-    expect(platformWebView.amountOfReloadsOnCurrentUrl, 0);
-
     await controller.reload();
-
-    expect(platformWebView.currentUrl, 'https://flutter.io');
-    expect(platformWebView.amountOfReloadsOnCurrentUrl, 1);
-
-    await controller.loadUrl('https://youtube.com');
-
-    expect(platformWebView.amountOfReloadsOnCurrentUrl, 0);
+    verify(mockWebViewPlatformController.reload());
   });
 
   testWidgets('evaluate Javascript', (WidgetTester tester) async {
+    when(mockWebViewPlatformController.evaluateJavascript('fake js string'))
+        .thenAnswer((_) => Future<String>.value('fake js string'));
+
     late WebViewController controller;
     await tester.pumpWidget(
       WebView(
@@ -371,10 +282,11 @@
         },
       ),
     );
+
     expect(
         // ignore: deprecated_member_use_from_same_package
-        await controller.evaluateJavascript("fake js string"),
-        "fake js string",
+        await controller.evaluateJavascript('fake js string'),
+        'fake js string',
         reason: 'should get the argument');
   });
 
@@ -409,8 +321,7 @@
       ),
     );
     await controller.runJavascript('fake js string');
-    expect(fakePlatformViewsController.lastCreatedView?.lastRunJavaScriptString,
-        'fake js string');
+    verify(mockWebViewPlatformController.runJavascript('fake js string'));
   });
 
   testWidgets('runJavaScript with JavascriptMode disabled',
@@ -432,6 +343,10 @@
   });
 
   testWidgets('runJavaScriptReturningResult', (WidgetTester tester) async {
+    when(mockWebViewPlatformController
+            .runJavascriptReturningResult('fake js string'))
+        .thenAnswer((_) => Future<String>.value('fake js string'));
+
     late WebViewController controller;
     await tester.pumpWidget(
       WebView(
@@ -442,8 +357,8 @@
         },
       ),
     );
-    expect(await controller.runJavascriptReturningResult("fake js string"),
-        "fake js string",
+    expect(await controller.runJavascriptReturningResult('fake js string'),
+        'fake js string',
         reason: 'should get the argument');
   });
 
@@ -466,18 +381,9 @@
   });
 
   testWidgets('Cookies can be cleared once', (WidgetTester tester) async {
-    await tester.pumpWidget(
-      const WebView(
-        initialUrl: 'https://flutter.io',
-      ),
-    );
-    final CookieManager cookieManager = CookieManager();
-    final bool hasCookies = await cookieManager.clearCookies();
-    expect(hasCookies, true);
-  });
+    when(mockWebViewPlatform.clearCookies())
+        .thenAnswer((_) => Future<bool>.value(true));
 
-  testWidgets('Second cookie clear does not have cookies',
-      (WidgetTester tester) async {
     await tester.pumpWidget(
       const WebView(
         initialUrl: 'https://flutter.io',
@@ -486,8 +392,6 @@
     final CookieManager cookieManager = CookieManager();
     final bool hasCookies = await cookieManager.clearCookies();
     expect(hasCookies, true);
-    final bool hasCookiesSecond = await cookieManager.clearCookies();
-    expect(hasCookiesSecond, false);
   });
 
   testWidgets('Initial JavaScript channels', (WidgetTester tester) async {
@@ -503,10 +407,12 @@
       ),
     );
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
+    final CreationParams params = captureBuildArgs(
+      mockWebViewPlatform,
+      creationParams: true,
+    ).single;
 
-    expect(platformWebView.javascriptChannelNames,
+    expect(params.javascriptChannelNames,
         unorderedEquals(<String>['Tts', 'Alarm']));
   });
 
@@ -570,11 +476,15 @@
       ),
     );
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
+    final JavascriptChannelRegistry channelRegistry = captureBuildArgs(
+      mockWebViewPlatform,
+      javascriptChannelRegistry: true,
+    ).first;
 
-    expect(platformWebView.javascriptChannelNames,
-        unorderedEquals(<String>['Tts', 'Alarm2', 'Alarm3']));
+    expect(
+      channelRegistry.channels.keys,
+      unorderedEquals(<String>['Tts', 'Alarm2', 'Alarm3']),
+    );
   });
 
   testWidgets('Remove all JavaScript channels and then add',
@@ -609,11 +519,12 @@
       ),
     );
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
+    final JavascriptChannelRegistry channelRegistry = captureBuildArgs(
+      mockWebViewPlatform,
+      javascriptChannelRegistry: true,
+    ).last;
 
-    expect(platformWebView.javascriptChannelNames,
-        unorderedEquals(<String>['Tts']));
+    expect(channelRegistry.channels.keys, unorderedEquals(<String>['Tts']));
   });
 
   testWidgets('JavaScript channel messages', (WidgetTester tester) async {
@@ -637,14 +548,16 @@
       ),
     );
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
+    final JavascriptChannelRegistry channelRegistry = captureBuildArgs(
+      mockWebViewPlatform,
+      javascriptChannelRegistry: true,
+    ).single;
 
     expect(ttsMessagesReceived, isEmpty);
     expect(alarmMessagesReceived, isEmpty);
 
-    platformWebView.fakeJavascriptPostMessage('Tts', 'Hello');
-    platformWebView.fakeJavascriptPostMessage('Tts', 'World');
+    channelRegistry.onJavascriptChannelMessage('Tts', 'Hello');
+    channelRegistry.onJavascriptChannelMessage('Tts', 'World');
 
     expect(ttsMessagesReceived, <String>['Hello', 'World']);
   });
@@ -660,12 +573,14 @@
         },
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).single;
 
-      platformWebView.fakeOnPageStartedCallback();
+      handler.onPageStarted('https://youtube.com');
 
-      expect(platformWebView.currentUrl, returnedUrl);
+      expect(returnedUrl, 'https://youtube.com');
     });
 
     testWidgets('onPageStarted is null', (WidgetTester tester) async {
@@ -674,12 +589,14 @@
         onPageStarted: null,
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).single;
 
       // The platform side will always invoke a call for onPageStarted. This is
       // to test that it does not crash on a null callback.
-      platformWebView.fakeOnPageStartedCallback();
+      handler.onPageStarted('https://youtube.com');
     });
 
     testWidgets('onPageStarted changed', (WidgetTester tester) async {
@@ -697,12 +614,13 @@
         },
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).last;
+      handler.onPageStarted('https://youtube.com');
 
-      platformWebView.fakeOnPageStartedCallback();
-
-      expect(platformWebView.currentUrl, returnedUrl);
+      expect(returnedUrl, 'https://youtube.com');
     });
   });
 
@@ -717,12 +635,13 @@
         },
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).single;
+      handler.onPageFinished('https://youtube.com');
 
-      platformWebView.fakeOnPageFinishedCallback();
-
-      expect(platformWebView.currentUrl, returnedUrl);
+      expect(returnedUrl, 'https://youtube.com');
     });
 
     testWidgets('onPageFinished is null', (WidgetTester tester) async {
@@ -731,12 +650,13 @@
         onPageFinished: null,
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
-
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).single;
       // The platform side will always invoke a call for onPageFinished. This is
       // to test that it does not crash on a null callback.
-      platformWebView.fakeOnPageFinishedCallback();
+      handler.onPageFinished('https://youtube.com');
     });
 
     testWidgets('onPageFinished changed', (WidgetTester tester) async {
@@ -754,12 +674,13 @@
         },
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).last;
+      handler.onPageFinished('https://youtube.com');
 
-      platformWebView.fakeOnPageFinishedCallback();
-
-      expect(platformWebView.currentUrl, returnedUrl);
+      expect(returnedUrl, 'https://youtube.com');
     });
   });
 
@@ -774,10 +695,11 @@
         },
       ));
 
-      final FakePlatformWebView? platformWebView =
-          fakePlatformViewsController.lastCreatedView;
-
-      platformWebView?.fakeOnProgressCallback(50);
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).single;
+      handler.onProgress(50);
 
       expect(loadingProgress, 50);
     });
@@ -788,11 +710,13 @@
         onProgress: null,
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).single;
 
       // This is to test that it does not crash on a null callback.
-      platformWebView.fakeOnProgressCallback(50);
+      handler.onProgress(50);
     });
 
     testWidgets('onLoadingProgress changed', (WidgetTester tester) async {
@@ -810,10 +734,11 @@
         },
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
-
-      platformWebView.fakeOnProgressCallback(50);
+      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
+        mockWebViewPlatform,
+        webViewPlatformCallbacksHandler: true,
+      ).last;
+      handler.onProgress(50);
 
       expect(loadingProgress, 50);
     });
@@ -825,10 +750,12 @@
         initialUrl: 'https://youtube.com',
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final CreationParams params = captureBuildArgs(
+        mockWebViewPlatform,
+        creationParams: true,
+      ).single;
 
-      expect(platformWebView.hasNavigationDelegate, false);
+      expect(params.webSettings!.hasNavigationDelegate, false);
 
       await tester.pumpWidget(WebView(
         initialUrl: 'https://youtube.com',
@@ -836,7 +763,12 @@
             NavigationDecision.navigate,
       ));
 
-      expect(platformWebView.hasNavigationDelegate, true);
+      final WebSettings updateSettings =
+          verify(mockWebViewPlatformController.updateSettings(captureAny))
+              .captured
+              .single;
+
+      expect(updateSettings.hasNavigationDelegate, true);
     });
 
     testWidgets('Block navigation', (WidgetTester tester) async {
@@ -852,22 +784,38 @@
                 : NavigationDecision.prevent;
           }));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final List<dynamic> args = captureBuildArgs(
+        mockWebViewPlatform,
+        creationParams: true,
+        webViewPlatformCallbacksHandler: true,
+      );
 
-      expect(platformWebView.hasNavigationDelegate, true);
+      final CreationParams params = args[0];
+      expect(params.webSettings!.hasNavigationDelegate, true);
 
-      platformWebView.fakeNavigate('https://www.google.com');
+      final WebViewPlatformCallbacksHandler handler = args[1];
+
       // The navigation delegate only allows navigation to https://flutter.dev
       // so we should still be in https://youtube.com.
-      expect(platformWebView.currentUrl, 'https://youtube.com');
+      expect(
+        handler.onNavigationRequest(
+          url: 'https://www.google.com',
+          isForMainFrame: true,
+        ),
+        completion(false),
+      );
+
       expect(navigationRequests.length, 1);
       expect(navigationRequests[0].url, 'https://www.google.com');
       expect(navigationRequests[0].isForMainFrame, true);
 
-      platformWebView.fakeNavigate('https://flutter.dev');
-      await tester.pump();
-      expect(platformWebView.currentUrl, 'https://flutter.dev');
+      expect(
+        handler.onNavigationRequest(
+          url: 'https://flutter.dev',
+          isForMainFrame: true,
+        ),
+        completion(true),
+      );
     });
   });
 
@@ -877,41 +825,50 @@
         debuggingEnabled: true,
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final CreationParams params = captureBuildArgs(
+        mockWebViewPlatform,
+        creationParams: true,
+      ).single;
 
-      expect(platformWebView.debuggingEnabled, true);
+      expect(params.webSettings!.debuggingEnabled, true);
     });
 
     testWidgets('defaults to false', (WidgetTester tester) async {
       await tester.pumpWidget(const WebView());
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final CreationParams params = captureBuildArgs(
+        mockWebViewPlatform,
+        creationParams: true,
+      ).single;
 
-      expect(platformWebView.debuggingEnabled, false);
+      expect(params.webSettings!.debuggingEnabled, false);
     });
 
     testWidgets('can be changed', (WidgetTester tester) async {
       final GlobalKey key = GlobalKey();
       await tester.pumpWidget(WebView(key: key));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
-
       await tester.pumpWidget(WebView(
         key: key,
         debuggingEnabled: true,
       ));
 
-      expect(platformWebView.debuggingEnabled, true);
+      final WebSettings enabledSettings =
+          verify(mockWebViewPlatformController.updateSettings(captureAny))
+              .captured
+              .last;
+      expect(enabledSettings.debuggingEnabled, true);
 
       await tester.pumpWidget(WebView(
         key: key,
         debuggingEnabled: false,
       ));
 
-      expect(platformWebView.debuggingEnabled, false);
+      final WebSettings disabledSettings =
+          verify(mockWebViewPlatformController.updateSettings(captureAny))
+              .captured
+              .last;
+      expect(disabledSettings.debuggingEnabled, false);
     });
   });
 
@@ -921,46 +878,56 @@
         zoomEnabled: true,
       ));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final CreationParams params = captureBuildArgs(
+        mockWebViewPlatform,
+        creationParams: true,
+      ).single;
 
-      expect(platformWebView.zoomEnabled, isTrue);
+      expect(params.webSettings!.zoomEnabled, isTrue);
     });
 
     testWidgets('defaults to true', (WidgetTester tester) async {
       await tester.pumpWidget(const WebView());
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
+      final CreationParams params = captureBuildArgs(
+        mockWebViewPlatform,
+        creationParams: true,
+      ).single;
 
-      expect(platformWebView.zoomEnabled, isTrue);
+      expect(params.webSettings!.zoomEnabled, isTrue);
     });
 
     testWidgets('can be changed', (WidgetTester tester) async {
       final GlobalKey key = GlobalKey();
       await tester.pumpWidget(WebView(key: key));
 
-      final FakePlatformWebView platformWebView =
-          fakePlatformViewsController.lastCreatedView!;
-
       await tester.pumpWidget(WebView(
         key: key,
         zoomEnabled: true,
       ));
 
-      expect(platformWebView.zoomEnabled, isTrue);
+      final WebSettings enabledSettings =
+          verify(mockWebViewPlatformController.updateSettings(captureAny))
+              .captured
+              .last;
+      // Zoom defaults to true, so no changes are made to settings.
+      expect(enabledSettings.zoomEnabled, isNull);
 
       await tester.pumpWidget(WebView(
         key: key,
         zoomEnabled: false,
       ));
 
-      expect(platformWebView.zoomEnabled, isFalse);
+      final WebSettings disabledSettings =
+          verify(mockWebViewPlatformController.updateSettings(captureAny))
+              .captured
+              .last;
+      expect(disabledSettings.zoomEnabled, isFalse);
     });
   });
 
   group('Custom platform implementation', () {
-    setUpAll(() {
+    setUp(() {
       WebView.platform = MyWebViewPlatform();
     });
     tearDownAll(() {
@@ -1017,16 +984,19 @@
       expect(platform.lastRequestHeaders, headers);
     });
   });
+
   testWidgets('Set UserAgent', (WidgetTester tester) async {
     await tester.pumpWidget(const WebView(
       initialUrl: 'https://youtube.com',
       javascriptMode: JavascriptMode.unrestricted,
     ));
 
-    final FakePlatformWebView platformWebView =
-        fakePlatformViewsController.lastCreatedView!;
+    final CreationParams params = captureBuildArgs(
+      mockWebViewPlatform,
+      creationParams: true,
+    ).single;
 
-    expect(platformWebView.userAgent, isNull);
+    expect(params.webSettings!.userAgent.value, isNull);
 
     await tester.pumpWidget(const WebView(
       initialUrl: 'https://youtube.com',
@@ -1034,264 +1004,74 @@
       userAgent: 'UA',
     ));
 
-    expect(platformWebView.userAgent, 'UA');
+    final WebSettings settings =
+        verify(mockWebViewPlatformController.updateSettings(captureAny))
+            .captured
+            .last;
+    expect(settings.userAgent.value, 'UA');
   });
 }
 
-class FakePlatformWebView {
-  FakePlatformWebView(int? id, Map<dynamic, dynamic> params) {
-    if (params.containsKey('initialUrl')) {
-      final String? initialUrl = params['initialUrl'];
-      if (initialUrl != null) {
-        history.add(initialUrl);
-        currentPosition++;
-      }
-    }
-    if (params.containsKey('javascriptChannelNames')) {
-      javascriptChannelNames =
-          List<String>.from(params['javascriptChannelNames']);
-    }
-    javascriptMode = JavascriptMode.values[params['settings']['jsMode']];
-    hasNavigationDelegate =
-        params['settings']['hasNavigationDelegate'] ?? false;
-    debuggingEnabled = params['settings']['debuggingEnabled'];
-    userAgent = params['settings']['userAgent'];
-    zoomEnabled = params['settings']['zoomEnabled'] ?? true;
-    channel = MethodChannel(
-        'plugins.flutter.io/webview_$id', const StandardMethodCodec());
-    channel.setMockMethodCallHandler(onMethodCall);
-  }
-
-  late MethodChannel channel;
-
-  List<String?> history = <String?>[];
-  int currentPosition = -1;
-  int amountOfReloadsOnCurrentUrl = 0;
-  bool hasCache = true;
-
-  String? get currentUrl => history.isEmpty ? null : history[currentPosition];
-  JavascriptMode? javascriptMode;
-  List<String>? javascriptChannelNames;
-
-  bool? hasNavigationDelegate;
-  bool? debuggingEnabled;
-  String? userAgent;
-  bool? zoomEnabled;
-
-  String? lastRunJavaScriptString;
-
-  Future<dynamic> onMethodCall(MethodCall call) {
-    switch (call.method) {
-      case 'loadUrl':
-        final Map<dynamic, dynamic> request = call.arguments;
-        _loadUrl(request['url']);
-        return Future<void>.sync(() {});
-      case 'updateSettings':
-        if (call.arguments['jsMode'] != null) {
-          javascriptMode = JavascriptMode.values[call.arguments['jsMode']];
-        }
-        if (call.arguments['hasNavigationDelegate'] != null) {
-          hasNavigationDelegate = call.arguments['hasNavigationDelegate'];
-        }
-        if (call.arguments['debuggingEnabled'] != null) {
-          debuggingEnabled = call.arguments['debuggingEnabled'];
-        }
-        userAgent = call.arguments['userAgent'];
-        if (call.arguments['zoomEnabled'] != null) {
-          zoomEnabled = call.arguments['zoomEnabled'];
-        }
-        break;
-      case 'canGoBack':
-        return Future<bool>.sync(() => currentPosition > 0);
-      case 'canGoForward':
-        return Future<bool>.sync(() => currentPosition < history.length - 1);
-      case 'goBack':
-        currentPosition = max(-1, currentPosition - 1);
-        return Future<void>.sync(() {});
-      case 'goForward':
-        currentPosition = min(history.length - 1, currentPosition + 1);
-        return Future<void>.sync(() {});
-      case 'reload':
-        amountOfReloadsOnCurrentUrl++;
-        return Future<void>.sync(() {});
-      case 'currentUrl':
-        return Future<String?>.value(currentUrl);
-      case 'runJavascriptReturningResult':
-      case 'evaluateJavascript':
-        lastRunJavaScriptString = call.arguments;
-        return Future<dynamic>.value(call.arguments);
-      case 'runJavascript':
-        lastRunJavaScriptString = call.arguments;
-        return Future<void>.sync(() {});
-      case 'addJavascriptChannels':
-        final List<String> channelNames = List<String>.from(call.arguments);
-        javascriptChannelNames!.addAll(channelNames);
-        break;
-      case 'removeJavascriptChannels':
-        final List<String> channelNames = List<String>.from(call.arguments);
-        javascriptChannelNames!
-            .removeWhere((String channel) => channelNames.contains(channel));
-        break;
-      case 'clearCache':
-        hasCache = false;
-        return Future<void>.sync(() {});
-    }
-    return Future<void>.sync(() {});
-  }
-
-  void fakeJavascriptPostMessage(String jsChannel, String message) {
-    final StandardMethodCodec codec = const StandardMethodCodec();
-    final Map<String, dynamic> arguments = <String, dynamic>{
-      'channel': jsChannel,
-      'message': message
-    };
-    final ByteData data = codec
-        .encodeMethodCall(MethodCall('javascriptChannelMessage', arguments));
-    _ambiguate(ServicesBinding.instance)!
-        .defaultBinaryMessenger
-        .handlePlatformMessage(channel.name, data, (ByteData? data) {});
-  }
-
-  // Fakes a main frame navigation that was initiated by the webview, e.g when
-  // the user clicks a link in the currently loaded page.
-  void fakeNavigate(String url) {
-    if (!hasNavigationDelegate!) {
-      print('no navigation delegate');
-      _loadUrl(url);
-      return;
-    }
-    final StandardMethodCodec codec = const StandardMethodCodec();
-    final Map<String, dynamic> arguments = <String, dynamic>{
-      'url': url,
-      'isForMainFrame': true
-    };
-    final ByteData data =
-        codec.encodeMethodCall(MethodCall('navigationRequest', arguments));
-    _ambiguate(ServicesBinding.instance)!
-        .defaultBinaryMessenger
-        .handlePlatformMessage(channel.name, data, (ByteData? data) {
-      final bool allow = codec.decodeEnvelope(data!);
-      if (allow) {
-        _loadUrl(url);
-      }
-    });
-  }
-
-  void fakeOnPageStartedCallback() {
-    final StandardMethodCodec codec = const StandardMethodCodec();
-
-    final ByteData data = codec.encodeMethodCall(MethodCall(
-      'onPageStarted',
-      <dynamic, dynamic>{'url': currentUrl},
-    ));
-
-    _ambiguate(ServicesBinding.instance)!
-        .defaultBinaryMessenger
-        .handlePlatformMessage(
-          channel.name,
-          data,
-          (ByteData? data) {},
-        );
-  }
-
-  void fakeOnPageFinishedCallback() {
-    final StandardMethodCodec codec = const StandardMethodCodec();
-
-    final ByteData data = codec.encodeMethodCall(MethodCall(
-      'onPageFinished',
-      <dynamic, dynamic>{'url': currentUrl},
-    ));
-
-    _ambiguate(ServicesBinding.instance)!
-        .defaultBinaryMessenger
-        .handlePlatformMessage(
-          channel.name,
-          data,
-          (ByteData? data) {},
-        );
-  }
-
-  void fakeOnProgressCallback(int progress) {
-    final StandardMethodCodec codec = const StandardMethodCodec();
-
-    final ByteData data = codec.encodeMethodCall(MethodCall(
-      'onProgress',
-      <dynamic, dynamic>{'progress': progress},
-    ));
-
-    _ambiguate(ServicesBinding.instance)!
-        .defaultBinaryMessenger
-        .handlePlatformMessage(channel.name, data, (ByteData? data) {});
-  }
-
-  void _loadUrl(String? url) {
-    history = history.sublist(0, currentPosition + 1);
-    history.add(url);
-    currentPosition++;
-    amountOfReloadsOnCurrentUrl = 0;
-  }
+List<dynamic> captureBuildArgs(
+  MockWebViewPlatform mockWebViewPlatform, {
+  bool context = false,
+  bool creationParams = false,
+  bool webViewPlatformCallbacksHandler = false,
+  bool javascriptChannelRegistry = false,
+  bool onWebViewPlatformCreated = false,
+  bool gestureRecognizers = false,
+}) {
+  return verify(mockWebViewPlatform.build(
+    context: context ? captureAnyNamed('context') : anyNamed('context'),
+    creationParams: creationParams
+        ? captureAnyNamed('creationParams')
+        : anyNamed('creationParams'),
+    webViewPlatformCallbacksHandler: webViewPlatformCallbacksHandler
+        ? captureAnyNamed('webViewPlatformCallbacksHandler')
+        : anyNamed('webViewPlatformCallbacksHandler'),
+    javascriptChannelRegistry: javascriptChannelRegistry
+        ? captureAnyNamed('javascriptChannelRegistry')
+        : anyNamed('javascriptChannelRegistry'),
+    onWebViewPlatformCreated: onWebViewPlatformCreated
+        ? captureAnyNamed('onWebViewPlatformCreated')
+        : anyNamed('onWebViewPlatformCreated'),
+    gestureRecognizers: gestureRecognizers
+        ? captureAnyNamed('gestureRecognizers')
+        : anyNamed('gestureRecognizers'),
+  )).captured;
 }
 
-class _FakePlatformViewsController {
-  FakePlatformWebView? lastCreatedView;
+// This Widget ensures that onWebViewPlatformCreated is only called once when
+// making multiple calls to `WidgetTester.pumpWidget` with different parameters
+// for the WebView.
+class TestPlatformWebView extends StatefulWidget {
+  const TestPlatformWebView({
+    Key? key,
+    required this.mockWebViewPlatformController,
+    this.onWebViewPlatformCreated,
+  }) : super(key: key);
 
-  Future<dynamic> fakePlatformViewsMethodHandler(MethodCall call) {
-    switch (call.method) {
-      case 'create':
-        final Map<dynamic, dynamic> args = call.arguments;
-        final Map<dynamic, dynamic> params = _decodeParams(args['params'])!;
-        lastCreatedView = FakePlatformWebView(
-          args['id'],
-          params,
-        );
-        return Future<int>.sync(() => 1);
-      default:
-        return Future<void>.sync(() {});
+  final MockWebViewPlatformController mockWebViewPlatformController;
+  final WebViewPlatformCreatedCallback? onWebViewPlatformCreated;
+
+  @override
+  State<StatefulWidget> createState() => TestPlatformWebViewState();
+}
+
+class TestPlatformWebViewState extends State<TestPlatformWebView> {
+  @override
+  void initState() {
+    super.initState();
+    WebViewPlatformCreatedCallback? onWebViewPlatformCreated =
+        widget.onWebViewPlatformCreated;
+    if (onWebViewPlatformCreated != null) {
+      onWebViewPlatformCreated(widget.mockWebViewPlatformController);
     }
   }
 
-  void reset() {
-    lastCreatedView = null;
-  }
-}
-
-Map<dynamic, dynamic>? _decodeParams(Uint8List paramsMessage) {
-  final ByteBuffer buffer = paramsMessage.buffer;
-  final ByteData messageBytes = buffer.asByteData(
-    paramsMessage.offsetInBytes,
-    paramsMessage.lengthInBytes,
-  );
-  return const StandardMessageCodec().decodeMessage(messageBytes);
-}
-
-class _FakeCookieManager {
-  _FakeCookieManager() {
-    final MethodChannel channel = const MethodChannel(
-      'plugins.flutter.io/cookie_manager',
-      StandardMethodCodec(),
-    );
-    channel.setMockMethodCallHandler(onMethodCall);
-  }
-
-  bool hasCookies = true;
-
-  Future<bool> onMethodCall(MethodCall call) {
-    switch (call.method) {
-      case 'clearCookies':
-        bool hadCookies = false;
-        if (hasCookies) {
-          hadCookies = true;
-          hasCookies = false;
-        }
-        return Future<bool>.sync(() {
-          return hadCookies;
-        });
-    }
-    return Future<bool>.sync(() => true);
-  }
-
-  void reset() {
-    hasCookies = true;
+  @override
+  Widget build(BuildContext context) {
+    return Container();
   }
 }
 
@@ -1381,10 +1161,3 @@
             .matches(creationParams.javascriptChannelNames, matchState);
   }
 }
-
-/// This allows a value of type T or T? to be treated as a value of type T?.
-///
-/// We use this so that APIs that have become non-nullable can still be used
-/// with `!` and `?` on the stable branch.
-// TODO(ianh): Remove this once we roll stable in late 2021.
-T? _ambiguate<T>(T? value) => value;
diff --git a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.mocks.dart b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.mocks.dart
new file mode 100644
index 0000000..b9d43cc
--- /dev/null
+++ b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.mocks.dart
@@ -0,0 +1,178 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Mocks generated by Mockito 5.0.16 from annotations
+// in webview_flutter/test/webview_flutter_test.dart.
+// Do not manually edit this file.
+
+import 'dart:async' as _i9;
+
+import 'package:flutter/foundation.dart' as _i7;
+import 'package:flutter/gestures.dart' as _i8;
+import 'package:flutter/widgets.dart' as _i2;
+import 'package:mockito/mockito.dart' as _i1;
+import 'package:webview_flutter_platform_interface/src/platform_interface/javascript_channel_registry.dart'
+    as _i6;
+import 'package:webview_flutter_platform_interface/src/platform_interface/webview_platform.dart'
+    as _i3;
+import 'package:webview_flutter_platform_interface/src/platform_interface/webview_platform_callbacks_handler.dart'
+    as _i5;
+import 'package:webview_flutter_platform_interface/src/platform_interface/webview_platform_controller.dart'
+    as _i10;
+import 'package:webview_flutter_platform_interface/src/types/types.dart' as _i4;
+
+// ignore_for_file: avoid_redundant_argument_values
+// ignore_for_file: avoid_setters_without_getters
+// ignore_for_file: comment_references
+// ignore_for_file: implementation_imports
+// ignore_for_file: invalid_use_of_visible_for_testing_member
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: unnecessary_parenthesis
+// ignore_for_file: camel_case_types
+
+class _FakeWidget_0 extends _i1.Fake implements _i2.Widget {
+  @override
+  String toString({_i2.DiagnosticLevel? minLevel = _i2.DiagnosticLevel.info}) =>
+      super.toString();
+}
+
+/// A class which mocks [WebViewPlatform].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockWebViewPlatform extends _i1.Mock implements _i3.WebViewPlatform {
+  MockWebViewPlatform() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  _i2.Widget build(
+          {_i2.BuildContext? context,
+          _i4.CreationParams? creationParams,
+          _i5.WebViewPlatformCallbacksHandler? webViewPlatformCallbacksHandler,
+          _i6.JavascriptChannelRegistry? javascriptChannelRegistry,
+          _i3.WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
+          Set<_i7.Factory<_i8.OneSequenceGestureRecognizer>>?
+              gestureRecognizers}) =>
+      (super.noSuchMethod(
+          Invocation.method(#build, [], {
+            #context: context,
+            #creationParams: creationParams,
+            #webViewPlatformCallbacksHandler: webViewPlatformCallbacksHandler,
+            #javascriptChannelRegistry: javascriptChannelRegistry,
+            #onWebViewPlatformCreated: onWebViewPlatformCreated,
+            #gestureRecognizers: gestureRecognizers
+          }),
+          returnValue: _FakeWidget_0()) as _i2.Widget);
+  @override
+  _i9.Future<bool> clearCookies() =>
+      (super.noSuchMethod(Invocation.method(#clearCookies, []),
+          returnValue: Future<bool>.value(false)) as _i9.Future<bool>);
+  @override
+  String toString() => super.toString();
+}
+
+/// A class which mocks [WebViewPlatformController].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockWebViewPlatformController extends _i1.Mock
+    implements _i10.WebViewPlatformController {
+  MockWebViewPlatformController() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  _i9.Future<void> loadUrl(String? url, Map<String, String>? headers) =>
+      (super.noSuchMethod(Invocation.method(#loadUrl, [url, headers]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<void> updateSettings(_i4.WebSettings? setting) =>
+      (super.noSuchMethod(Invocation.method(#updateSettings, [setting]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<String?> currentUrl() =>
+      (super.noSuchMethod(Invocation.method(#currentUrl, []),
+          returnValue: Future<String?>.value()) as _i9.Future<String?>);
+  @override
+  _i9.Future<bool> canGoBack() =>
+      (super.noSuchMethod(Invocation.method(#canGoBack, []),
+          returnValue: Future<bool>.value(false)) as _i9.Future<bool>);
+  @override
+  _i9.Future<bool> canGoForward() =>
+      (super.noSuchMethod(Invocation.method(#canGoForward, []),
+          returnValue: Future<bool>.value(false)) as _i9.Future<bool>);
+  @override
+  _i9.Future<void> goBack() =>
+      (super.noSuchMethod(Invocation.method(#goBack, []),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<void> goForward() =>
+      (super.noSuchMethod(Invocation.method(#goForward, []),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<void> reload() =>
+      (super.noSuchMethod(Invocation.method(#reload, []),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<void> clearCache() =>
+      (super.noSuchMethod(Invocation.method(#clearCache, []),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<String> evaluateJavascript(String? javascript) =>
+      (super.noSuchMethod(Invocation.method(#evaluateJavascript, [javascript]),
+          returnValue: Future<String>.value('')) as _i9.Future<String>);
+  @override
+  _i9.Future<void> runJavascript(String? javascript) =>
+      (super.noSuchMethod(Invocation.method(#runJavascript, [javascript]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<String> runJavascriptReturningResult(String? javascript) =>
+      (super.noSuchMethod(
+          Invocation.method(#runJavascriptReturningResult, [javascript]),
+          returnValue: Future<String>.value('')) as _i9.Future<String>);
+  @override
+  _i9.Future<void> addJavascriptChannels(Set<String>? javascriptChannelNames) =>
+      (super.noSuchMethod(
+          Invocation.method(#addJavascriptChannels, [javascriptChannelNames]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<void> removeJavascriptChannels(
+          Set<String>? javascriptChannelNames) =>
+      (super.noSuchMethod(
+          Invocation.method(
+              #removeJavascriptChannels, [javascriptChannelNames]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<String?> getTitle() =>
+      (super.noSuchMethod(Invocation.method(#getTitle, []),
+          returnValue: Future<String?>.value()) as _i9.Future<String?>);
+  @override
+  _i9.Future<void> scrollTo(int? x, int? y) =>
+      (super.noSuchMethod(Invocation.method(#scrollTo, [x, y]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<void> scrollBy(int? x, int? y) =>
+      (super.noSuchMethod(Invocation.method(#scrollBy, [x, y]),
+          returnValue: Future<void>.value(),
+          returnValueForMissingStub: Future<void>.value()) as _i9.Future<void>);
+  @override
+  _i9.Future<int> getScrollX() =>
+      (super.noSuchMethod(Invocation.method(#getScrollX, []),
+          returnValue: Future<int>.value(0)) as _i9.Future<int>);
+  @override
+  _i9.Future<int> getScrollY() =>
+      (super.noSuchMethod(Invocation.method(#getScrollY, []),
+          returnValue: Future<int>.value(0)) as _i9.Future<int>);
+  @override
+  String toString() => super.toString();
+}