import 'package:flutter/material.dart'; import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'; /// Helper class to set up WebViewPlatform for testing class WebViewTestHelper { static FakeWebViewPlatform? _instance; /// Sets up a fake WebViewPlatform instance for testing static void setUpWebViewPlatform() { _instance = FakeWebViewPlatform(); WebViewPlatform.instance = _instance!; } /// Cleans up the WebViewPlatform instance after testing /// Note: We can't set WebViewPlatform.instance to null, so we just reset our reference static void tearDownWebViewPlatform() { _instance = null; // Don't set WebViewPlatform.instance to null as it's not allowed } } /// A fake implementation of WebViewPlatform for testing class FakeWebViewPlatform extends WebViewPlatform { FakeWebViewPlatform() : super(); @override PlatformWebViewController createPlatformWebViewController( PlatformWebViewControllerCreationParams params, ) { return FakePlatformWebViewController._(params); } @override PlatformWebViewWidget createPlatformWebViewWidget( PlatformWebViewWidgetCreationParams params, ) { return FakePlatformWebViewWidget._(params); } @override PlatformNavigationDelegate createPlatformNavigationDelegate( PlatformNavigationDelegateCreationParams params, ) { return FakePlatformNavigationDelegate._(params); } } /// A fake implementation of PlatformWebViewController for testing class FakePlatformWebViewController extends PlatformWebViewController { FakePlatformWebViewController._(super.params) : super.implementation(); // Implement the methods that are actually called in tests // Using dynamic to avoid type issues with Params classes @override Future setJavaScriptMode(dynamic params) async { // No-op implementation for testing } Future setNavigationDelegate(dynamic params) async { // No-op implementation for testing } @override Future loadRequest(dynamic params) async { // No-op implementation for testing } @override Future addJavaScriptChannel(dynamic params) async { // No-op implementation for testing } @override Future removeJavaScriptChannel(dynamic params) async { // No-op implementation for testing } @override Future setBackgroundColor(dynamic params) async { // No-op implementation for testing } Future setZoomEnabled(dynamic params) async { // No-op implementation for testing } @override Future setUserAgent(dynamic params) async { // No-op implementation for testing } @override Future currentUrl() async => null; @override Future getTitle() async => ''; @override Future canGoBack() async => false; @override Future canGoForward() async => false; @override Future goBack() async {} @override Future goForward() async {} @override Future reload() async {} @override Future clearCache() async {} @override Future clearLocalStorage() async {} @override Future runJavaScript(dynamic params) async {} @override Future runJavaScriptReturningResult(dynamic params) async { return ''; } @override Future setOnConsoleMessage(dynamic params) async {} @override Future setPlatformNavigationDelegate(dynamic delegate) async { // No-op implementation for testing } } /// A fake implementation of PlatformWebViewWidget for testing class FakePlatformWebViewWidget extends PlatformWebViewWidget { FakePlatformWebViewWidget._(super.params) : super.implementation(); @override Widget build(BuildContext context) { return const SizedBox.shrink(); } } /// A fake implementation of PlatformNavigationDelegate for testing class FakePlatformNavigationDelegate extends PlatformNavigationDelegate { FakePlatformNavigationDelegate._(super.params) : super.implementation(); @override Future setOnNavigationRequest(dynamic params) async { // No-op implementation for testing } @override Future setOnPageStarted(dynamic params) async { // No-op implementation for testing } @override Future setOnPageFinished(dynamic params) async { // No-op implementation for testing } @override Future setOnWebResourceError(dynamic params) async { // No-op implementation for testing } // Implement methods that might be called @override dynamic noSuchMethod(Invocation invocation) { // Return empty futures for async methods if (invocation.memberName.toString().contains('Future')) { return Future.value(); } // Return null for other methods return null; } }