Skip to content

Commit 3d1d453

Browse files
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.* - flutter/flutter#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].*
1 parent 380520d commit 3d1d453

File tree

5 files changed

+105
-4
lines changed

5 files changed

+105
-4
lines changed

dev/bots/test.dart

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,13 +1181,29 @@ Future<void> _runWebLongRunningTests() async {
11811181
driver: path.join('test_driver', 'integration_test.dart'),
11821182
buildMode: buildMode,
11831183
renderer: 'canvaskit',
1184+
expectWriteResponseFile: true,
1185+
expectResponseFileContent: 'null',
11841186
),
11851187
() => _runFlutterDriverWebTest(
11861188
testAppDirectory: path.join('packages', 'integration_test', 'example'),
11871189
target: path.join('integration_test', 'extended_test.dart'),
11881190
driver: path.join('test_driver', 'extended_integration_test.dart'),
11891191
buildMode: buildMode,
11901192
renderer: 'canvaskit',
1193+
expectWriteResponseFile: true,
1194+
expectResponseFileContent: '''
1195+
{
1196+
"screenshots": [
1197+
{
1198+
"screenshotName": "platform_name",
1199+
"bytes": []
1200+
},
1201+
{
1202+
"screenshotName": "platform_name_2",
1203+
"bytes": []
1204+
}
1205+
]
1206+
}''',
11911207
),
11921208
],
11931209

@@ -1321,13 +1337,20 @@ Future<void> _runFlutterDriverWebTest({
13211337
String? driver,
13221338
bool expectFailure = false,
13231339
bool silenceBrowserOutput = false,
1340+
bool expectWriteResponseFile = false,
1341+
String expectResponseFileContent = '',
13241342
}) async {
13251343
printProgress('${green}Running integration tests $target in $buildMode mode.$reset');
13261344
await runCommand(
13271345
flutter,
13281346
<String>[ 'clean' ],
13291347
workingDirectory: testAppDirectory,
13301348
);
1349+
final String responseFile =
1350+
path.join(testAppDirectory, 'build', 'integration_response_data.json');
1351+
if (File(responseFile).existsSync()) {
1352+
File(responseFile).deleteSync();
1353+
}
13311354
await runCommand(
13321355
flutter,
13331356
<String>[
@@ -1356,6 +1379,20 @@ Future<void> _runFlutterDriverWebTest({
13561379
return false;
13571380
},
13581381
);
1382+
if (expectWriteResponseFile) {
1383+
if (!File(responseFile).existsSync()) {
1384+
foundError(<String>[
1385+
'$bold${red}Command did not write the response file but expected response file written.$reset',
1386+
]);
1387+
} else {
1388+
final String response = File(responseFile).readAsStringSync();
1389+
if (response != expectResponseFileContent) {
1390+
foundError(<String>[
1391+
'$bold${red}Command write the response file with $response but expected response file with $expectResponseFileContent.$reset',
1392+
]);
1393+
}
1394+
}
1395+
}
13591396
}
13601397

13611398
// Compiles a sample web app and checks that its JS doesn't contain certain

packages/integration_test/example/test_driver/extended_integration_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ Future<void> main() async {
2525
}
2626
return true;
2727
},
28-
);
28+
writeResponseOnFailure: true);
2929
}

packages/integration_test/example/test_driver/integration_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
import 'package:integration_test/integration_test_driver.dart';
66

7-
Future<void> main() => integrationDriver();
7+
Future<void> main() => integrationDriver(writeResponseOnFailure: true);

