Make flutter_driver be usable from a null-safe app (#75175)

This commit is contained in:
Michael Goderbauer 2021-02-02 10:34:11 -08:00 committed by GitHub
parent 5b6444f317
commit 9fd5242e65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 21 deletions

View file

@ -311,7 +311,7 @@ abstract class FlutterDriver {
/// See also:
///
/// * [getWidgetDiagnostics], which gets the [DiagnosticsNode] of a [Widget].
Future<Map<String, Object>> getRenderObjectDiagnostics(
Future<Map<String, Object?>> getRenderObjectDiagnostics(
SerializableFinder finder, {
int subtreeDepth = 0,
bool includeProperties = true,
@ -323,7 +323,7 @@ abstract class FlutterDriver {
subtreeDepth: subtreeDepth,
includeProperties: includeProperties,
timeout: timeout,
)) as Map<String, Object>;
));
}
/// Returns a JSON map of the [DiagnosticsNode] that is associated with the
@ -344,7 +344,7 @@ abstract class FlutterDriver {
///
/// * [getRenderObjectDiagnostics], which gets the [DiagnosticsNode] of a
/// [RenderObject].
Future<Map<String, Object>> getWidgetDiagnostics(
Future<Map<String, Object?>> getWidgetDiagnostics(
SerializableFinder finder, {
int subtreeDepth = 0,
bool includeProperties = true,
@ -356,7 +356,7 @@ abstract class FlutterDriver {
subtreeDepth: subtreeDepth,
includeProperties: includeProperties,
timeout: timeout,
)) as Map<String, Object>;
));
}
/// Tell the driver to perform a scrolling action.

View file

@ -149,6 +149,7 @@ class VMServiceFlutterDriver extends FlutterDriver {
'when another tool (usually a debugger) resumed the isolate '
'before the flutter_driver did.'
);
return vms.Success();
} else {
// Failed to resume due to another reason. Fail hard.
throw e;
@ -312,11 +313,11 @@ class VMServiceFlutterDriver extends FlutterDriver {
isolateId: _appIsolate.id,
args: serialized,
).then<Map<String, dynamic>>((vms.Response value) => value.json!);
response = (await _warnIfSlow<Map<String, dynamic>>(
response = await _warnIfSlow<Map<String, dynamic>>(
future: future,
timeout: command.timeout ?? kUnusuallyLongTimeout,
message: '${command.kind} message is taking a long time to complete...',
))!;
);
_logCommunication('<<< $response');
} catch (error, stackTrace) {
throw DriverError(
@ -407,7 +408,7 @@ class VMServiceFlutterDriver extends FlutterDriver {
const int kSecondInMicros = 1000000;
int currentStart = startTime;
int currentEnd = startTime + kSecondInMicros; // 1 second of timeline
final List<Map<String, Object?>?> chunks = <Map<String, Object>?>[];
final List<Map<String, Object?>?> chunks = <Map<String, Object?>?>[];
do {
final vms.Timeline chunk = await _serviceClient.getVMTimeline(
timeOriginMicros: currentStart,
@ -420,9 +421,9 @@ class VMServiceFlutterDriver extends FlutterDriver {
currentEnd += kSecondInMicros;
} while (currentStart < endTime!);
return Timeline.fromJson(<String, Object>{
'traceEvents': <Object> [
'traceEvents': <Object?> [
for (Map<String, Object?>? chunk in chunks)
...chunk!['traceEvents']! as List<Object>,
...chunk!['traceEvents']! as List<Object?>,
],
});
} catch (error, stackTrace) {
@ -621,22 +622,24 @@ void _log(String message) {
driverLog('VMServiceFlutterDriver', message);
}
Future<T?> _warnIfSlow<T>({
required Future<T?> future,
Future<T> _warnIfSlow<T>({
required Future<T> future,
required Duration timeout,
required String message,
}) {
}) async {
assert(future != null);
assert(timeout != null);
assert(message != null);
future
.timeout(timeout, onTimeout: () {
_log(message);
return null;
})
final Completer<void> completer = Completer<void>();
completer.future.timeout(timeout, onTimeout: () {
_log(message);
return null;
});
try {
await future.whenComplete(() { completer.complete(); });
} catch (e) {
// Don't duplicate errors if [future] completes with an error.
.catchError((Object e, StackTrace s) => null);
}
return future;
}

View file

@ -14,7 +14,7 @@ import 'package:flutter_driver/src/driver/timeline.dart';
import 'package:fake_async/fake_async.dart';
import 'package:vm_service/vm_service.dart' as vms;
import 'common.dart';
import '../../common.dart';
/// Magical timeout value that's different from the default.
const Duration _kTestTimeout = Duration(milliseconds: 1234);
@ -1010,4 +1010,4 @@ class FakeIsolate extends Fake implements vms.Isolate {
@override
List<String> get extensionRPCs => <String>[];
}
}

View file

@ -0,0 +1,41 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;
void main() {
// On CI we only execute the tests in the `test/src/real_test` and
// `test/src/web_test` directory, see https://github.com/flutter/flutter/blob/master/dev/bots/test.dart.
// This test ensures that we do not accidentally add tests in the the `test`
// or `test/src` directory, which would not run on CI.
test('test files exist only in directories where CI expects them', () {
final String flutterDriverPath = p.dirname(Platform.script.path);
expect(p.basename(flutterDriverPath), 'flutter_driver');
final String flutterDriverTestPath = p.join(flutterDriverPath, 'test');
final Directory flutterDriverTestDir = Directory(flutterDriverTestPath);
expect(flutterDriverTestDir.existsSync(), isTrue);
final List<String> filesInTestDir = flutterDriverTestDir.listSync()
.map((FileSystemEntity e) => p.basename(e.path))
.where((String s) => p.extension(s) == '.dart')
.toList();
// There are no test files in the `test` directory.
expect(filesInTestDir, <String>['common.dart']);
// There are no test files in the src directory.
final String flutterDriverTestSrcPath = p.join(flutterDriverTestPath, 'src');
final Directory flutterDriverTestSrcDir = Directory(flutterDriverTestSrcPath);
expect(flutterDriverTestSrcDir.existsSync(), isTrue);
final List<String> filesInTestSrcDir = flutterDriverTestSrcDir.listSync()
.map((FileSystemEntity e) => p.basename(e.path))
.where((String s) => p.extension(s) == '.dart')
.toList();
// There are no test files in the `test/src` directory.
expect(filesInTestSrcDir, unorderedEquals(<String>[]));
});
}