updated tests
This commit is contained in:
parent
9a6934cc67
commit
cae685c1b2
|
@ -1,5 +1,5 @@
|
||||||
final TEST_URL_ABOUT_BLANK = Uri.parse('about:blank');
|
final TEST_URL_ABOUT_BLANK = Uri.parse('about:blank');
|
||||||
final TEST_CROSS_PLATFORM_URL_1 = Uri.parse('https://flutter.dev');
|
final TEST_CROSS_PLATFORM_URL_1 = Uri.parse('https://flutter.dev/');
|
||||||
final TEST_CROSS_PLATFORM_URL_2 = Uri.parse('https://www.bing.com/');
|
final TEST_CROSS_PLATFORM_URL_2 = Uri.parse('https://www.bing.com/');
|
||||||
final TEST_URL_1 = Uri.parse('https://github.com/flutter');
|
final TEST_URL_1 = Uri.parse('https://github.com/flutter');
|
||||||
final TEST_URL_2 = Uri.parse('https://www.google.com/');
|
final TEST_URL_2 = Uri.parse('https://www.google.com/');
|
||||||
|
|
|
@ -8,32 +8,75 @@ import 'package:flutter_test/flutter_test.dart';
|
||||||
import '../constants.dart';
|
import '../constants.dart';
|
||||||
|
|
||||||
void initialUrlRequest() {
|
void initialUrlRequest() {
|
||||||
final shouldSkip = !kIsWeb || ![
|
final shouldSkip = !kIsWeb ||
|
||||||
TargetPlatform.android,
|
![
|
||||||
TargetPlatform.iOS,
|
TargetPlatform.android,
|
||||||
TargetPlatform.macOS,
|
TargetPlatform.iOS,
|
||||||
].contains(defaultTargetPlatform);
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
testWidgets('initialUrlRequest', (WidgetTester tester) async {
|
group('initial url request', () {
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
final shouldSkipTest1 = !kIsWeb ||
|
||||||
await tester.pumpWidget(
|
![
|
||||||
Directionality(
|
TargetPlatform.android,
|
||||||
textDirection: TextDirection.ltr,
|
TargetPlatform.iOS,
|
||||||
child: InAppWebView(
|
TargetPlatform.macOS,
|
||||||
key: GlobalKey(),
|
].contains(defaultTargetPlatform);
|
||||||
initialUrlRequest:
|
|
||||||
URLRequest(url: TEST_CROSS_PLATFORM_URL_1),
|
testWidgets('basic', (WidgetTester tester) async {
|
||||||
onWebViewCreated: (controller) {
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
controllerCompleter.complete(controller);
|
await tester.pumpWidget(
|
||||||
},
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialUrlRequest: URLRequest(url: TEST_CROSS_PLATFORM_URL_1),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
final InAppWebViewController controller =
|
final InAppWebViewController controller =
|
||||||
await controllerCompleter.future;
|
await controllerCompleter.future;
|
||||||
final String? currentUrl = (await controller.getUrl())?.toString();
|
final String? currentUrl = (await controller.getUrl())?.toString();
|
||||||
|
|
||||||
expect(currentUrl, TEST_CROSS_PLATFORM_URL_1.toString());
|
expect(currentUrl, TEST_CROSS_PLATFORM_URL_1.toString());
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkipTest1);
|
||||||
}
|
|
||||||
|
final shouldSkipTest2 = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
testWidgets('launches with allowsBackForwardNavigationGestures true',
|
||||||
|
(WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 400,
|
||||||
|
height: 300,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialUrlRequest:
|
||||||
|
URLRequest(url: TEST_URL_1),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
allowsBackForwardNavigationGestures: true),
|
||||||
|
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: shouldSkipTest2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,376 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../.env.dart';
|
||||||
|
|
||||||
|
void interceptAjaxRequest() {
|
||||||
|
final shouldSkip = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
group('intercept ajax request', () {
|
||||||
|
testWidgets('send string data', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer shouldInterceptAjaxPostRequestCompleter =
|
||||||
|
Completer<void>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialData: InAppWebViewInitialData(data: """
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>InAppWebViewAjaxTest</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>InAppWebViewAjaxTest</h1>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
||||||
|
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||||
|
xhttp.send("firstname=Foo&lastname=Bar");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
useShouldInterceptAjaxRequest: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
||||||
|
assert(ajaxRequest.data == "firstname=Foo&lastname=Bar");
|
||||||
|
|
||||||
|
ajaxRequest.responseType = 'json';
|
||||||
|
ajaxRequest.data = "firstname=Foo2&lastname=Bar2";
|
||||||
|
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
||||||
|
return ajaxRequest;
|
||||||
|
},
|
||||||
|
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
||||||
|
ajaxRequest.status == 200) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxReadyStateChangeCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
onAjaxProgress: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxProgressCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await shouldInterceptAjaxPostRequestCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
||||||
|
await onAjaxReadyStateChangeCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxProgressValue =
|
||||||
|
await onAjaxProgressCompleter.future;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
mapEquals(onAjaxReadyStateChangeValue,
|
||||||
|
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
mapEquals(
|
||||||
|
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('send json data', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer shouldInterceptAjaxPostRequestCompleter =
|
||||||
|
Completer<void>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialData: InAppWebViewInitialData(data: """
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>InAppWebViewAjaxTest</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>InAppWebViewAjaxTest</h1>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
||||||
|
var jsonData = {
|
||||||
|
firstname: 'Foo',
|
||||||
|
lastname: 'Bar'
|
||||||
|
};
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
||||||
|
xhttp.setRequestHeader("Content-type", "application/json");
|
||||||
|
xhttp.send(JSON.stringify(jsonData));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
useShouldInterceptAjaxRequest: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
||||||
|
String data = ajaxRequest.data;
|
||||||
|
assert(data.contains('"firstname":"Foo"') &&
|
||||||
|
data.contains('"lastname":"Bar"'));
|
||||||
|
|
||||||
|
ajaxRequest.responseType = 'json';
|
||||||
|
ajaxRequest.data = '{"firstname": "Foo2", "lastname": "Bar2"}';
|
||||||
|
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
||||||
|
return ajaxRequest;
|
||||||
|
},
|
||||||
|
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
||||||
|
ajaxRequest.status == 200) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxReadyStateChangeCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
onAjaxProgress: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxProgressCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await shouldInterceptAjaxPostRequestCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
||||||
|
await onAjaxReadyStateChangeCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxProgressValue =
|
||||||
|
await onAjaxProgressCompleter.future;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
mapEquals(onAjaxReadyStateChangeValue,
|
||||||
|
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
mapEquals(
|
||||||
|
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('send URLSearchParams data', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer shouldInterceptAjaxPostRequestCompleter =
|
||||||
|
Completer<void>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialData: InAppWebViewInitialData(data: """
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>InAppWebViewAjaxTest</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>InAppWebViewAjaxTest</h1>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
||||||
|
var paramsString = "firstname=Foo&lastname=Bar";
|
||||||
|
var searchParams = new URLSearchParams(paramsString);
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
||||||
|
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||||
|
xhttp.send(searchParams);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
useShouldInterceptAjaxRequest: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
||||||
|
assert(ajaxRequest.data == "firstname=Foo&lastname=Bar");
|
||||||
|
|
||||||
|
ajaxRequest.responseType = 'json';
|
||||||
|
ajaxRequest.data = "firstname=Foo2&lastname=Bar2";
|
||||||
|
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
||||||
|
return ajaxRequest;
|
||||||
|
},
|
||||||
|
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
||||||
|
ajaxRequest.status == 200) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxReadyStateChangeCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
onAjaxProgress: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxProgressCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await shouldInterceptAjaxPostRequestCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
||||||
|
await onAjaxReadyStateChangeCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxProgressValue =
|
||||||
|
await onAjaxProgressCompleter.future;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
mapEquals(onAjaxReadyStateChangeValue,
|
||||||
|
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
mapEquals(
|
||||||
|
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('send FormData', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer shouldInterceptAjaxPostRequestCompleter =
|
||||||
|
Completer<void>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
||||||
|
Completer<Map<String, dynamic>>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialData: InAppWebViewInitialData(data: """
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>InAppWebViewAjaxTest</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>InAppWebViewAjaxTest</h1>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append('firstname', 'Foo');
|
||||||
|
formData.append('lastname', 'Bar');
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
||||||
|
xhttp.send(formData);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
useShouldInterceptAjaxRequest: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
||||||
|
assert(ajaxRequest.data != null);
|
||||||
|
|
||||||
|
var body = ajaxRequest.data.cast<int>();
|
||||||
|
var bodyString = String.fromCharCodes(body);
|
||||||
|
assert(bodyString.indexOf("WebKitFormBoundary") >= 0);
|
||||||
|
|
||||||
|
ajaxRequest.data = utf8.encode(bodyString
|
||||||
|
.replaceFirst("Foo", "Foo2")
|
||||||
|
.replaceFirst("Bar", "Bar2"));
|
||||||
|
ajaxRequest.responseType = 'json';
|
||||||
|
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
||||||
|
return ajaxRequest;
|
||||||
|
},
|
||||||
|
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
||||||
|
ajaxRequest.status == 200) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxReadyStateChangeCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
onAjaxProgress: (controller, ajaxRequest) async {
|
||||||
|
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
||||||
|
Map<String, dynamic> res = ajaxRequest.response;
|
||||||
|
onAjaxProgressCompleter.complete(res);
|
||||||
|
}
|
||||||
|
return AjaxRequestAction.PROCEED;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await shouldInterceptAjaxPostRequestCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
||||||
|
await onAjaxReadyStateChangeCompleter.future;
|
||||||
|
final Map<String, dynamic> onAjaxProgressValue =
|
||||||
|
await onAjaxProgressCompleter.future;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
mapEquals(onAjaxReadyStateChangeValue,
|
||||||
|
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
expect(
|
||||||
|
mapEquals(
|
||||||
|
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
||||||
|
true);
|
||||||
|
});
|
||||||
|
}, skip: shouldSkip);
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'audio_playback_policy.dart';
|
import 'audio_playback_policy.dart';
|
||||||
import 'get_title.dart';
|
import 'get_title.dart';
|
||||||
import 'initial_url_request.dart';
|
import 'initial_url_request.dart';
|
||||||
|
import 'intercept_ajax_request.dart';
|
||||||
import 'javascript_code_evaluation.dart';
|
import 'javascript_code_evaluation.dart';
|
||||||
import 'javascript_handler.dart';
|
import 'javascript_handler.dart';
|
||||||
import 'load_file_url.dart';
|
import 'load_file_url.dart';
|
||||||
|
@ -14,6 +15,7 @@ import 'set_custom_useragent.dart';
|
||||||
import 'set_get_settings.dart';
|
import 'set_get_settings.dart';
|
||||||
import 'should_override_url_loading.dart';
|
import 'should_override_url_loading.dart';
|
||||||
import 'video_playback_policy.dart';
|
import 'video_playback_policy.dart';
|
||||||
|
import 'webview_windows.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('InAppWebView', () {
|
group('InAppWebView', () {
|
||||||
|
@ -31,5 +33,7 @@ void main() {
|
||||||
programmaticScroll();
|
programmaticScroll();
|
||||||
shouldOverrideUrlLoading();
|
shouldOverrideUrlLoading();
|
||||||
onLoadError();
|
onLoadError();
|
||||||
|
webViewWindows();
|
||||||
|
interceptAjaxRequest();
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -0,0 +1,337 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../constants.dart';
|
||||||
|
|
||||||
|
void webViewWindows() {
|
||||||
|
final shouldSkip = !kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
group("WebView Windows", () {
|
||||||
|
final shouldSkipTest1 = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
testWidgets('onCreateWindow return false', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer<void> pageLoaded = Completer<void>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialFile:
|
||||||
|
"test_assets/in_app_webview_on_create_window_test.html",
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
javaScriptCanOpenWindowsAutomatically: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
onLoadStop: (controller, url) {
|
||||||
|
if (url!.toString() == TEST_CROSS_PLATFORM_URL_1.toString()) {
|
||||||
|
pageLoaded.complete();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCreateWindow: (controller, createNavigationAction) async {
|
||||||
|
controller.loadUrl(urlRequest: createNavigationAction.request);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await expectLater(pageLoaded.future, completes);
|
||||||
|
}, skip: shouldSkipTest1);
|
||||||
|
|
||||||
|
final shouldSkipTest2 = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
testWidgets('onCreateWindow return true', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer<int> onCreateWindowCompleter = Completer<int>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialFile:
|
||||||
|
"test_assets/in_app_webview_on_create_window_test.html",
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
javaScriptCanOpenWindowsAutomatically: true,
|
||||||
|
supportMultipleWindows: true),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
onCreateWindow: (controller, createNavigationAction) async {
|
||||||
|
onCreateWindowCompleter.complete(createNavigationAction.windowId);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
var windowId = await onCreateWindowCompleter.future;
|
||||||
|
|
||||||
|
final Completer windowControllerCompleter =
|
||||||
|
Completer<InAppWebViewController>();
|
||||||
|
final Completer<String> windowPageLoaded = Completer<String>();
|
||||||
|
final Completer<void> onCloseWindowCompleter = Completer<void>();
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
windowId: windowId,
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
windowControllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
onLoadStop: (controller, url) async {
|
||||||
|
if (url!.scheme != "about" && !windowPageLoaded.isCompleted) {
|
||||||
|
windowPageLoaded.complete(url.toString());
|
||||||
|
await controller.evaluateJavascript(source: "window.close();");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCloseWindow: (controller) {
|
||||||
|
onCloseWindowCompleter.complete();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final String windowUrlLoaded = await windowPageLoaded.future;
|
||||||
|
|
||||||
|
expect(windowUrlLoaded, TEST_CROSS_PLATFORM_URL_1.toString());
|
||||||
|
await expectLater(onCloseWindowCompleter.future, completes);
|
||||||
|
}, skip: shouldSkipTest2);
|
||||||
|
|
||||||
|
final shouldSkipTest3 = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
testWidgets('window.open() with target _blank opens in same window',
|
||||||
|
(WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final StreamController<String> pageLoads =
|
||||||
|
StreamController<String>.broadcast();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
initialUrlRequest: URLRequest(url: TEST_URL_ABOUT_BLANK),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
javaScriptEnabled: true,
|
||||||
|
javaScriptCanOpenWindowsAutomatically: true),
|
||||||
|
onLoadStop: (controller, url) {
|
||||||
|
pageLoads.add(url!.toString());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await pageLoads.stream.first;
|
||||||
|
final InAppWebViewController controller =
|
||||||
|
await controllerCompleter.future;
|
||||||
|
|
||||||
|
await controller.evaluateJavascript(
|
||||||
|
source: 'window.open("$TEST_URL_ABOUT_BLANK", "_blank");');
|
||||||
|
await pageLoads.stream.first;
|
||||||
|
final String? currentUrl = (await controller.getUrl())?.toString();
|
||||||
|
expect(currentUrl, TEST_URL_ABOUT_BLANK.toString());
|
||||||
|
|
||||||
|
pageLoads.close();
|
||||||
|
}, skip: shouldSkipTest3);
|
||||||
|
|
||||||
|
final shouldSkipTest4 = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'can open new window and go back',
|
||||||
|
(WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter =
|
||||||
|
Completer<InAppWebViewController>();
|
||||||
|
final StreamController<String> pageLoads =
|
||||||
|
StreamController<String>.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);
|
||||||
|
},
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
javaScriptEnabled: true,
|
||||||
|
javaScriptCanOpenWindowsAutomatically: true,
|
||||||
|
),
|
||||||
|
onLoadStop: (controller, url) {
|
||||||
|
pageLoads.add(url!.toString());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await pageLoads.stream.first;
|
||||||
|
final InAppWebViewController controller =
|
||||||
|
await controllerCompleter.future;
|
||||||
|
|
||||||
|
await controller.evaluateJavascript(
|
||||||
|
source: 'window.open("$TEST_URL_1");');
|
||||||
|
await pageLoads.stream.first;
|
||||||
|
expect(
|
||||||
|
(await controller.getUrl())?.toString(), contains(TEST_URL_1.host));
|
||||||
|
|
||||||
|
await controller.goBack();
|
||||||
|
await pageLoads.stream.first;
|
||||||
|
expect((await controller.getUrl())?.toString(),
|
||||||
|
contains(TEST_CROSS_PLATFORM_URL_1.host));
|
||||||
|
|
||||||
|
pageLoads.close();
|
||||||
|
}, skip: shouldSkipTest4);
|
||||||
|
|
||||||
|
final shouldSkipTest5 = kIsWeb ||
|
||||||
|
![
|
||||||
|
TargetPlatform.android,
|
||||||
|
TargetPlatform.iOS,
|
||||||
|
TargetPlatform.macOS,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'javascript does not run in parent window',
|
||||||
|
(WidgetTester tester) async {
|
||||||
|
final String iframe = '''
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script>
|
||||||
|
window.onload = () => {
|
||||||
|
window.open(`javascript:
|
||||||
|
var elem = document.createElement("p");
|
||||||
|
elem.innerHTML = "<b>Executed JS in parent origin: " + window.location.origin + "</b>";
|
||||||
|
document.body.append(elem);
|
||||||
|
`);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
''';
|
||||||
|
final String iframeTestBase64 =
|
||||||
|
base64Encode(const Utf8Encoder().convert(iframe));
|
||||||
|
|
||||||
|
final String openWindowTest = '''
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>XSS test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<iframe
|
||||||
|
onload="window.iframeLoaded = true;"
|
||||||
|
src="data:text/html;charset=utf-8;base64,$iframeTestBase64"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
''';
|
||||||
|
final String openWindowTestBase64 =
|
||||||
|
base64Encode(const Utf8Encoder().convert(openWindowTest));
|
||||||
|
final Completer controllerCompleter =
|
||||||
|
Completer<InAppWebViewController>();
|
||||||
|
final Completer<void> pageLoadCompleter = Completer<void>();
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialUrlRequest: URLRequest(
|
||||||
|
url: Uri.parse(
|
||||||
|
'data:text/html;charset=utf-8;base64,$openWindowTestBase64')),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
javaScriptEnabled: true,
|
||||||
|
javaScriptCanOpenWindowsAutomatically: true,
|
||||||
|
),
|
||||||
|
onLoadStop: (controller, url) {
|
||||||
|
pageLoadCompleter.complete();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final InAppWebViewController controller =
|
||||||
|
await controllerCompleter.future;
|
||||||
|
await pageLoadCompleter.future;
|
||||||
|
|
||||||
|
expect(controller.evaluateJavascript(source: 'iframeLoaded'),
|
||||||
|
completion(true));
|
||||||
|
expect(
|
||||||
|
controller.evaluateJavascript(
|
||||||
|
source:
|
||||||
|
'document.querySelector("p") && document.querySelector("p").textContent'),
|
||||||
|
completion(null),
|
||||||
|
);
|
||||||
|
}, skip: shouldSkipTest5);
|
||||||
|
|
||||||
|
final shouldSkipTest6 = !kIsWeb;
|
||||||
|
|
||||||
|
testWidgets('onCreateWindow called on Web', (WidgetTester tester) async {
|
||||||
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
final Completer<String> onCreateWindowCalled = Completer<String>();
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: InAppWebView(
|
||||||
|
key: GlobalKey(),
|
||||||
|
initialUrlRequest: URLRequest(url: TEST_WEB_PLATFORM_URL_1),
|
||||||
|
initialSettings: InAppWebViewSettings(
|
||||||
|
clearCache: true,
|
||||||
|
javaScriptCanOpenWindowsAutomatically: true,
|
||||||
|
),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
controllerCompleter.complete(controller);
|
||||||
|
},
|
||||||
|
onCreateWindow: (controller, createNavigationAction) async {
|
||||||
|
onCreateWindowCalled.complete(createNavigationAction.request.url.toString());
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final InAppWebViewController controller = await controllerCompleter.future;
|
||||||
|
await controller.evaluateJavascript(source: "window.open('$TEST_CROSS_PLATFORM_URL_1')");
|
||||||
|
|
||||||
|
var url = await onCreateWindowCalled.future;
|
||||||
|
expect(url, TEST_CROSS_PLATFORM_URL_1.toString());
|
||||||
|
}, skip: shouldSkipTest6);
|
||||||
|
}, skip: shouldSkip);
|
||||||
|
}
|
|
@ -27,562 +27,7 @@ void main() {
|
||||||
|
|
||||||
group('InAppWebView', () {
|
group('InAppWebView', () {
|
||||||
|
|
||||||
testWidgets('launches with allowsBackForwardNavigationGestures true on iOS',
|
|
||||||
(WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: SizedBox(
|
|
||||||
width: 400,
|
|
||||||
height: 300,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialUrlRequest:
|
|
||||||
URLRequest(url: Uri.parse('https://github.com/flutter')),
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
ios: IOSInAppWebViewOptions(
|
|
||||||
allowsBackForwardNavigationGestures: true)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final InAppWebViewController controller =
|
|
||||||
await controllerCompleter.future;
|
|
||||||
final String? currentUrl = (await controller.getUrl())?.toString();
|
|
||||||
expect(currentUrl, 'https://github.com/flutter');
|
|
||||||
}, skip: defaultTargetPlatform != TargetPlatform.iOS);
|
|
||||||
|
|
||||||
testWidgets('target _blank opens in same window',
|
|
||||||
(WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
|
||||||
final StreamController<String> pageLoads =
|
|
||||||
StreamController<String>.broadcast();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
initialUrlRequest: URLRequest(url: Uri.parse("about:blank")),
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
javaScriptEnabled: true,
|
|
||||||
javaScriptCanOpenWindowsAutomatically: true),
|
|
||||||
),
|
|
||||||
onLoadStop: (controller, url) {
|
|
||||||
pageLoads.add(url!.toString());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await pageLoads.stream.first;
|
|
||||||
final InAppWebViewController controller =
|
|
||||||
await controllerCompleter.future;
|
|
||||||
|
|
||||||
await controller.evaluateJavascript(
|
|
||||||
source: 'window.open("about:blank", "_blank");');
|
|
||||||
await pageLoads.stream.first;
|
|
||||||
final String? currentUrl = (await controller.getUrl())?.toString();
|
|
||||||
expect(currentUrl, 'about:blank');
|
|
||||||
|
|
||||||
pageLoads.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets(
|
|
||||||
'can open new window and go back',
|
|
||||||
(WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final StreamController<String> pageLoads =
|
|
||||||
StreamController<String>.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);
|
|
||||||
},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
javaScriptEnabled: true,
|
|
||||||
javaScriptCanOpenWindowsAutomatically: true),
|
|
||||||
),
|
|
||||||
onLoadStop: (controller, url) {
|
|
||||||
pageLoads.add(url!.toString());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await pageLoads.stream.first;
|
|
||||||
final InAppWebViewController controller =
|
|
||||||
await controllerCompleter.future;
|
|
||||||
|
|
||||||
await controller.evaluateJavascript(
|
|
||||||
source: 'window.open("https://github.com/flutter");');
|
|
||||||
await pageLoads.stream.first;
|
|
||||||
expect((await controller.getUrl())?.toString(),
|
|
||||||
contains('github.com/flutter'));
|
|
||||||
|
|
||||||
await controller.goBack();
|
|
||||||
await pageLoads.stream.first;
|
|
||||||
expect(
|
|
||||||
(await controller.getUrl())?.toString(), contains('flutter.dev'));
|
|
||||||
|
|
||||||
pageLoads.close();
|
|
||||||
},
|
|
||||||
skip: true /* defaultTargetPlatform != TargetPlatform.android */,
|
|
||||||
);
|
|
||||||
|
|
||||||
testWidgets(
|
|
||||||
'javascript does not run in parent window',
|
|
||||||
(WidgetTester tester) async {
|
|
||||||
final String iframe = '''
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<script>
|
|
||||||
window.onload = () => {
|
|
||||||
window.open(`javascript:
|
|
||||||
var elem = document.createElement("p");
|
|
||||||
elem.innerHTML = "<b>Executed JS in parent origin: " + window.location.origin + "</b>";
|
|
||||||
document.body.append(elem);
|
|
||||||
`);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
''';
|
|
||||||
final String iframeTestBase64 =
|
|
||||||
base64Encode(const Utf8Encoder().convert(iframe));
|
|
||||||
|
|
||||||
final String openWindowTest = '''
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>XSS test</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<iframe
|
|
||||||
onload="window.iframeLoaded = true;"
|
|
||||||
src="data:text/html;charset=utf-8;base64,$iframeTestBase64"></iframe>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
''';
|
|
||||||
final String openWindowTestBase64 =
|
|
||||||
base64Encode(const Utf8Encoder().convert(openWindowTest));
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer<void> pageLoadCompleter = Completer<void>();
|
|
||||||
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialUrlRequest: URLRequest(
|
|
||||||
url: Uri.parse(
|
|
||||||
'data:text/html;charset=utf-8;base64,$openWindowTestBase64')),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
javaScriptEnabled: true,
|
|
||||||
javaScriptCanOpenWindowsAutomatically: true),
|
|
||||||
),
|
|
||||||
onLoadStop: (controller, url) {
|
|
||||||
pageLoadCompleter.complete();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final InAppWebViewController controller =
|
|
||||||
await controllerCompleter.future;
|
|
||||||
await pageLoadCompleter.future;
|
|
||||||
|
|
||||||
expect(controller.evaluateJavascript(source: 'iframeLoaded'),
|
|
||||||
completion(true));
|
|
||||||
expect(
|
|
||||||
controller.evaluateJavascript(
|
|
||||||
source:
|
|
||||||
'document.querySelector("p") && document.querySelector("p").textContent'),
|
|
||||||
completion(null),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
skip: defaultTargetPlatform != TargetPlatform.android,
|
|
||||||
);
|
|
||||||
|
|
||||||
group('intercept ajax request', () {
|
|
||||||
testWidgets('send string data', (WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer shouldInterceptAjaxPostRequestCompleter =
|
|
||||||
Completer<void>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewAjaxTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewAjaxTest</h1>
|
|
||||||
<script>
|
|
||||||
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
|
||||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
|
||||||
xhttp.send("firstname=Foo&lastname=Bar");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
useShouldInterceptAjaxRequest: true,
|
|
||||||
)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
|
||||||
assert(ajaxRequest.data == "firstname=Foo&lastname=Bar");
|
|
||||||
|
|
||||||
ajaxRequest.responseType = 'json';
|
|
||||||
ajaxRequest.data = "firstname=Foo2&lastname=Bar2";
|
|
||||||
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
|
||||||
return ajaxRequest;
|
|
||||||
},
|
|
||||||
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
|
||||||
ajaxRequest.status == 200) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxReadyStateChangeCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
onAjaxProgress: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxProgressCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await shouldInterceptAjaxPostRequestCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
|
||||||
await onAjaxReadyStateChangeCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxProgressValue =
|
|
||||||
await onAjaxProgressCompleter.future;
|
|
||||||
|
|
||||||
expect(
|
|
||||||
mapEquals(onAjaxReadyStateChangeValue,
|
|
||||||
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
expect(
|
|
||||||
mapEquals(
|
|
||||||
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('send json data', (WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer shouldInterceptAjaxPostRequestCompleter =
|
|
||||||
Completer<void>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewAjaxTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewAjaxTest</h1>
|
|
||||||
<script>
|
|
||||||
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
|
||||||
var jsonData = {
|
|
||||||
firstname: 'Foo',
|
|
||||||
lastname: 'Bar'
|
|
||||||
};
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
|
||||||
xhttp.setRequestHeader("Content-type", "application/json");
|
|
||||||
xhttp.send(JSON.stringify(jsonData));
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
useShouldInterceptAjaxRequest: true,
|
|
||||||
)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
|
||||||
String data = ajaxRequest.data;
|
|
||||||
assert(data.contains('"firstname":"Foo"') &&
|
|
||||||
data.contains('"lastname":"Bar"'));
|
|
||||||
|
|
||||||
ajaxRequest.responseType = 'json';
|
|
||||||
ajaxRequest.data = '{"firstname": "Foo2", "lastname": "Bar2"}';
|
|
||||||
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
|
||||||
return ajaxRequest;
|
|
||||||
},
|
|
||||||
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
|
||||||
ajaxRequest.status == 200) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxReadyStateChangeCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
onAjaxProgress: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxProgressCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await shouldInterceptAjaxPostRequestCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
|
||||||
await onAjaxReadyStateChangeCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxProgressValue =
|
|
||||||
await onAjaxProgressCompleter.future;
|
|
||||||
|
|
||||||
expect(
|
|
||||||
mapEquals(onAjaxReadyStateChangeValue,
|
|
||||||
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
expect(
|
|
||||||
mapEquals(
|
|
||||||
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('send URLSearchParams data', (WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer shouldInterceptAjaxPostRequestCompleter =
|
|
||||||
Completer<void>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewAjaxTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewAjaxTest</h1>
|
|
||||||
<script>
|
|
||||||
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
|
||||||
var paramsString = "firstname=Foo&lastname=Bar";
|
|
||||||
var searchParams = new URLSearchParams(paramsString);
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
|
||||||
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
|
||||||
xhttp.send(searchParams);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
useShouldInterceptAjaxRequest: true,
|
|
||||||
)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
|
||||||
assert(ajaxRequest.data == "firstname=Foo&lastname=Bar");
|
|
||||||
|
|
||||||
ajaxRequest.responseType = 'json';
|
|
||||||
ajaxRequest.data = "firstname=Foo2&lastname=Bar2";
|
|
||||||
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
|
||||||
return ajaxRequest;
|
|
||||||
},
|
|
||||||
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
|
||||||
ajaxRequest.status == 200) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxReadyStateChangeCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
onAjaxProgress: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxProgressCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await shouldInterceptAjaxPostRequestCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
|
||||||
await onAjaxReadyStateChangeCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxProgressValue =
|
|
||||||
await onAjaxProgressCompleter.future;
|
|
||||||
|
|
||||||
expect(
|
|
||||||
mapEquals(onAjaxReadyStateChangeValue,
|
|
||||||
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
expect(
|
|
||||||
mapEquals(
|
|
||||||
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('send FormData', (WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer shouldInterceptAjaxPostRequestCompleter =
|
|
||||||
Completer<void>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxReadyStateChangeCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
final Completer<Map<String, dynamic>> onAjaxProgressCompleter =
|
|
||||||
Completer<Map<String, dynamic>>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialData: InAppWebViewInitialData(data: """
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>InAppWebViewAjaxTest</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>InAppWebViewAjaxTest</h1>
|
|
||||||
<script>
|
|
||||||
window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {
|
|
||||||
var formData = new FormData();
|
|
||||||
formData.append('firstname', 'Foo');
|
|
||||||
formData.append('lastname', 'Bar');
|
|
||||||
var xhttp = new XMLHttpRequest();
|
|
||||||
xhttp.open("POST", "http://${environment["NODE_SERVER_IP"]}:8082/test-ajax-post");
|
|
||||||
xhttp.send(formData);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""),
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
useShouldInterceptAjaxRequest: true,
|
|
||||||
)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
shouldInterceptAjaxRequest: (controller, ajaxRequest) async {
|
|
||||||
assert(ajaxRequest.data != null);
|
|
||||||
|
|
||||||
var body = ajaxRequest.data.cast<int>();
|
|
||||||
var bodyString = String.fromCharCodes(body);
|
|
||||||
assert(bodyString.indexOf("WebKitFormBoundary") >= 0);
|
|
||||||
|
|
||||||
ajaxRequest.data = utf8.encode(bodyString
|
|
||||||
.replaceFirst("Foo", "Foo2")
|
|
||||||
.replaceFirst("Bar", "Bar2"));
|
|
||||||
ajaxRequest.responseType = 'json';
|
|
||||||
shouldInterceptAjaxPostRequestCompleter.complete(controller);
|
|
||||||
return ajaxRequest;
|
|
||||||
},
|
|
||||||
onAjaxReadyStateChange: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.readyState == AjaxRequestReadyState.DONE &&
|
|
||||||
ajaxRequest.status == 200) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxReadyStateChangeCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
onAjaxProgress: (controller, ajaxRequest) async {
|
|
||||||
if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) {
|
|
||||||
Map<String, dynamic> res = ajaxRequest.response;
|
|
||||||
onAjaxProgressCompleter.complete(res);
|
|
||||||
}
|
|
||||||
return AjaxRequestAction.PROCEED;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await shouldInterceptAjaxPostRequestCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxReadyStateChangeValue =
|
|
||||||
await onAjaxReadyStateChangeCompleter.future;
|
|
||||||
final Map<String, dynamic> onAjaxProgressValue =
|
|
||||||
await onAjaxProgressCompleter.future;
|
|
||||||
|
|
||||||
expect(
|
|
||||||
mapEquals(onAjaxReadyStateChangeValue,
|
|
||||||
{'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
expect(
|
|
||||||
mapEquals(
|
|
||||||
onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}),
|
|
||||||
true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('intercept fetch request', () {
|
group('intercept fetch request', () {
|
||||||
testWidgets('send string data', (WidgetTester tester) async {
|
testWidgets('send string data', (WidgetTester tester) async {
|
||||||
|
@ -1091,112 +536,7 @@ void main() {
|
||||||
expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG);
|
expect(consoleMessage.messageLevel, ConsoleMessageLevel.LOG);
|
||||||
});
|
});
|
||||||
|
|
||||||
group("WebView Windows", () {
|
|
||||||
testWidgets('onCreateWindow return false', (WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer<void> pageLoaded = Completer<void>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialFile:
|
|
||||||
"test_assets/in_app_webview_on_create_window_test.html",
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
javaScriptCanOpenWindowsAutomatically: true,
|
|
||||||
)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
onLoadStop: (controller, url) {
|
|
||||||
if (url!.toString() == "https://flutter.dev/") {
|
|
||||||
pageLoaded.complete();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCreateWindow: (controller, createNavigationAction) async {
|
|
||||||
controller.loadUrl(urlRequest: createNavigationAction.request);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await expectLater(pageLoaded.future, completes);
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('onCreateWindow return true', (WidgetTester tester) async {
|
|
||||||
final Completer controllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer<int> onCreateWindowCompleter = Completer<int>();
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
initialFile:
|
|
||||||
"test_assets/in_app_webview_on_create_window_test.html",
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
javaScriptCanOpenWindowsAutomatically: true,
|
|
||||||
),
|
|
||||||
android:
|
|
||||||
AndroidInAppWebViewOptions(supportMultipleWindows: true)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
controllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
onCreateWindow: (controller, createNavigationAction) async {
|
|
||||||
onCreateWindowCompleter
|
|
||||||
.complete(createNavigationAction.windowId);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
var windowId = await onCreateWindowCompleter.future;
|
|
||||||
|
|
||||||
final Completer windowControllerCompleter =
|
|
||||||
Completer<InAppWebViewController>();
|
|
||||||
final Completer<String> windowPageLoaded = Completer<String>();
|
|
||||||
final Completer<void> onCloseWindowCompleter = Completer<void>();
|
|
||||||
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Directionality(
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: InAppWebView(
|
|
||||||
key: GlobalKey(),
|
|
||||||
windowId: windowId,
|
|
||||||
initialOptions: InAppWebViewGroupOptions(
|
|
||||||
crossPlatform: InAppWebViewOptions(
|
|
||||||
clearCache: true,
|
|
||||||
)),
|
|
||||||
onWebViewCreated: (controller) {
|
|
||||||
windowControllerCompleter.complete(controller);
|
|
||||||
},
|
|
||||||
onLoadStop: (controller, url) async {
|
|
||||||
if (url!.scheme != "about" && !windowPageLoaded.isCompleted) {
|
|
||||||
windowPageLoaded.complete(url.toString());
|
|
||||||
await controller.evaluateJavascript(
|
|
||||||
source: "window.close();");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCloseWindow: (controller) {
|
|
||||||
onCloseWindowCompleter.complete();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
final String windowUrlLoaded = await windowPageLoaded.future;
|
|
||||||
|
|
||||||
expect(windowUrlLoaded, "https://flutter.dev/");
|
|
||||||
await expectLater(onCloseWindowCompleter.future, completes);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
testWidgets('onFindResultReceived', (WidgetTester tester) async {
|
testWidgets('onFindResultReceived', (WidgetTester tester) async {
|
||||||
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
final Completer controllerCompleter = Completer<InAppWebViewController>();
|
||||||
|
|
|
@ -204,7 +204,7 @@ abstract class WebView {
|
||||||
///Also, note that calling [InAppWebViewController.setSettings] method using the controller of the new created WebView,
|
///Also, note that calling [InAppWebViewController.setSettings] method using the controller of the new created WebView,
|
||||||
///it will update also the WebView options of the caller WebView.
|
///it will update also the WebView options of the caller WebView.
|
||||||
///
|
///
|
||||||
///**NOTE for Web**: this event will be called only if the iframe has the same origin.
|
///**NOTE for Web**: this event will be called only if the iframe has the same origin. It works only for `window.open()` javascript calls.
|
||||||
///Also, there is no way to block the opening the window in a synchronous way, so returning `true` will just close it quickly.
|
///Also, there is no way to block the opening the window in a synchronous way, so returning `true` will just close it quickly.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
|
|
Loading…
Reference in New Issue