Unverified Commit cca9592f authored by Dan Field's avatar Dan Field Committed by GitHub

NNBD integration_test (#74922)

parent 18b1e23e
...@@ -504,7 +504,7 @@ abstract class FlutterDriver { ...@@ -504,7 +504,7 @@ abstract class FlutterDriver {
/// It's expected that the application has registered a [DataHandler] /// It's expected that the application has registered a [DataHandler]
/// callback in [enableFlutterDriverExtension] that can successfully handle /// callback in [enableFlutterDriverExtension] that can successfully handle
/// these requests. /// these requests.
Future<String> requestData(String message, { Duration? timeout }) async { Future<String> requestData(String? message, { Duration? timeout }) async {
return RequestDataResult.fromJson(await sendCommand(RequestData(message, timeout: timeout))).message; return RequestDataResult.fromJson(await sendCommand(RequestData(message, timeout: timeout))).message;
} }
......
...@@ -36,7 +36,7 @@ void main() { ...@@ -36,7 +36,7 @@ void main() {
find.byWidgetPredicate( find.byWidgetPredicate(
(Widget widget) => (Widget widget) =>
widget is Text && widget is Text &&
widget.data.startsWith('Platform: ${Platform.operatingSystem}'), widget.data!.startsWith('Platform: ${Platform.operatingSystem}'),
), ),
findsOneWidget, findsOneWidget,
); );
......
...@@ -30,7 +30,7 @@ void main() { ...@@ -30,7 +30,7 @@ void main() {
find.byWidgetPredicate( find.byWidgetPredicate(
(Widget widget) => (Widget widget) =>
widget is Text && widget is Text &&
widget.data widget.data!
.startsWith('Platform: ${html.window.navigator.platform}\n'), .startsWith('Platform: ${html.window.navigator.platform}\n'),
), ),
findsOneWidget, findsOneWidget,
......
...@@ -34,7 +34,7 @@ void main() { ...@@ -34,7 +34,7 @@ void main() {
find.byWidgetPredicate( find.byWidgetPredicate(
(Widget widget) => (Widget widget) =>
widget is Text && widget is Text &&
widget.data.startsWith('Platform: ${Platform.operatingSystem}'), widget.data!.startsWith('Platform: ${Platform.operatingSystem}'),
), ),
findsOneWidget, findsOneWidget,
); );
......
...@@ -34,7 +34,7 @@ void main() { ...@@ -34,7 +34,7 @@ void main() {
find.byWidgetPredicate( find.byWidgetPredicate(
(Widget widget) => (Widget widget) =>
widget is Text && widget is Text &&
widget.data widget.data!
.startsWith('Platform: ${html.window.navigator.platform}\n'), .startsWith('Platform: ${html.window.navigator.platform}\n'),
), ),
findsOneWidget, findsOneWidget,
......
...@@ -3,7 +3,7 @@ description: Demonstrates how to use the integration_test plugin. ...@@ -3,7 +3,7 @@ description: Demonstrates how to use the integration_test plugin.
publish_to: 'none' publish_to: 'none'
environment: environment:
sdk: ">=2.1.0 <3.0.0" sdk: '>=2.12.0-0 <3.0.0'
flutter: ">=1.6.7 <2.0.0" flutter: ">=1.6.7 <2.0.0"
dependencies: dependencies:
......
...@@ -33,7 +33,7 @@ void main() { ...@@ -33,7 +33,7 @@ void main() {
await expectLater( await expectLater(
find.byWidgetPredicate( find.byWidgetPredicate(
(Widget widget) => (Widget widget) =>
widget is Text && widget.data.startsWith('This should fail'), widget is Text && widget.data!.startsWith('This should fail'),
), ),
findsOneWidget, findsOneWidget,
); );
......
...@@ -21,7 +21,7 @@ class IOCallbackManager implements CallbackManager { ...@@ -21,7 +21,7 @@ class IOCallbackManager implements CallbackManager {
@override @override
Future<Map<String, dynamic>> callback( Future<Map<String, dynamic>> callback(
Map<String, String> params, IntegrationTestResults testRunner) async { Map<String, String> params, IntegrationTestResults testRunner) async {
final String command = params['command']; final String command = params['command']!;
Map<String, String> response; Map<String, String> response;
switch (command) { switch (command) {
case 'request_data': case 'request_data':
......
...@@ -75,14 +75,13 @@ class WebCallbackManager implements CallbackManager { ...@@ -75,14 +75,13 @@ class WebCallbackManager implements CallbackManager {
@override @override
Future<Map<String, dynamic>> callback( Future<Map<String, dynamic>> callback(
Map<String, String> params, IntegrationTestResults testRunner) async { Map<String, String> params, IntegrationTestResults testRunner) async {
final String command = params['command']; final String command = params['command']!;
Map<String, String> response; Map<String, String> response;
switch (command) { switch (command) {
case 'request_data': case 'request_data':
return params['message'] == null return params['message'] == null
? _requestData(testRunner) ? _requestData(testRunner)
: _requestDataWithMessage(params['message'], testRunner); : _requestDataWithMessage(params['message']!, testRunner);
break;
case 'get_health': case 'get_health':
response = <String, String>{'status': 'ok'}; response = <String, String>{'status': 'ok'};
break; break;
......
...@@ -21,7 +21,7 @@ class Response { ...@@ -21,7 +21,7 @@ class Response {
: _allTestsPassed = false; : _allTestsPassed = false;
/// Constructor for failure response. /// Constructor for failure response.
Response.toolException({String ex}) Response.toolException({String? ex})
: _allTestsPassed = false, : _allTestsPassed = false,
_failureDetails = <Failure>[Failure('ToolException', ex)]; _failureDetails = <Failure>[Failure('ToolException', ex)];
...@@ -30,22 +30,22 @@ class Response { ...@@ -30,22 +30,22 @@ class Response {
: _allTestsPassed = false, : _allTestsPassed = false,
_failureDetails = null; _failureDetails = null;
final List<Failure> _failureDetails; final List<Failure>? _failureDetails;
final bool _allTestsPassed; final bool _allTestsPassed;
/// The extra information to be added along side the test result. /// The extra information to be added along side the test result.
Map<String, dynamic> data; Map<String, dynamic>? data;
/// Whether the test ran successfully or not. /// Whether the test ran successfully or not.
bool get allTestsPassed => _allTestsPassed; bool get allTestsPassed => _allTestsPassed;
/// If the result are failures get the formatted details. /// If the result are failures get the formatted details.
String get formattedFailureDetails => String get formattedFailureDetails =>
_allTestsPassed ? '' : formatFailures(_failureDetails); _allTestsPassed ? '' : formatFailures(_failureDetails!);
/// Failure details as a list. /// Failure details as a list.
List<Failure> get failureDetails => _failureDetails; List<Failure>? get failureDetails => _failureDetails;
/// Serializes this message to a JSON map. /// Serializes this message to a JSON map.
String toJson() => json.encode(<String, dynamic>{ String toJson() => json.encode(<String, dynamic>{
...@@ -57,7 +57,7 @@ class Response { ...@@ -57,7 +57,7 @@ class Response {
/// Deserializes the result from JSON. /// Deserializes the result from JSON.
static Response fromJson(String source) { static Response fromJson(String source) {
final Map<String, dynamic> responseJson = json.decode(source) as Map<String, dynamic>; final Map<String, dynamic> responseJson = json.decode(source) as Map<String, dynamic>;
if (responseJson['result'] as String == 'true') { if ((responseJson['result'] as String?) == 'true') {
return Response.allTestsPassed(data: responseJson['data'] as Map<String, dynamic>); return Response.allTestsPassed(data: responseJson['data'] as Map<String, dynamic>);
} else { } else {
return Response.someTestsFailed( return Response.someTestsFailed(
...@@ -87,11 +87,11 @@ class Response { ...@@ -87,11 +87,11 @@ class Response {
/// Create a list of Strings from [_failureDetails]. /// Create a list of Strings from [_failureDetails].
List<String> _failureDetailsAsString() { List<String> _failureDetailsAsString() {
final List<String> list = <String>[]; final List<String> list = <String>[];
if (_failureDetails == null || _failureDetails.isEmpty) { if (_failureDetails == null || _failureDetails!.isEmpty) {
return list; return list;
} }
for (final Failure failure in _failureDetails) { for (final Failure failure in _failureDetails!) {
list.add(failure.toJson()); list.add(failure.toJson());
} }
...@@ -115,11 +115,11 @@ class Failure { ...@@ -115,11 +115,11 @@ class Failure {
final String methodName; final String methodName;
/// The details of the failure such as stack trace. /// The details of the failure such as stack trace.
final String details; final String? details;
/// Serializes the object to JSON. /// Serializes the object to JSON.
String toJson() { String toJson() {
return json.encode(<String, String>{ return json.encode(<String, String?>{
'methodName': methodName, 'methodName': methodName,
'details': details, 'details': details,
}); });
...@@ -131,7 +131,7 @@ class Failure { ...@@ -131,7 +131,7 @@ class Failure {
/// Decode a JSON string to create a Failure object. /// Decode a JSON string to create a Failure object.
static Failure fromJsonString(String jsonString) { static Failure fromJsonString(String jsonString) {
final Map<String, dynamic> failure = json.decode(jsonString) as Map<String, dynamic>; final Map<String, dynamic> failure = json.decode(jsonString) as Map<String, dynamic>;
return Failure(failure['methodName'] as String, failure['details'] as String); return Failure(failure['methodName'] as String, failure['details'] as String?);
} }
} }
...@@ -291,7 +291,7 @@ abstract class IntegrationTestResults { ...@@ -291,7 +291,7 @@ abstract class IntegrationTestResults {
List<Failure> get failureMethodsDetails; List<Failure> get failureMethodsDetails;
/// The extra data for the reported result. /// The extra data for the reported result.
Map<String, dynamic> get reportData; Map<String, dynamic>? get reportData;
/// Whether all the test methods completed succesfully. /// Whether all the test methods completed succesfully.
Completer<bool> get allTestsPassed; Completer<bool> get allTestsPassed;
......
...@@ -41,7 +41,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -41,7 +41,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
await _channel.invokeMethod<void>( await _channel.invokeMethod<void>(
'allTestsFinished', 'allTestsFinished',
<String, dynamic>{ <String, dynamic>{
'results': results.map((String name, Object result) { 'results': results.map<String, dynamic>((String name, Object result) {
if (result is Failure) { if (result is Failure) {
return MapEntry<String, dynamic>(name, result.details); return MapEntry<String, dynamic>(name, result.details);
} }
...@@ -76,7 +76,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -76,7 +76,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
@override @override
bool get registerTestTextInput => false; bool get registerTestTextInput => false;
Size _surfaceSize; Size? _surfaceSize;
// This flag is used to print warning messages when tracking performance // This flag is used to print warning messages when tracking performance
// under debug mode. // under debug mode.
...@@ -87,7 +87,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -87,7 +87,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
/// ///
/// Set to null to use the default surface size. /// Set to null to use the default surface size.
@override @override
Future<void> setSurfaceSize(Size size) { Future<void> setSurfaceSize(Size? size) {
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
assert(inTest); assert(inTest);
if (_surfaceSize == size) { if (_surfaceSize == size) {
...@@ -124,7 +124,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -124,7 +124,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
IntegrationTestWidgetsFlutterBinding(); IntegrationTestWidgetsFlutterBinding();
} }
assert(WidgetsBinding.instance is IntegrationTestWidgetsFlutterBinding); assert(WidgetsBinding.instance is IntegrationTestWidgetsFlutterBinding);
return WidgetsBinding.instance; return WidgetsBinding.instance!;
} }
static const MethodChannel _channel = static const MethodChannel _channel =
...@@ -146,7 +146,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -146,7 +146,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
/// ///
/// The default value is `null`. /// The default value is `null`.
@override @override
Map<String, dynamic> reportData; Map<String, dynamic>? reportData;
/// Manages callbacks received from driver side and commands send to driver /// Manages callbacks received from driver side and commands send to driver
/// side. /// side.
...@@ -183,7 +183,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -183,7 +183,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
Future<void> testBody(), Future<void> testBody(),
VoidCallback invariantTester, { VoidCallback invariantTester, {
String description = '', String description = '',
Duration timeout, Duration? timeout,
}) async { }) async {
await super.runTest( await super.runTest(
testBody, testBody,
...@@ -194,15 +194,15 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -194,15 +194,15 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
results[description] ??= _success; results[description] ??= _success;
} }
vm.VmService _vmService; vm.VmService? _vmService;
/// Initialize the [vm.VmService] settings for the timeline. /// Initialize the [vm.VmService] settings for the timeline.
@visibleForTesting @visibleForTesting
Future<void> enableTimeline({ Future<void> enableTimeline({
List<String> streams = const <String>['all'], List<String> streams = const <String>['all'],
@visibleForTesting vm.VmService vmService, @visibleForTesting vm.VmService? vmService,
}) async { }) async {
assert(streams != null); assert(streams != null); // ignore: unnecessary_null_comparison
assert(streams.isNotEmpty); assert(streams.isNotEmpty);
if (vmService != null) { if (vmService != null) {
_vmService = vmService; _vmService = vmService;
...@@ -212,10 +212,10 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -212,10 +212,10 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
await developer.Service.getInfo(); await developer.Service.getInfo();
assert(info.serverUri != null); assert(info.serverUri != null);
_vmService = await vm_io.vmServiceConnectUri( _vmService = await vm_io.vmServiceConnectUri(
'ws://localhost:${info.serverUri.port}${info.serverUri.path}ws', 'ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws',
); );
} }
await _vmService.setVMTimelineFlags(streams); await _vmService!.setVMTimelineFlags(streams);
} }
/// Runs [action] and returns a [vm.Timeline] trace for it. /// Runs [action] and returns a [vm.Timeline] trace for it.
...@@ -239,14 +239,14 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -239,14 +239,14 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
await enableTimeline(streams: streams); await enableTimeline(streams: streams);
if (retainPriorEvents) { if (retainPriorEvents) {
await action(); await action();
return await _vmService.getVMTimeline(); return await _vmService!.getVMTimeline();
} }
await _vmService.clearVMTimeline(); await _vmService!.clearVMTimeline();
final vm.Timestamp startTime = await _vmService.getVMTimelineMicros(); final vm.Timestamp startTime = await _vmService!.getVMTimelineMicros();
await action(); await action();
final vm.Timestamp endTime = await _vmService.getVMTimelineMicros(); final vm.Timestamp endTime = await _vmService!.getVMTimelineMicros();
return await _vmService.getVMTimeline( return await _vmService!.getVMTimeline(
timeOriginMicros: startTime.timestamp, timeOriginMicros: startTime.timestamp,
timeExtentMicros: endTime.timestamp, timeExtentMicros: endTime.timestamp,
); );
...@@ -279,7 +279,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -279,7 +279,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
retainPriorEvents: retainPriorEvents, retainPriorEvents: retainPriorEvents,
); );
reportData ??= <String, dynamic>{}; reportData ??= <String, dynamic>{};
reportData[reportKey] = timeline.toJson(); reportData![reportKey] = timeline.toJson();
} }
/// Watches the [FrameTiming] during `action` and report it to the binding /// Watches the [FrameTiming] during `action` and report it to the binding
...@@ -317,7 +317,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -317,7 +317,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
final FrameTimingSummarizer frameTimes = final FrameTimingSummarizer frameTimes =
FrameTimingSummarizer(frameTimings); FrameTimingSummarizer(frameTimings);
reportData ??= <String, dynamic>{}; reportData ??= <String, dynamic>{};
reportData[reportKey] = frameTimes.summary; reportData![reportKey] = frameTimes.summary;
} }
@override @override
...@@ -327,7 +327,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding ...@@ -327,7 +327,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
/// ///
/// See [TestWidgetsFlutterBinding.defaultTestTimeout] for more details. /// See [TestWidgetsFlutterBinding.defaultTestTimeout] for more details.
set defaultTestTimeout(Timeout timeout) => _defaultTestTimeout = timeout; set defaultTestTimeout(Timeout timeout) => _defaultTestTimeout = timeout;
Timeout _defaultTestTimeout; Timeout? _defaultTestTimeout;
@override @override
void attachRootWidget(Widget rootWidget) { void attachRootWidget(Widget rootWidget) {
......
...@@ -21,18 +21,18 @@ String testOutputsDirectory = ...@@ -21,18 +21,18 @@ String testOutputsDirectory =
/// The callback type to handle [Response.data] after the test /// The callback type to handle [Response.data] after the test
/// succeeds. /// succeeds.
typedef ResponseDataCallback = FutureOr<void> Function(Map<String, dynamic>); typedef ResponseDataCallback = FutureOr<void> Function(Map<String, dynamic>?);
/// Writes a json-serializable json data to to /// Writes a json-serializable json data to to
/// [testOutputsDirectory]/`testOutputFilename.json`. /// [testOutputsDirectory]/`testOutputFilename.json`.
/// ///
/// This is the default `responseDataCallback` in [integrationDriver]. /// This is the default `responseDataCallback` in [integrationDriver].
Future<void> writeResponseData( Future<void> writeResponseData(
Map<String, dynamic> data, { Map<String, dynamic>? data, {
String testOutputFilename = 'integration_response_data', String testOutputFilename = 'integration_response_data',
String destinationDirectory, String? destinationDirectory,
}) async { }) async {
assert(testOutputFilename != null); assert(testOutputFilename != null); // ignore: unnecessary_null_comparison
destinationDirectory ??= testOutputsDirectory; destinationDirectory ??= testOutputsDirectory;
await fs.directory(destinationDirectory).create(recursive: true); await fs.directory(destinationDirectory).create(recursive: true);
final File file = fs.file(path.join( final File file = fs.file(path.join(
...@@ -65,7 +65,7 @@ Future<void> writeResponseData( ...@@ -65,7 +65,7 @@ Future<void> writeResponseData(
/// ``` /// ```
Future<void> integrationDriver({ Future<void> integrationDriver({
Duration timeout = const Duration(minutes: 1), Duration timeout = const Duration(minutes: 1),
ResponseDataCallback responseDataCallback = writeResponseData, ResponseDataCallback? responseDataCallback = writeResponseData,
}) async { }) async {
final FlutterDriver driver = await FlutterDriver.connect(); final FlutterDriver driver = await FlutterDriver.connect();
final String jsonResult = await driver.requestData(null, timeout: timeout); final String jsonResult = await driver.requestData(null, timeout: timeout);
...@@ -86,6 +86,6 @@ Future<void> integrationDriver({ ...@@ -86,6 +86,6 @@ Future<void> integrationDriver({
const JsonEncoder _prettyEncoder = JsonEncoder.withIndent(' '); const JsonEncoder _prettyEncoder = JsonEncoder.withIndent(' ');
String _encodeJson(Map<String, dynamic> jsonObject, bool pretty) { String _encodeJson(Map<String, dynamic>? jsonObject, bool pretty) {
return pretty ? _prettyEncoder.convert(jsonObject) : json.encode(jsonObject); return pretty ? _prettyEncoder.convert(jsonObject) : json.encode(jsonObject);
} }
...@@ -12,7 +12,7 @@ import 'common.dart'; ...@@ -12,7 +12,7 @@ import 'common.dart';
/// Example Integration Test which can also run WebDriver command depending on /// Example Integration Test which can also run WebDriver command depending on
/// the requests coming from the test methods. /// the requests coming from the test methods.
Future<void> integrationDriver( Future<void> integrationDriver(
{FlutterDriver driver, Function onScreenshot}) async { {FlutterDriver? driver, Function? onScreenshot}) async {
driver ??= await FlutterDriver.connect(); driver ??= await FlutterDriver.connect();
// Test states that it's waiting on web driver commands. // Test states that it's waiting on web driver commands.
// [DriverTestMessage] is converted to string since json format causes an // [DriverTestMessage] is converted to string since json format causes an
...@@ -24,15 +24,15 @@ Future<void> integrationDriver( ...@@ -24,15 +24,15 @@ Future<void> integrationDriver(
// Until `integration_test` returns a [WebDriverCommandType.noop], keep // Until `integration_test` returns a [WebDriverCommandType.noop], keep
// executing WebDriver commands. // executing WebDriver commands.
while (response.data != null && while (response.data != null &&
response.data['web_driver_command'] != null && response.data!['web_driver_command'] != null &&
response.data['web_driver_command'] != '${WebDriverCommandType.noop}') { response.data!['web_driver_command'] != '${WebDriverCommandType.noop}') {
final String webDriverCommand = response.data['web_driver_command'] as String; final String? webDriverCommand = response.data!['web_driver_command'] as String?;
if (webDriverCommand == '${WebDriverCommandType.screenshot}') { if (webDriverCommand == '${WebDriverCommandType.screenshot}') {
// Use `driver.screenshot()` method to get a screenshot of the web page. // Use `driver.screenshot()` method to get a screenshot of the web page.
final List<int> screenshotImage = await driver.screenshot(); final List<int> screenshotImage = await driver.screenshot();
final String screenshotName = response.data['screenshot_name'] as String; final String? screenshotName = response.data!['screenshot_name'] as String?;
final bool screenshotSuccess = await onScreenshot(screenshotName, screenshotImage) as bool; final bool screenshotSuccess = await onScreenshot!(screenshotName, screenshotImage) as bool;
if (screenshotSuccess) { if (screenshotSuccess) {
jsonResponse = await driver.requestData(DriverTestMessage.complete().toString()); jsonResponse = await driver.requestData(DriverTestMessage.complete().toString());
} else { } else {
...@@ -54,9 +54,9 @@ Future<void> integrationDriver( ...@@ -54,9 +54,9 @@ Future<void> integrationDriver(
// If No-op command is sent, ask for the result of all tests. // If No-op command is sent, ask for the result of all tests.
if (response.data != null && if (response.data != null &&
response.data['web_driver_command'] != null && response.data!['web_driver_command'] != null &&
response.data['web_driver_command'] == '${WebDriverCommandType.noop}') { response.data!['web_driver_command'] == '${WebDriverCommandType.noop}') {
jsonResponse = await driver.requestData(null); jsonResponse = await driver.requestData('');
response = Response.fromJson(jsonResponse); response = Response.fromJson(jsonResponse);
print('result $jsonResponse'); print('result $jsonResponse');
......
name: integration_test name: integration_test
description: Runs tests that use the flutter_test API as integration tests. description: Runs tests that use the flutter_test API as integration tests.
version: 0.9.2+2
publish_to: none publish_to: none
homepage: https://github.com/flutter/plugins/tree/master/packages/integration_test
environment: environment:
sdk: ">=2.10.0-0.0.dev <3.0.0" sdk: '>=2.12.0-0 <3.0.0'
dependencies: dependencies:
flutter: flutter:
......
...@@ -18,7 +18,7 @@ const String _failureExcerpt = r'Expected: <false>\n Actual: <true>'; ...@@ -18,7 +18,7 @@ const String _failureExcerpt = r'Expected: <false>\n Actual: <true>';
Future<void> main() async { Future<void> main() async {
group('Integration binding result', () { group('Integration binding result', () {
test('when multiple tests pass', () async { test('when multiple tests pass', () async {
final Map<String, dynamic> results = await _runTest(path.join('test', 'data', 'pass_test_script.dart')); final Map<String, dynamic>? results = await _runTest(path.join('test', 'data', 'pass_test_script.dart'));
expect( expect(
results, results,
...@@ -29,7 +29,7 @@ Future<void> main() async { ...@@ -29,7 +29,7 @@ Future<void> main() async {
}); });
test('when multiple tests fail', () async { test('when multiple tests fail', () async {
final Map<String, dynamic> results = await _runTest(path.join('test', 'data', 'fail_test_script.dart')); final Map<String, dynamic>? results = await _runTest(path.join('test', 'data', 'fail_test_script.dart'));
expect(results, hasLength(2)); expect(results, hasLength(2));
expect(results, containsPair('failing test 1', contains(_failureExcerpt))); expect(results, containsPair('failing test 1', contains(_failureExcerpt)));
...@@ -37,7 +37,7 @@ Future<void> main() async { ...@@ -37,7 +37,7 @@ Future<void> main() async {
}); });
test('when one test passes, then another fails', () async { test('when one test passes, then another fails', () async {
final Map<String, dynamic> results = await _runTest(path.join('test', 'data', 'pass_then_fail_test_script.dart')); final Map<String, dynamic>? results = await _runTest(path.join('test', 'data', 'pass_then_fail_test_script.dart'));
expect(results, hasLength(2)); expect(results, hasLength(2));
expect(results, containsPair('passing test', equals('success'))); expect(results, containsPair('passing test', equals('success')));
...@@ -49,7 +49,7 @@ Future<void> main() async { ...@@ -49,7 +49,7 @@ Future<void> main() async {
/// Runs a test script and returns the [IntegrationTestWidgetsFlutterBinding.result]. /// Runs a test script and returns the [IntegrationTestWidgetsFlutterBinding.result].
/// ///
/// [scriptPath] is relative to the package root. /// [scriptPath] is relative to the package root.
Future<Map<String, dynamic>> _runTest(String scriptPath) async { Future<Map<String, dynamic>?> _runTest(String scriptPath) async {
final Process process = final Process process =
await Process.start(_flutterBin, <String>['test', '--machine', scriptPath]); await Process.start(_flutterBin, <String>['test', '--machine', scriptPath]);
...@@ -63,7 +63,7 @@ Future<Map<String, dynamic>> _runTest(String scriptPath) async { ...@@ -63,7 +63,7 @@ Future<Map<String, dynamic>> _runTest(String scriptPath) async {
.expand((String text) => text.split('\n')) .expand((String text) => text.split('\n'))
.map<dynamic>((String line) { .map<dynamic>((String line) {
try { try {
return jsonDecode(line); return jsonDecode(line) as Map<String, dynamic>?;
} on FormatException { } on FormatException {
// Only interested in test events which are JSON. // Only interested in test events which are JSON.
} }
...@@ -73,12 +73,12 @@ Future<Map<String, dynamic>> _runTest(String scriptPath) async { ...@@ -73,12 +73,12 @@ Future<Map<String, dynamic>> _runTest(String scriptPath) async {
? json.cast() ? json.cast()
: <Map<String, dynamic>>[json as Map<String, dynamic>]; : <Map<String, dynamic>>[json as Map<String, dynamic>];
}) })
.where((Map<String, dynamic> testEvent) => .where((Map<String, dynamic>? testEvent) =>
testEvent != null && testEvent['type'] == 'print') testEvent != null && testEvent['type'] == 'print')
.map((Map<String, dynamic> printEvent) => printEvent['message'] as String) .map((Map<String, dynamic>? printEvent) => printEvent!['message'] as String?)
.firstWhere((String message) => .firstWhere((String? message) =>
message.startsWith(_integrationResultsPrefix))) message!.startsWith(_integrationResultsPrefix)))!
.replaceAll(_integrationResultsPrefix, ''); .replaceAll(_integrationResultsPrefix, '');
return jsonDecode(testResults) as Map<String, dynamic>; return jsonDecode(testResults) as Map<String, dynamic>?;
} }
...@@ -18,14 +18,14 @@ vm.Timeline _kTimelines = vm.Timeline( ...@@ -18,14 +18,14 @@ vm.Timeline _kTimelines = vm.Timeline(
); );
Future<void> main() async { Future<void> main() async {
Future<Map<String, dynamic>> request; Future<Map<String, dynamic>>? request;
group('Test Integration binding', () { group('Test Integration binding', () {
final WidgetsBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized(); final WidgetsBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
assert(binding is IntegrationTestWidgetsFlutterBinding); assert(binding is IntegrationTestWidgetsFlutterBinding);
final IntegrationTestWidgetsFlutterBinding integrationBinding = binding as IntegrationTestWidgetsFlutterBinding; final IntegrationTestWidgetsFlutterBinding integrationBinding = binding as IntegrationTestWidgetsFlutterBinding;
FakeVM fakeVM; FakeVM? fakeVM;
setUp(() { setUp(() {
request = integrationBinding.callback(<String, String>{ request = integrationBinding.callback(<String, String>{
...@@ -74,9 +74,9 @@ Future<void> main() async { ...@@ -74,9 +74,9 @@ Future<void> main() async {
await integrationBinding.enableTimeline(vmService: fakeVM); await integrationBinding.enableTimeline(vmService: fakeVM);
await integrationBinding.traceAction(() async {}); await integrationBinding.traceAction(() async {});
expect(integrationBinding.reportData, isNotNull); expect(integrationBinding.reportData, isNotNull);
expect(integrationBinding.reportData.containsKey('timeline'), true); expect(integrationBinding.reportData!.containsKey('timeline'), true);
expect( expect(
json.encode(integrationBinding.reportData['timeline']), json.encode(integrationBinding.reportData!['timeline']),
json.encode(_kTimelines), json.encode(_kTimelines),
); );
}); });
...@@ -107,20 +107,20 @@ Future<void> main() async { ...@@ -107,20 +107,20 @@ Future<void> main() async {
// part of the `tearDownAll` registerred in the group during // part of the `tearDownAll` registerred in the group during
// `IntegrationTestWidgetsFlutterBinding` initialization. // `IntegrationTestWidgetsFlutterBinding` initialization.
final Map<String, dynamic> response = final Map<String, dynamic> response =
(await request)['response'] as Map<String, dynamic>; (await request)!['response'] as Map<String, dynamic>;
final String message = response['message'] as String; final String message = response['message'] as String;
final Response result = Response.fromJson(message); final Response result = Response.fromJson(message);
assert(result.data['answer'] == 42); assert(result.data!['answer'] == 42);
}); });
} }
class FakeVM extends Fake implements vm.VmService { class FakeVM extends Fake implements vm.VmService {
FakeVM({@required this.timeline}); FakeVM({required this.timeline});
vm.Timeline timeline; vm.Timeline timeline;
@override @override
Future<vm.Timeline> getVMTimeline({int timeOriginMicros, int timeExtentMicros}) async { Future<vm.Timeline> getVMTimeline({int? timeOriginMicros, int? timeExtentMicros}) async {
return timeline; return timeline;
} }
......
...@@ -39,13 +39,13 @@ void main() { ...@@ -39,13 +39,13 @@ void main() {
response = Response.allTestsPassed(data: data); response = Response.allTestsPassed(data: data);
jsonString = response.toJson(); jsonString = response.toJson();
restored = Response.fromJson(jsonString); restored = Response.fromJson(jsonString);
expect(restored.data.keys, <String>['aaa']); expect(restored.data!.keys, <String>['aaa']);
expect(restored.data.values, <String>['bbb']); expect(restored.data!.values, <String>['bbb']);
response = Response.someTestsFailed(<Failure>[fail, fail2], data: data); response = Response.someTestsFailed(<Failure>[fail, fail2], data: data);
jsonString = response.toJson(); jsonString = response.toJson();
restored = Response.fromJson(jsonString); restored = Response.fromJson(jsonString);
expect(restored.data.keys, <String>['aaa']); expect(restored.data!.keys, <String>['aaa']);
expect(restored.data.values, <String>['bbb']); expect(restored.data!.values, <String>['bbb']);
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment