Unverified Commit 3d1d4532 authored by LinChen's avatar LinChen Committed by GitHub

make integration_test_driver_extended.dart support writeResponseData--(done) (#128382)

*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*

*List which issues are fixed by this PR. You must list at least one issue.*
- https://github.com/flutter/flutter/issues/128381

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
parent 380520d4
...@@ -1181,6 +1181,8 @@ Future<void> _runWebLongRunningTests() async { ...@@ -1181,6 +1181,8 @@ Future<void> _runWebLongRunningTests() async {
driver: path.join('test_driver', 'integration_test.dart'), driver: path.join('test_driver', 'integration_test.dart'),
buildMode: buildMode, buildMode: buildMode,
renderer: 'canvaskit', renderer: 'canvaskit',
expectWriteResponseFile: true,
expectResponseFileContent: 'null',
), ),
() => _runFlutterDriverWebTest( () => _runFlutterDriverWebTest(
testAppDirectory: path.join('packages', 'integration_test', 'example'), testAppDirectory: path.join('packages', 'integration_test', 'example'),
...@@ -1188,6 +1190,20 @@ Future<void> _runWebLongRunningTests() async { ...@@ -1188,6 +1190,20 @@ Future<void> _runWebLongRunningTests() async {
driver: path.join('test_driver', 'extended_integration_test.dart'), driver: path.join('test_driver', 'extended_integration_test.dart'),
buildMode: buildMode, buildMode: buildMode,
renderer: 'canvaskit', renderer: 'canvaskit',
expectWriteResponseFile: true,
expectResponseFileContent: '''
{
"screenshots": [
{
"screenshotName": "platform_name",
"bytes": []
},
{
"screenshotName": "platform_name_2",
"bytes": []
}
]
}''',
), ),
], ],
...@@ -1321,6 +1337,8 @@ Future<void> _runFlutterDriverWebTest({ ...@@ -1321,6 +1337,8 @@ Future<void> _runFlutterDriverWebTest({
String? driver, String? driver,
bool expectFailure = false, bool expectFailure = false,
bool silenceBrowserOutput = false, bool silenceBrowserOutput = false,
bool expectWriteResponseFile = false,
String expectResponseFileContent = '',
}) async { }) async {
printProgress('${green}Running integration tests $target in $buildMode mode.$reset'); printProgress('${green}Running integration tests $target in $buildMode mode.$reset');
await runCommand( await runCommand(
...@@ -1328,6 +1346,11 @@ Future<void> _runFlutterDriverWebTest({ ...@@ -1328,6 +1346,11 @@ Future<void> _runFlutterDriverWebTest({
<String>[ 'clean' ], <String>[ 'clean' ],
workingDirectory: testAppDirectory, workingDirectory: testAppDirectory,
); );
final String responseFile =
path.join(testAppDirectory, 'build', 'integration_response_data.json');
if (File(responseFile).existsSync()) {
File(responseFile).deleteSync();
}
await runCommand( await runCommand(
flutter, flutter,
<String>[ <String>[
...@@ -1356,6 +1379,20 @@ Future<void> _runFlutterDriverWebTest({ ...@@ -1356,6 +1379,20 @@ Future<void> _runFlutterDriverWebTest({
return false; return false;
}, },
); );
if (expectWriteResponseFile) {
if (!File(responseFile).existsSync()) {
foundError(<String>[
'$bold${red}Command did not write the response file but expected response file written.$reset',
]);
} else {
final String response = File(responseFile).readAsStringSync();
if (response != expectResponseFileContent) {
foundError(<String>[
'$bold${red}Command write the response file with $response but expected response file with $expectResponseFileContent.$reset',
]);
}
}
}
} }
// Compiles a sample web app and checks that its JS doesn't contain certain // Compiles a sample web app and checks that its JS doesn't contain certain
......
...@@ -25,5 +25,5 @@ Future<void> main() async { ...@@ -25,5 +25,5 @@ Future<void> main() async {
} }
return true; return true;
}, },
); writeResponseOnFailure: true);
} }
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
import 'package:integration_test/integration_test_driver.dart'; import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver(); Future<void> main() => integrationDriver(writeResponseOnFailure: true);
...@@ -67,9 +67,14 @@ Future<void> writeResponseData( ...@@ -67,9 +67,14 @@ Future<void> writeResponseData(
/// ///
/// `responseDataCallback` is the handler for processing [Response.data]. /// `responseDataCallback` is the handler for processing [Response.data].
/// The default value is `writeResponseData`. /// The default value is `writeResponseData`.
///
/// `writeResponseOnFailure` determines whether the `responseDataCallback`
/// function will be called to process the [Response.data] when a test fails.
/// The default value is `false`.
Future<void> integrationDriver({ Future<void> integrationDriver({
Duration timeout = const Duration(minutes: 20), Duration timeout = const Duration(minutes: 20),
ResponseDataCallback? responseDataCallback = writeResponseData, ResponseDataCallback? responseDataCallback = writeResponseData,
bool writeResponseOnFailure = false,
}) 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);
...@@ -85,6 +90,9 @@ Future<void> integrationDriver({ ...@@ -85,6 +90,9 @@ Future<void> integrationDriver({
exit(0); exit(0);
} else { } else {
print('Failure Details:\n${response.formattedFailureDetails}'); print('Failure Details:\n${response.formattedFailureDetails}');
if (responseDataCallback != null && writeResponseOnFailure) {
await responseDataCallback(response.data);
}
exit(1); exit(1);
} }
} }
......
...@@ -6,12 +6,45 @@ ...@@ -6,12 +6,45 @@
// ignore_for_file: avoid_print // ignore_for_file: avoid_print
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter_driver/flutter_driver.dart'; import 'package:flutter_driver/flutter_driver.dart';
import 'package:path/path.dart' as path;
import 'common.dart'; import 'common.dart';
/// Flutter Driver test output directory.
///
/// Tests should write any output files to this directory. Defaults to the path
/// set in the FLUTTER_TEST_OUTPUTS_DIR environment variable, or `build` if
/// unset.
String testOutputsDirectory =
Platform.environment['FLUTTER_TEST_OUTPUTS_DIR'] ?? 'build';
/// The callback type to handle [Response.data] after the test
/// succeeds.
typedef ResponseDataCallback = FutureOr<void> Function(Map<String, dynamic>?);
/// Writes a json-serializable data to
/// [testOutputsDirectory]/`testOutputFilename.json`.
///
/// This is the default `responseDataCallback` in [integrationDriver].
Future<void> writeResponseData(
Map<String, dynamic>? data, {
String testOutputFilename = 'integration_response_data',
String? destinationDirectory,
}) async {
destinationDirectory ??= testOutputsDirectory;
await fs.directory(destinationDirectory).create(recursive: true);
final File file = fs.file(path.join(
destinationDirectory,
'$testOutputFilename.json',
));
final String resultString = _encodeJson(data, true);
await file.writeAsString(resultString);
}
/// Adaptor to run an integration test using `flutter drive`. /// Adaptor to run an integration test using `flutter drive`.
/// ///
/// To an integration test `<test_name>.dart` using `flutter drive`, put a file named /// To an integration test `<test_name>.dart` using `flutter drive`, put a file named
...@@ -43,8 +76,19 @@ import 'common.dart'; ...@@ -43,8 +76,19 @@ import 'common.dart';
/// and it returns `true` if both images are equal. /// and it returns `true` if both images are equal.
/// ///
/// As a result, returning `false` from `onScreenshot` will make the test fail. /// As a result, returning `false` from `onScreenshot` will make the test fail.
Future<void> integrationDriver( ///
{FlutterDriver? driver, ScreenshotCallback? onScreenshot}) async { /// `responseDataCallback` is the handler for processing [Response.data].
/// The default value is `writeResponseData`.
///
/// `writeResponseOnFailure` determines whether the `responseDataCallback`
/// function will be called to process the [Response.data] when a test fails.
/// The default value is `false`.
Future<void> integrationDriver({
FlutterDriver? driver,
ScreenshotCallback? onScreenshot,
ResponseDataCallback? responseDataCallback = writeResponseData,
bool writeResponseOnFailure = false,
}) 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
...@@ -130,9 +174,21 @@ Future<void> integrationDriver( ...@@ -130,9 +174,21 @@ Future<void> integrationDriver(
if (response.allTestsPassed) { if (response.allTestsPassed) {
print('All tests passed.'); print('All tests passed.');
if (responseDataCallback != null) {
await responseDataCallback(response.data);
}
exit(0); exit(0);
} else { } else {
print('Failure Details:\n${response.formattedFailureDetails}'); print('Failure Details:\n${response.formattedFailureDetails}');
if (responseDataCallback != null && writeResponseOnFailure) {
await responseDataCallback(response.data);
}
exit(1); exit(1);
} }
} }
const JsonEncoder _prettyEncoder = JsonEncoder.withIndent(' ');
String _encodeJson(Map<String, dynamic>? jsonObject, bool pretty) {
return pretty ? _prettyEncoder.convert(jsonObject) : json.encode(jsonObject);
}
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