packages/integration_test/lib/integration_test_driver.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,14 @@ Future<void> writeResponseData(
6767
///
6868
/// `responseDataCallback` is the handler for processing [Response.data].
6969
/// The default value is `writeResponseData`.
70+
///
71+
/// `writeResponseOnFailure` determines whether the `responseDataCallback`
72+
/// function will be called to process the [Response.data] when a test fails.
73+
/// The default value is `false`.
7074
Future<void> integrationDriver({
7175
Duration timeout = const Duration(minutes: 20),
7276
ResponseDataCallback? responseDataCallback = writeResponseData,
77+
bool writeResponseOnFailure = false,
7378
}) async {
7479
final FlutterDriver driver = await FlutterDriver.connect();
7580
final String jsonResult = await driver.requestData(null, timeout: timeout);
@@ -85,6 +90,9 @@ Future<void> integrationDriver({
8590
exit(0);
8691
} else {
8792
print('Failure Details:\n${response.formattedFailureDetails}');
93+
if (responseDataCallback != null && writeResponseOnFailure) {
94+
await responseDataCallback(response.data);
95+
}
8896
exit(1);
8997
}
9098
}

packages/integration_test/lib/integration_test_driver_extended.dart

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,45 @@
66
// ignore_for_file: avoid_print
77

88
import 'dart:async';
9+
import 'dart:convert';
910
import 'dart:io';
1011

1112
import 'package:flutter_driver/flutter_driver.dart';
13+
import 'package:path/path.dart' as path;
1214

1315
import 'common.dart';
1416

17+
/// Flutter Driver test output directory.
18+
///
19+
/// Tests should write any output files to this directory. Defaults to the path
20+
/// set in the FLUTTER_TEST_OUTPUTS_DIR environment variable, or `build` if
21+
/// unset.
22+
String testOutputsDirectory =
23+
Platform.environment['FLUTTER_TEST_OUTPUTS_DIR'] ?? 'build';
24+
25+
/// The callback type to handle [Response.data] after the test
26+
/// succeeds.
27+
typedef ResponseDataCallback = FutureOr<void> Function(Map<String, dynamic>?);
28+
29+
/// Writes a json-serializable data to
30+
/// [testOutputsDirectory]/`testOutputFilename.json`.
31+
///
32+
/// This is the default `responseDataCallback` in [integrationDriver].
33+
Future<void> writeResponseData(
34+
Map<String, dynamic>? data, {
35+
String testOutputFilename = 'integration_response_data',
36+
String? destinationDirectory,
37+
}) async {
38+
destinationDirectory ??= testOutputsDirectory;
39+
await fs.directory(destinationDirectory).create(recursive: true);
40+
final File file = fs.file(path.join(
41+
destinationDirectory,
42+
'$testOutputFilename.json',
43+
));
44+
final String resultString = _encodeJson(data, true);
45+
await file.writeAsString(resultString);
46+
}
47+
1548
/// Adaptor to run an integration test using `flutter drive`.
1649
///
1750
/// To an integration test `<test_name>.dart` using `flutter drive`, put a file named
@@ -43,8 +76,19 @@ import 'common.dart';
4376
/// and it returns `true` if both images are equal.
4477
///
4578
/// As a result, returning `false` from `onScreenshot` will make the test fail.
46-
Future<void> integrationDriver(
47-
{FlutterDriver? driver, ScreenshotCallback? onScreenshot}) async {
79+
///
80+
/// `responseDataCallback` is the handler for processing [Response.data].
81+
/// The default value is `writeResponseData`.
82+
///
83+
/// `writeResponseOnFailure` determines whether the `responseDataCallback`
84+
/// function will be called to process the [Response.data] when a test fails.
85+
/// The default value is `false`.
86+
Future<void> integrationDriver({
87+
FlutterDriver? driver,
88+
ScreenshotCallback? onScreenshot,
89+
ResponseDataCallback? responseDataCallback = writeResponseData,
90+
bool writeResponseOnFailure = false,
91+
}) async {
4892
driver ??= await FlutterDriver.connect();
4993
// Test states that it's waiting on web driver commands.
5094
// [DriverTestMessage] is converted to string since json format causes an
@@ -130,9 +174,21 @@ Future<void> integrationDriver(
130174

131175
if (response.allTestsPassed) {
132176
print('All tests passed.');
177+
if (responseDataCallback != null) {
178+
await responseDataCallback(response.data);
179+
}
133180
exit(0);
134181
} else {
135182
print('Failure Details:\n${response.formattedFailureDetails}');
183+
if (responseDataCallback != null && writeResponseOnFailure) {
184+
await responseDataCallback(response.data);
185+
}
136186
exit(1);
137187
}
138188
}
189+
190+
const JsonEncoder _prettyEncoder = JsonEncoder.withIndent(' ');
191+
192+
String _encodeJson(Map<String, dynamic>? jsonObject, bool pretty) {
193+
return pretty ? _prettyEncoder.convert(jsonObject) : json.encode(jsonObject);
194+
}

0 commit comments

Comments
 (0)