diff --git a/packages/e2e/CHANGELOG.md b/packages/e2e/CHANGELOG.md index ad2f8d3e24f0..255d7ce08c2d 100644 --- a/packages/e2e/CHANGELOG.md +++ b/packages/e2e/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.1 + +* Added `data` in the reported json. + ## 0.6.0 * **Breaking change** `E2EPlugin` exports a `Future` for `testResults`. diff --git a/packages/e2e/lib/common.dart b/packages/e2e/lib/common.dart index 39efcc867704..4325b6555ba8 100644 --- a/packages/e2e/lib/common.dart +++ b/packages/e2e/lib/common.dart @@ -11,13 +11,17 @@ class Response { final bool _allTestsPassed; + /// The extra information to be added along side the test result. + Map data; + /// Constructor to use for positive response. - Response.allTestsPassed() + Response.allTestsPassed({this.data}) : this._allTestsPassed = true, this._failureDetails = null; /// Constructor for failure response. - Response.someTestsFailed(this._failureDetails) : this._allTestsPassed = false; + Response.someTestsFailed(this._failureDetails, {this.data}) + : this._allTestsPassed = false; /// Whether the test ran successfully or not. bool get allTestsPassed => _allTestsPassed; @@ -33,16 +37,19 @@ class Response { String toJson() => json.encode({ 'result': allTestsPassed.toString(), 'failureDetails': _failureDetailsAsString(), + if (data != null) 'data': data }); /// Deserializes the result from JSON. static Response fromJson(String source) { - Map responseJson = json.decode(source); - if (responseJson['result'] == 'true') { - return Response.allTestsPassed(); + final Map responseJson = json.decode(source); + if (responseJson['result'] as String == 'true') { + return Response.allTestsPassed(data: responseJson['data']); } else { return Response.someTestsFailed( - _failureDetailsFromJson(responseJson['failureDetails'])); + _failureDetailsFromJson(responseJson['failureDetails']), + data: responseJson['data'], + ); } } diff --git a/packages/e2e/lib/e2e.dart b/packages/e2e/lib/e2e.dart index ec1615e904b4..a9bf83041e40 100644 --- a/packages/e2e/lib/e2e.dart +++ b/packages/e2e/lib/e2e.dart @@ -78,33 +78,47 @@ class E2EWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding { static Map _results = {}; + /// The extra data for the reported result. + /// + /// The values in `reportData` must be json-serializable objects or `null`. + /// If it's `null`, no extra data is attached to the result. + /// + /// The default value is `null`. + Map reportData; + + /// the callback function to response the driver side input. + @visibleForTesting + Future> callback(Map params) async { + final String command = params['command']; + Map response; + switch (command) { + case 'request_data': + final bool allTestsPassed = await _allTestsPassed.future; + response = { + 'message': allTestsPassed + ? Response.allTestsPassed(data: reportData).toJson() + : Response.someTestsFailed( + _failureMethodsDetails, + data: reportData, + ).toJson(), + }; + break; + case 'get_health': + response = {'status': 'ok'}; + break; + default: + throw UnimplementedError('$command is not implemented'); + } + return { + 'isError': false, + 'response': response, + }; + } + // Emulates the Flutter driver extension, returning 'pass' or 'fail'. @override void initServiceExtensions() { super.initServiceExtensions(); - Future> callback(Map params) async { - final String command = params['command']; - Map response; - switch (command) { - case 'request_data': - final bool allTestsPassed = await _allTestsPassed.future; - response = { - 'message': allTestsPassed - ? Response.allTestsPassed().toJson() - : Response.someTestsFailed(_failureMethodsDetails).toJson(), - }; - break; - case 'get_health': - response = {'status': 'ok'}; - break; - default: - throw UnimplementedError('$command is not implemented'); - } - return { - 'isError': false, - 'response': response, - }; - } if (kIsWeb) { registerWebServiceExtension(callback); diff --git a/packages/e2e/pubspec.yaml b/packages/e2e/pubspec.yaml index 25eeb3ce1374..70e57d0cb4f7 100644 --- a/packages/e2e/pubspec.yaml +++ b/packages/e2e/pubspec.yaml @@ -1,10 +1,10 @@ name: e2e description: Runs tests that use the flutter_test API as integration tests. -version: 0.6.0 +version: 0.6.1 homepage: https://github.com/flutter/plugins/tree/master/packages/e2e environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.2.2 <3.0.0" flutter: ">=1.12.13+hotfix.5 <2.0.0" dependencies: diff --git a/packages/e2e/test/binding_test.dart b/packages/e2e/test/binding_test.dart new file mode 100644 index 000000000000..8c97e161b0fe --- /dev/null +++ b/packages/e2e/test/binding_test.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:e2e/e2e.dart'; +import 'package:e2e/common.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() async { + Future> request; + + group('Test E2E binding', () { + final WidgetsBinding binding = E2EWidgetsFlutterBinding.ensureInitialized(); + assert(binding is E2EWidgetsFlutterBinding); + final E2EWidgetsFlutterBinding e2ebinding = + binding as E2EWidgetsFlutterBinding; + + setUp(() { + request = e2ebinding.callback({ + 'command': 'request_data', + }); + }); + + testWidgets('Run E2E app', (WidgetTester tester) async { + runApp(MaterialApp( + home: Text('Test'), + )); + expect(tester.binding, e2ebinding); + e2ebinding.reportData = {'answer': 42}; + }); + }); + + tearDownAll(() async { + // This part is outside the group so that `request` has been compeleted as + // part of the `tearDownAll` registerred in the group during + // `E2EWidgetsFlutterBinding` initialization. + final Map response = + (await request)['response'] as Map; + final String message = response['message'] as String; + Response result = Response.fromJson(message); + assert(result.data['answer'] == 42); + }); +} diff --git a/packages/e2e/test/response_serialization_test.dart b/packages/e2e/test/response_serialization_test.dart new file mode 100644 index 000000000000..4d823e2ebf10 --- /dev/null +++ b/packages/e2e/test/response_serialization_test.dart @@ -0,0 +1,47 @@ +import 'package:flutter_test/flutter_test.dart'; + +import 'package:e2e/common.dart'; + +void main() { + test('Serialize and deserialize Failure', () { + Failure fail = Failure('what a name', 'no detail'); + Failure restored = Failure.fromJsonString(fail.toString()); + expect(restored.methodName, fail.methodName); + expect(restored.details, fail.details); + }); + + test('Serialize and deserialize Response', () { + Response response, restored; + String jsonString; + + response = Response.allTestsPassed(); + jsonString = response.toJson(); + expect(jsonString, '{"result":"true","failureDetails":[]}'); + restored = Response.fromJson(jsonString); + expect(restored.allTestsPassed, response.allTestsPassed); + expect(restored.data, null); + expect(restored.formattedFailureDetails, ''); + + final Failure fail = Failure('what a name', 'no detail'); + final Failure fail2 = Failure('what a name2', 'no detail2'); + response = Response.someTestsFailed([fail, fail2]); + jsonString = response.toJson(); + restored = Response.fromJson(jsonString); + expect(restored.allTestsPassed, response.allTestsPassed); + expect(restored.data, null); + expect(restored.formattedFailureDetails, response.formattedFailureDetails); + + Map data = {'aaa': 'bbb'}; + response = Response.allTestsPassed(data: data); + jsonString = response.toJson(); + restored = Response.fromJson(jsonString); + expect(restored.data.keys, ['aaa']); + expect(restored.data.values, ['bbb']); + + response = Response.someTestsFailed([fail, fail2], data: data); + jsonString = response.toJson(); + restored = Response.fromJson(jsonString); + expect(restored.data.keys, ['aaa']); + expect(restored.data.values, ['bbb']); + }); +}