blob: 62889b0dd4af85d7526dcdc860fe115837b1f363 [file] [log] [blame]
// 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.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
import 'package:webview_flutter_wkwebview/src/foundation/foundation.dart';
import 'package:webview_flutter_wkwebview/src/web_kit/web_kit.dart';
import 'package:webview_flutter_wkwebview/src/webkit_proxy.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import 'webkit_navigation_delegate_test.mocks.dart';
@GenerateMocks(<Type>[WKWebView])
void main() {
WidgetsFlutterBinding.ensureInitialized();
group('WebKitNavigationDelegate', () {
test('WebKitNavigationDelegate uses params field in constructor', () async {
await runZonedGuarded(
() async => WebKitNavigationDelegate(
const PlatformNavigationDelegateCreationParams(),
),
(Object error, __) {
expect(error, isNot(isA<TypeError>()));
},
);
});
test('setOnPageFinished', () {
final WebKitNavigationDelegate webKitDelgate = WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
late final String callbackUrl;
webKitDelgate.setOnPageFinished((String url) => callbackUrl = url);
CapturingNavigationDelegate.lastCreatedDelegate.didFinishNavigation!(
WKWebView.detached(),
'https://www.google.com',
);
expect(callbackUrl, 'https://www.google.com');
});
test('setOnPageStarted', () {
final WebKitNavigationDelegate webKitDelgate = WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
late final String callbackUrl;
webKitDelgate.setOnPageStarted((String url) => callbackUrl = url);
CapturingNavigationDelegate
.lastCreatedDelegate.didStartProvisionalNavigation!(
WKWebView.detached(),
'https://www.google.com',
);
expect(callbackUrl, 'https://www.google.com');
});
test('onWebResourceError from didFailNavigation', () {
final WebKitNavigationDelegate webKitDelgate = WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
late final WebKitWebResourceError callbackError;
void onWebResourceError(WebResourceError error) {
callbackError = error as WebKitWebResourceError;
}
webKitDelgate.setOnWebResourceError(onWebResourceError);
CapturingNavigationDelegate.lastCreatedDelegate.didFailNavigation!(
WKWebView.detached(),
const NSError(
code: WKErrorCode.webViewInvalidated,
domain: 'domain',
localizedDescription: 'my desc',
),
);
expect(callbackError.description, 'my desc');
expect(callbackError.errorCode, WKErrorCode.webViewInvalidated);
expect(callbackError.domain, 'domain');
expect(callbackError.errorType, WebResourceErrorType.webViewInvalidated);
expect(callbackError.isForMainFrame, true);
});
test('onWebResourceError from didFailProvisionalNavigation', () {
final WebKitNavigationDelegate webKitDelgate = WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
late final WebKitWebResourceError callbackError;
void onWebResourceError(WebResourceError error) {
callbackError = error as WebKitWebResourceError;
}
webKitDelgate.setOnWebResourceError(onWebResourceError);
CapturingNavigationDelegate
.lastCreatedDelegate.didFailProvisionalNavigation!(
WKWebView.detached(),
const NSError(
code: WKErrorCode.webViewInvalidated,
domain: 'domain',
localizedDescription: 'my desc',
),
);
expect(callbackError.description, 'my desc');
expect(callbackError.errorCode, WKErrorCode.webViewInvalidated);
expect(callbackError.domain, 'domain');
expect(callbackError.errorType, WebResourceErrorType.webViewInvalidated);
expect(callbackError.isForMainFrame, true);
});
test('onWebResourceError from webViewWebContentProcessDidTerminate', () {
final WebKitNavigationDelegate webKitDelgate = WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
late final WebKitWebResourceError callbackError;
void onWebResourceError(WebResourceError error) {
callbackError = error as WebKitWebResourceError;
}
webKitDelgate.setOnWebResourceError(onWebResourceError);
CapturingNavigationDelegate
.lastCreatedDelegate.webViewWebContentProcessDidTerminate!(
WKWebView.detached(),
);
expect(callbackError.description, '');
expect(callbackError.errorCode, WKErrorCode.webContentProcessTerminated);
expect(callbackError.domain, 'WKErrorDomain');
expect(
callbackError.errorType,
WebResourceErrorType.webContentProcessTerminated,
);
expect(callbackError.isForMainFrame, true);
});
test('onNavigationRequest from decidePolicyForNavigationAction', () {
final WebKitNavigationDelegate webKitDelgate = WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
late final NavigationRequest callbackRequest;
FutureOr<NavigationDecision> onNavigationRequest(
NavigationRequest request) {
callbackRequest = request;
return NavigationDecision.navigate;
}
webKitDelgate.setOnNavigationRequest(onNavigationRequest);
expect(
CapturingNavigationDelegate
.lastCreatedDelegate.decidePolicyForNavigationAction!(
WKWebView.detached(),
const WKNavigationAction(
request: NSUrlRequest(url: 'https://www.google.com'),
targetFrame: WKFrameInfo(isMainFrame: false),
navigationType: WKNavigationType.linkActivated,
),
),
completion(WKNavigationActionPolicy.allow),
);
expect(callbackRequest.url, 'https://www.google.com');
expect(callbackRequest.isMainFrame, isFalse);
});
test('Requests to open a new window loads request in same window', () {
WebKitNavigationDelegate(
const WebKitNavigationDelegateCreationParams(
webKitProxy: WebKitProxy(
createNavigationDelegate: CapturingNavigationDelegate.new,
createUIDelegate: CapturingUIDelegate.new,
),
),
);
final MockWKWebView mockWebView = MockWKWebView();
const NSUrlRequest request = NSUrlRequest(url: 'https://www.google.com');
CapturingUIDelegate.lastCreatedDelegate.onCreateWebView!(
mockWebView,
WKWebViewConfiguration.detached(),
const WKNavigationAction(
request: request,
targetFrame: WKFrameInfo(isMainFrame: false),
navigationType: WKNavigationType.linkActivated,
),
);
verify(mockWebView.loadRequest(request));
});
});
}
// Records the last created instance of itself.
class CapturingNavigationDelegate extends WKNavigationDelegate {
CapturingNavigationDelegate({
super.didFinishNavigation,
super.didStartProvisionalNavigation,
super.didFailNavigation,
super.didFailProvisionalNavigation,
super.decidePolicyForNavigationAction,
super.webViewWebContentProcessDidTerminate,
}) : super.detached() {
lastCreatedDelegate = this;
}
static CapturingNavigationDelegate lastCreatedDelegate =
CapturingNavigationDelegate();
}
// Records the last created instance of itself.
class CapturingUIDelegate extends WKUIDelegate {
CapturingUIDelegate({super.onCreateWebView}) : super.detached() {
lastCreatedDelegate = this;
}
static CapturingUIDelegate lastCreatedDelegate = CapturingUIDelegate();
}