mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Declare locals as final where not reassigned (flutter_driver) (#8567)
This commit is contained in:
parent
e0c51480d2
commit
cdeb83cf59
|
@ -139,9 +139,9 @@ class FlutterDriver {
|
||||||
|
|
||||||
// Connect to Dart VM servcies
|
// Connect to Dart VM servcies
|
||||||
_log.info('Connecting to Flutter application at $dartVmServiceUrl');
|
_log.info('Connecting to Flutter application at $dartVmServiceUrl');
|
||||||
VMServiceClientConnection connection = await vmServiceConnectFunction(dartVmServiceUrl);
|
final VMServiceClientConnection connection = await vmServiceConnectFunction(dartVmServiceUrl);
|
||||||
VMServiceClient client = connection.client;
|
final VMServiceClient client = connection.client;
|
||||||
VM vm = await client.getVM();
|
final VM vm = await client.getVM();
|
||||||
_log.trace('Looking for the isolate');
|
_log.trace('Looking for the isolate');
|
||||||
VMIsolate isolate = await vm.isolates.first.loadRunnable();
|
VMIsolate isolate = await vm.isolates.first.loadRunnable();
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ class FlutterDriver {
|
||||||
isolate = await vm.isolates.first.loadRunnable();
|
isolate = await vm.isolates.first.loadRunnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
FlutterDriver driver = new FlutterDriver.connectedTo(
|
final FlutterDriver driver = new FlutterDriver.connectedTo(
|
||||||
client, connection.peer, isolate,
|
client, connection.peer, isolate,
|
||||||
printCommunication: printCommunication,
|
printCommunication: printCommunication,
|
||||||
logCommunicationToFile: logCommunicationToFile
|
logCommunicationToFile: logCommunicationToFile
|
||||||
|
@ -203,8 +203,8 @@ class FlutterDriver {
|
||||||
// If the isolate is paused at the start, e.g. via the --start-paused
|
// If the isolate is paused at the start, e.g. via the --start-paused
|
||||||
// option, then the VM service extension is not registered yet. Wait for
|
// option, then the VM service extension is not registered yet. Wait for
|
||||||
// it to be registered.
|
// it to be registered.
|
||||||
Future<dynamic> whenResumed = resumeLeniently();
|
final Future<dynamic> whenResumed = resumeLeniently();
|
||||||
Future<dynamic> whenServiceExtensionReady = Future.any<dynamic>(<Future<dynamic>>[
|
final Future<dynamic> whenServiceExtensionReady = Future.any<dynamic>(<Future<dynamic>>[
|
||||||
waitForServiceExtension(),
|
waitForServiceExtension(),
|
||||||
// We will never receive the extension event if the user does not
|
// We will never receive the extension event if the user does not
|
||||||
// register it. If that happens time out.
|
// register it. If that happens time out.
|
||||||
|
@ -212,7 +212,7 @@ class FlutterDriver {
|
||||||
]);
|
]);
|
||||||
await whenResumed;
|
await whenResumed;
|
||||||
_log.trace('Waiting for service extension');
|
_log.trace('Waiting for service extension');
|
||||||
dynamic signal = await whenServiceExtensionReady;
|
final dynamic signal = await whenServiceExtensionReady;
|
||||||
if (signal == 'timeout') {
|
if (signal == 'timeout') {
|
||||||
throw new DriverError(
|
throw new DriverError(
|
||||||
'Timed out waiting for Flutter Driver extension to become available. '
|
'Timed out waiting for Flutter Driver extension to become available. '
|
||||||
|
@ -239,7 +239,7 @@ class FlutterDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point the service extension must be installed. Verify it.
|
// At this point the service extension must be installed. Verify it.
|
||||||
Health health = await driver.checkHealth();
|
final Health health = await driver.checkHealth();
|
||||||
if (health.status != HealthStatus.ok) {
|
if (health.status != HealthStatus.ok) {
|
||||||
await client.close();
|
await client.close();
|
||||||
throw new DriverError('Flutter application health check failed.');
|
throw new DriverError('Flutter application health check failed.');
|
||||||
|
@ -265,7 +265,7 @@ class FlutterDriver {
|
||||||
Future<Map<String, dynamic>> _sendCommand(Command command) async {
|
Future<Map<String, dynamic>> _sendCommand(Command command) async {
|
||||||
Map<String, dynamic> response;
|
Map<String, dynamic> response;
|
||||||
try {
|
try {
|
||||||
Map<String, String> serialized = command.serialize();
|
final Map<String, String> serialized = command.serialize();
|
||||||
_logCommunication('>>> $serialized');
|
_logCommunication('>>> $serialized');
|
||||||
response = await _appIsolate
|
response = await _appIsolate
|
||||||
.invokeExtension(_kFlutterExtensionMethod, serialized)
|
.invokeExtension(_kFlutterExtensionMethod, serialized)
|
||||||
|
@ -293,7 +293,7 @@ class FlutterDriver {
|
||||||
if (_printCommunication)
|
if (_printCommunication)
|
||||||
_log.info(message);
|
_log.info(message);
|
||||||
if (_logCommunicationToFile) {
|
if (_logCommunicationToFile) {
|
||||||
f.File file = fs.file(p.join(testOutputsDirectory, 'flutter_driver_commands_$_driverId.log'));
|
final f.File file = fs.file(p.join(testOutputsDirectory, 'flutter_driver_commands_$_driverId.log'));
|
||||||
file.createSync(recursive: true); // no-op if file exists
|
file.createSync(recursive: true); // no-op if file exists
|
||||||
file.writeAsStringSync('${new DateTime.now()} $message\n', mode: f.FileMode.APPEND, flush: true);
|
file.writeAsStringSync('${new DateTime.now()} $message\n', mode: f.FileMode.APPEND, flush: true);
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ class FlutterDriver {
|
||||||
/// This command invokes the `onSubmitted` handler of the `Input` widget and
|
/// This command invokes the `onSubmitted` handler of the `Input` widget and
|
||||||
/// the returns the submitted text value.
|
/// the returns the submitted text value.
|
||||||
Future<String> submitInputText(SerializableFinder finder) async {
|
Future<String> submitInputText(SerializableFinder finder) async {
|
||||||
Map<String, dynamic> json = await _sendCommand(new SubmitInputText(finder));
|
final Map<String, dynamic> json = await _sendCommand(new SubmitInputText(finder));
|
||||||
return json['text'];
|
return json['text'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ class FlutterDriver {
|
||||||
|
|
||||||
/// Take a screenshot. The image will be returned as a PNG.
|
/// Take a screenshot. The image will be returned as a PNG.
|
||||||
Future<List<int>> screenshot() async {
|
Future<List<int>> screenshot() async {
|
||||||
Map<String, dynamic> result = await _peer.sendRequest('_flutter.screenshot');
|
final Map<String, dynamic> result = await _peer.sendRequest('_flutter.screenshot');
|
||||||
return BASE64.decode(result['screenshot']);
|
return BASE64.decode(result['screenshot']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@ class FlutterDriver {
|
||||||
///
|
///
|
||||||
/// [getFlagList]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#getflaglist
|
/// [getFlagList]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#getflaglist
|
||||||
Future<List<Map<String, dynamic>>> getVmFlags() async {
|
Future<List<Map<String, dynamic>>> getVmFlags() async {
|
||||||
Map<String, dynamic> result = await _peer.sendRequest('getFlagList');
|
final Map<String, dynamic> result = await _peer.sendRequest('getFlagList');
|
||||||
return result['flags'];
|
return result['flags'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +525,7 @@ void restoreVmServiceConnectFunction() {
|
||||||
///
|
///
|
||||||
/// Times out after 30 seconds.
|
/// Times out after 30 seconds.
|
||||||
Future<VMServiceClientConnection> _waitAndConnect(String url) async {
|
Future<VMServiceClientConnection> _waitAndConnect(String url) async {
|
||||||
Stopwatch timer = new Stopwatch()..start();
|
final Stopwatch timer = new Stopwatch()..start();
|
||||||
|
|
||||||
Future<VMServiceClientConnection> attemptConnection() async {
|
Future<VMServiceClientConnection> attemptConnection() async {
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(url);
|
||||||
|
|
|
@ -39,7 +39,7 @@ final StreamController<LogRecord> _logger =
|
||||||
});
|
});
|
||||||
|
|
||||||
void _log(LogLevel level, String loggerName, Object message) {
|
void _log(LogLevel level, String loggerName, Object message) {
|
||||||
LogRecord record = new LogRecord._(level, loggerName, '$message');
|
final LogRecord record = new LogRecord._(level, loggerName, '$message');
|
||||||
// If nobody expressed interest in rerouting log messages somewhere specific,
|
// If nobody expressed interest in rerouting log messages somewhere specific,
|
||||||
// print them to stderr.
|
// print them to stderr.
|
||||||
if (_noLogSubscribers)
|
if (_noLogSubscribers)
|
||||||
|
|
|
@ -29,7 +29,7 @@ class _DriverBinding extends WidgetsFlutterBinding { // TODO(ianh): refactor so
|
||||||
@override
|
@override
|
||||||
void initServiceExtensions() {
|
void initServiceExtensions() {
|
||||||
super.initServiceExtensions();
|
super.initServiceExtensions();
|
||||||
FlutterDriverExtension extension = new FlutterDriverExtension();
|
final FlutterDriverExtension extension = new FlutterDriverExtension();
|
||||||
registerServiceExtension(
|
registerServiceExtension(
|
||||||
name: _extensionMethodName,
|
name: _extensionMethodName,
|
||||||
callback: extension.call
|
callback: extension.call
|
||||||
|
@ -119,22 +119,22 @@ class FlutterDriverExtension {
|
||||||
/// The returned JSON is command specific. Generally the caller deserializes
|
/// The returned JSON is command specific. Generally the caller deserializes
|
||||||
/// the result into a subclass of [Result], but that's not strictly required.
|
/// the result into a subclass of [Result], but that's not strictly required.
|
||||||
Future<Map<String, dynamic>> call(Map<String, String> params) async {
|
Future<Map<String, dynamic>> call(Map<String, String> params) async {
|
||||||
String commandKind = params['command'];
|
final String commandKind = params['command'];
|
||||||
try {
|
try {
|
||||||
CommandHandlerCallback commandHandler = _commandHandlers[commandKind];
|
final CommandHandlerCallback commandHandler = _commandHandlers[commandKind];
|
||||||
CommandDeserializerCallback commandDeserializer =
|
final CommandDeserializerCallback commandDeserializer =
|
||||||
_commandDeserializers[commandKind];
|
_commandDeserializers[commandKind];
|
||||||
if (commandHandler == null || commandDeserializer == null)
|
if (commandHandler == null || commandDeserializer == null)
|
||||||
throw 'Extension $_extensionMethod does not support command $commandKind';
|
throw 'Extension $_extensionMethod does not support command $commandKind';
|
||||||
Command command = commandDeserializer(params);
|
final Command command = commandDeserializer(params);
|
||||||
Result response = await commandHandler(command).timeout(command.timeout);
|
final Result response = await commandHandler(command).timeout(command.timeout);
|
||||||
return _makeResponse(response?.toJson());
|
return _makeResponse(response?.toJson());
|
||||||
} on TimeoutException catch (error, stackTrace) {
|
} on TimeoutException catch (error, stackTrace) {
|
||||||
String msg = 'Timeout while executing $commandKind: $error\n$stackTrace';
|
final String msg = 'Timeout while executing $commandKind: $error\n$stackTrace';
|
||||||
_log.error(msg);
|
_log.error(msg);
|
||||||
return _makeResponse(msg, isError: true);
|
return _makeResponse(msg, isError: true);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
String msg = 'Uncaught extension error while executing $commandKind: $error\n$stackTrace';
|
final String msg = 'Uncaught extension error while executing $commandKind: $error\n$stackTrace';
|
||||||
_log.error(msg);
|
_log.error(msg);
|
||||||
return _makeResponse(msg, isError: true);
|
return _makeResponse(msg, isError: true);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ class FlutterDriverExtension {
|
||||||
|
|
||||||
Finder _createByTooltipMessageFinder(ByTooltipMessage arguments) {
|
Finder _createByTooltipMessageFinder(ByTooltipMessage arguments) {
|
||||||
return find.byElementPredicate((Element element) {
|
return find.byElementPredicate((Element element) {
|
||||||
Widget widget = element.widget;
|
final Widget widget = element.widget;
|
||||||
if (widget is Tooltip)
|
if (widget is Tooltip)
|
||||||
return widget.message == arguments.text;
|
return widget.message == arguments.text;
|
||||||
return false;
|
return false;
|
||||||
|
@ -204,7 +204,7 @@ class FlutterDriverExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
Finder _createFinder(SerializableFinder finder) {
|
Finder _createFinder(SerializableFinder finder) {
|
||||||
FinderConstructor constructor = _finders[finder.finderType];
|
final FinderConstructor constructor = _finders[finder.finderType];
|
||||||
|
|
||||||
if (constructor == null)
|
if (constructor == null)
|
||||||
throw 'Unsupported finder type: ${finder.finderType}';
|
throw 'Unsupported finder type: ${finder.finderType}';
|
||||||
|
@ -213,13 +213,13 @@ class FlutterDriverExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<TapResult> _tap(Command command) async {
|
Future<TapResult> _tap(Command command) async {
|
||||||
Tap tapCommand = command;
|
final Tap tapCommand = command;
|
||||||
await _prober.tap(await _waitForElement(_createFinder(tapCommand.finder)));
|
await _prober.tap(await _waitForElement(_createFinder(tapCommand.finder)));
|
||||||
return new TapResult();
|
return new TapResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<WaitForResult> _waitFor(Command command) async {
|
Future<WaitForResult> _waitFor(Command command) async {
|
||||||
WaitFor waitForCommand = command;
|
final WaitFor waitForCommand = command;
|
||||||
if ((await _waitForElement(_createFinder(waitForCommand.finder))).evaluate().isNotEmpty)
|
if ((await _waitForElement(_createFinder(waitForCommand.finder))).evaluate().isNotEmpty)
|
||||||
return new WaitForResult();
|
return new WaitForResult();
|
||||||
else
|
else
|
||||||
|
@ -232,15 +232,15 @@ class FlutterDriverExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ScrollResult> _scroll(Command command) async {
|
Future<ScrollResult> _scroll(Command command) async {
|
||||||
Scroll scrollCommand = command;
|
final Scroll scrollCommand = command;
|
||||||
Finder target = await _waitForElement(_createFinder(scrollCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(scrollCommand.finder));
|
||||||
final int totalMoves = scrollCommand.duration.inMicroseconds * scrollCommand.frequency ~/ Duration.MICROSECONDS_PER_SECOND;
|
final int totalMoves = scrollCommand.duration.inMicroseconds * scrollCommand.frequency ~/ Duration.MICROSECONDS_PER_SECOND;
|
||||||
Offset delta = new Offset(scrollCommand.dx, scrollCommand.dy) / totalMoves.toDouble();
|
final Offset delta = new Offset(scrollCommand.dx, scrollCommand.dy) / totalMoves.toDouble();
|
||||||
Duration pause = scrollCommand.duration ~/ totalMoves;
|
final Duration pause = scrollCommand.duration ~/ totalMoves;
|
||||||
Point startLocation = _prober.getCenter(target);
|
final Point startLocation = _prober.getCenter(target);
|
||||||
Point currentLocation = startLocation;
|
Point currentLocation = startLocation;
|
||||||
TestPointer pointer = new TestPointer(1);
|
final TestPointer pointer = new TestPointer(1);
|
||||||
HitTestResult hitTest = new HitTestResult();
|
final HitTestResult hitTest = new HitTestResult();
|
||||||
|
|
||||||
_prober.binding.hitTest(hitTest, startLocation);
|
_prober.binding.hitTest(hitTest, startLocation);
|
||||||
_prober.binding.dispatchEvent(pointer.down(startLocation), hitTest);
|
_prober.binding.dispatchEvent(pointer.down(startLocation), hitTest);
|
||||||
|
@ -256,38 +256,38 @@ class FlutterDriverExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ScrollResult> _scrollIntoView(Command command) async {
|
Future<ScrollResult> _scrollIntoView(Command command) async {
|
||||||
ScrollIntoView scrollIntoViewCommand = command;
|
final ScrollIntoView scrollIntoViewCommand = command;
|
||||||
Finder target = await _waitForElement(_createFinder(scrollIntoViewCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(scrollIntoViewCommand.finder));
|
||||||
await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: scrollIntoViewCommand.alignment ?? 0.0);
|
await Scrollable.ensureVisible(target.evaluate().single, duration: const Duration(milliseconds: 100), alignment: scrollIntoViewCommand.alignment ?? 0.0);
|
||||||
return new ScrollResult();
|
return new ScrollResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SetInputTextResult> _setInputText(Command command) async {
|
Future<SetInputTextResult> _setInputText(Command command) async {
|
||||||
SetInputText setInputTextCommand = command;
|
final SetInputText setInputTextCommand = command;
|
||||||
Finder target = await _waitForElement(_createFinder(setInputTextCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(setInputTextCommand.finder));
|
||||||
Input input = target.evaluate().single.widget;
|
final Input input = target.evaluate().single.widget;
|
||||||
input.onChanged(new InputValue(text: setInputTextCommand.text));
|
input.onChanged(new InputValue(text: setInputTextCommand.text));
|
||||||
return new SetInputTextResult();
|
return new SetInputTextResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SubmitInputTextResult> _submitInputText(Command command) async {
|
Future<SubmitInputTextResult> _submitInputText(Command command) async {
|
||||||
SubmitInputText submitInputTextCommand = command;
|
final SubmitInputText submitInputTextCommand = command;
|
||||||
Finder target = await _waitForElement(_createFinder(submitInputTextCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(submitInputTextCommand.finder));
|
||||||
Input input = target.evaluate().single.widget;
|
final Input input = target.evaluate().single.widget;
|
||||||
input.onSubmitted(input.value);
|
input.onSubmitted(input.value);
|
||||||
return new SubmitInputTextResult(input.value.text);
|
return new SubmitInputTextResult(input.value.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GetTextResult> _getText(Command command) async {
|
Future<GetTextResult> _getText(Command command) async {
|
||||||
GetText getTextCommand = command;
|
final GetText getTextCommand = command;
|
||||||
Finder target = await _waitForElement(_createFinder(getTextCommand.finder));
|
final Finder target = await _waitForElement(_createFinder(getTextCommand.finder));
|
||||||
// TODO(yjbanov): support more ways to read text
|
// TODO(yjbanov): support more ways to read text
|
||||||
Text text = target.evaluate().single.widget;
|
final Text text = target.evaluate().single.widget;
|
||||||
return new GetTextResult(text.data);
|
return new GetTextResult(text.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SetFrameSyncResult> _setFrameSync(Command command) async {
|
Future<SetFrameSyncResult> _setFrameSync(Command command) async {
|
||||||
SetFrameSync setFrameSyncCommand = command;
|
final SetFrameSync setFrameSyncCommand = command;
|
||||||
_frameSync = setFrameSyncCommand.enabled;
|
_frameSync = setFrameSyncCommand.enabled;
|
||||||
return new SetFrameSyncResult();
|
return new SetFrameSyncResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ abstract class SerializableFinder {
|
||||||
|
|
||||||
/// Deserializes a finder from JSON generated by [serialize].
|
/// Deserializes a finder from JSON generated by [serialize].
|
||||||
static SerializableFinder deserialize(Map<String, String> json) {
|
static SerializableFinder deserialize(Map<String, String> json) {
|
||||||
String finderType = json['finderType'];
|
final String finderType = json['finderType'];
|
||||||
switch(finderType) {
|
switch(finderType) {
|
||||||
case 'ByValueKey': return ByValueKey.deserialize(json);
|
case 'ByValueKey': return ByValueKey.deserialize(json);
|
||||||
case 'ByTooltipMessage': return ByTooltipMessage.deserialize(json);
|
case 'ByTooltipMessage': return ByTooltipMessage.deserialize(json);
|
||||||
|
@ -188,8 +188,8 @@ class ByValueKey extends SerializableFinder {
|
||||||
|
|
||||||
/// Deserializes the finder from JSON generated by [serialize].
|
/// Deserializes the finder from JSON generated by [serialize].
|
||||||
static ByValueKey deserialize(Map<String, String> json) {
|
static ByValueKey deserialize(Map<String, String> json) {
|
||||||
String keyValueString = json['keyValueString'];
|
final String keyValueString = json['keyValueString'];
|
||||||
String keyValueType = json['keyValueType'];
|
final String keyValueType = json['keyValueType'];
|
||||||
switch(keyValueType) {
|
switch(keyValueType) {
|
||||||
case 'int':
|
case 'int':
|
||||||
return new ByValueKey(int.parse(keyValueString));
|
return new ByValueKey(int.parse(keyValueString));
|
||||||
|
|
|
@ -26,7 +26,7 @@ class SetInputText extends CommandWithTarget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, String> serialize() {
|
Map<String, String> serialize() {
|
||||||
Map<String, String> json = super.serialize();
|
final Map<String, String> json = super.serialize();
|
||||||
json['text'] = text;
|
json['text'] = text;
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import 'package:matcher/matcher.dart';
|
||||||
|
|
||||||
/// Matches [value] against the [matcher].
|
/// Matches [value] against the [matcher].
|
||||||
MatchResult match(dynamic value, Matcher matcher) {
|
MatchResult match(dynamic value, Matcher matcher) {
|
||||||
Map<dynamic, dynamic> matchState = <dynamic, dynamic>{};
|
final Map<dynamic, dynamic> matchState = <dynamic, dynamic>{};
|
||||||
if (matcher.matches(value, matchState)) {
|
if (matcher.matches(value, matchState)) {
|
||||||
return new MatchResult._matched();
|
return new MatchResult._matched();
|
||||||
} else {
|
} else {
|
||||||
Description description =
|
final Description description =
|
||||||
matcher.describeMismatch(value, new _TextDescription(), matchState, false);
|
matcher.describeMismatch(value, new _TextDescription(), matchState, false);
|
||||||
return new MatchResult._mismatched(description.toString());
|
return new MatchResult._mismatched(description.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ Future<dynamic> retry(Action action, Duration timeout,
|
||||||
assert(timeout != null);
|
assert(timeout != null);
|
||||||
assert(pauseBetweenRetries != null);
|
assert(pauseBetweenRetries != null);
|
||||||
|
|
||||||
Stopwatch sw = stopwatchFactory()..start();
|
final Stopwatch sw = stopwatchFactory()..start();
|
||||||
dynamic result;
|
dynamic result;
|
||||||
dynamic lastError;
|
dynamic lastError;
|
||||||
dynamic lastStackTrace;
|
dynamic lastStackTrace;
|
||||||
|
|
|
@ -122,7 +122,7 @@ class TimelineEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TimelineEvent> _parseEvents(Map<String, dynamic> json) {
|
List<TimelineEvent> _parseEvents(Map<String, dynamic> json) {
|
||||||
List<Map<String, dynamic>> jsonEvents = json['traceEvents'];
|
final List<Map<String, dynamic>> jsonEvents = json['traceEvents'];
|
||||||
|
|
||||||
if (jsonEvents == null)
|
if (jsonEvents == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -93,7 +93,7 @@ class TimelineSummary {
|
||||||
{String destinationDirectory, bool pretty: false}) async {
|
{String destinationDirectory, bool pretty: false}) async {
|
||||||
destinationDirectory ??= testOutputsDirectory;
|
destinationDirectory ??= testOutputsDirectory;
|
||||||
await fs.directory(destinationDirectory).create(recursive: true);
|
await fs.directory(destinationDirectory).create(recursive: true);
|
||||||
File file = fs.file(path.join(destinationDirectory, '$traceName.timeline.json'));
|
final File file = fs.file(path.join(destinationDirectory, '$traceName.timeline.json'));
|
||||||
await file.writeAsString(_encodeJson(_timeline.json, pretty));
|
await file.writeAsString(_encodeJson(_timeline.json, pretty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class TimelineSummary {
|
||||||
{String destinationDirectory, bool pretty: false}) async {
|
{String destinationDirectory, bool pretty: false}) async {
|
||||||
destinationDirectory ??= testOutputsDirectory;
|
destinationDirectory ??= testOutputsDirectory;
|
||||||
await fs.directory(destinationDirectory).create(recursive: true);
|
await fs.directory(destinationDirectory).create(recursive: true);
|
||||||
File file = fs.file(path.join(destinationDirectory, '$traceName.timeline_summary.json'));
|
final File file = fs.file(path.join(destinationDirectory, '$traceName.timeline_summary.json'));
|
||||||
await file.writeAsString(_encodeJson(summaryJson, pretty));
|
await file.writeAsString(_encodeJson(summaryJson, pretty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,15 +127,15 @@ class TimelineSummary {
|
||||||
///
|
///
|
||||||
/// See: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
|
/// See: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
|
||||||
List<TimedEvent> _extractBeginEndEvents(String name) {
|
List<TimedEvent> _extractBeginEndEvents(String name) {
|
||||||
List<TimedEvent> result = <TimedEvent>[];
|
final List<TimedEvent> result = <TimedEvent>[];
|
||||||
|
|
||||||
// Timeline does not guarantee that the first event is the "begin" event.
|
// Timeline does not guarantee that the first event is the "begin" event.
|
||||||
Iterator<TimelineEvent> events = _extractNamedEvents(name)
|
final Iterator<TimelineEvent> events = _extractNamedEvents(name)
|
||||||
.skipWhile((TimelineEvent evt) => evt.phase != 'B').iterator;
|
.skipWhile((TimelineEvent evt) => evt.phase != 'B').iterator;
|
||||||
while(events.moveNext()) {
|
while(events.moveNext()) {
|
||||||
TimelineEvent beginEvent = events.current;
|
final TimelineEvent beginEvent = events.current;
|
||||||
if (events.moveNext()) {
|
if (events.moveNext()) {
|
||||||
TimelineEvent endEvent = events.current;
|
final TimelineEvent endEvent = events.current;
|
||||||
result.add(new TimedEvent(
|
result.add(new TimedEvent(
|
||||||
beginEvent.timestampMicros,
|
beginEvent.timestampMicros,
|
||||||
endEvent.timestampMicros
|
endEvent.timestampMicros
|
||||||
|
@ -150,7 +150,7 @@ class TimelineSummary {
|
||||||
if (durations.isEmpty)
|
if (durations.isEmpty)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
int total = durations.fold<int>(0, (int t, Duration duration) => t + duration.inMilliseconds);
|
final int total = durations.fold<int>(0, (int t, Duration duration) => t + duration.inMilliseconds);
|
||||||
return total / durations.length;
|
return total / durations.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ void main() {
|
||||||
when(mockIsolate.resume()).thenReturn(new Future<Null>.value());
|
when(mockIsolate.resume()).thenReturn(new Future<Null>.value());
|
||||||
when(mockIsolate.onExtensionAdded).thenReturn(new Stream<String>.fromIterable(<String>['ext.flutter.driver']));
|
when(mockIsolate.onExtensionAdded).thenReturn(new Stream<String>.fromIterable(<String>['ext.flutter.driver']));
|
||||||
|
|
||||||
FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
||||||
expect(driver, isNotNull);
|
expect(driver, isNotNull);
|
||||||
expectLogContains('Isolate is paused at start');
|
expectLogContains('Isolate is paused at start');
|
||||||
});
|
});
|
||||||
|
@ -62,7 +62,7 @@ void main() {
|
||||||
when(mockIsolate.pauseEvent).thenReturn(new MockVMPauseBreakpointEvent());
|
when(mockIsolate.pauseEvent).thenReturn(new MockVMPauseBreakpointEvent());
|
||||||
when(mockIsolate.resume()).thenReturn(new Future<Null>.value());
|
when(mockIsolate.resume()).thenReturn(new Future<Null>.value());
|
||||||
|
|
||||||
FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
||||||
expect(driver, isNotNull);
|
expect(driver, isNotNull);
|
||||||
expectLogContains('Isolate is paused mid-flight');
|
expectLogContains('Isolate is paused mid-flight');
|
||||||
});
|
});
|
||||||
|
@ -79,14 +79,14 @@ void main() {
|
||||||
return new Future<Null>.error(new rpc.RpcException(101, ''));
|
return new Future<Null>.error(new rpc.RpcException(101, ''));
|
||||||
});
|
});
|
||||||
|
|
||||||
FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
||||||
expect(driver, isNotNull);
|
expect(driver, isNotNull);
|
||||||
expectLogContains('Attempted to resume an already resumed isolate');
|
expectLogContains('Attempted to resume an already resumed isolate');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('connects to unpaused isolate', () async {
|
test('connects to unpaused isolate', () async {
|
||||||
when(mockIsolate.pauseEvent).thenReturn(new MockVMResumeEvent());
|
when(mockIsolate.pauseEvent).thenReturn(new MockVMResumeEvent());
|
||||||
FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
||||||
expect(driver, isNotNull);
|
expect(driver, isNotNull);
|
||||||
expectLogContains('Isolate is not paused. Assuming application is ready.');
|
expectLogContains('Isolate is not paused. Assuming application is ready.');
|
||||||
});
|
});
|
||||||
|
@ -108,7 +108,7 @@ void main() {
|
||||||
test('checks the health of the driver extension', () async {
|
test('checks the health of the driver extension', () async {
|
||||||
when(mockIsolate.invokeExtension(any, any)).thenReturn(
|
when(mockIsolate.invokeExtension(any, any)).thenReturn(
|
||||||
makeMockResponse(<String, dynamic>{'status': 'ok'}));
|
makeMockResponse(<String, dynamic>{'status': 'ok'}));
|
||||||
Health result = await driver.checkHealth();
|
final Health result = await driver.checkHealth();
|
||||||
expect(result.status, HealthStatus.ok);
|
expect(result.status, HealthStatus.ok);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ void main() {
|
||||||
'text': 'hello'
|
'text': 'hello'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
String result = await driver.getText(find.byValueKey(123));
|
final String result = await driver.getText(find.byValueKey(123));
|
||||||
expect(result, 'hello');
|
expect(result, 'hello');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -240,7 +240,7 @@ void main() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
Timeline timeline = await driver.traceAction(() {
|
final Timeline timeline = await driver.traceAction(() {
|
||||||
actionCalled = true;
|
actionCalled = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ void main() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
Timeline timeline = await driver.traceAction(() {
|
final Timeline timeline = await driver.traceAction(() {
|
||||||
actionCalled = true;
|
actionCalled = true;
|
||||||
},
|
},
|
||||||
streams: const <TimelineStream>[
|
streams: const <TimelineStream>[
|
||||||
|
|
|
@ -8,8 +8,8 @@ import 'package:flutter_driver/src/matcher_util.dart';
|
||||||
void main() {
|
void main() {
|
||||||
group('match', () {
|
group('match', () {
|
||||||
test('matches', () {
|
test('matches', () {
|
||||||
_TestMatcher matcher = new _TestMatcher(1);
|
final _TestMatcher matcher = new _TestMatcher(1);
|
||||||
MatchResult ok = match(1, matcher);
|
final MatchResult ok = match(1, matcher);
|
||||||
expect(ok.hasMatched, isTrue);
|
expect(ok.hasMatched, isTrue);
|
||||||
expect(ok.mismatchDescription, isNull);
|
expect(ok.mismatchDescription, isNull);
|
||||||
expect(matcher.matchState1 is Map<dynamic, dynamic>, isTrue);
|
expect(matcher.matchState1 is Map<dynamic, dynamic>, isTrue);
|
||||||
|
@ -17,8 +17,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('mismatches', () {
|
test('mismatches', () {
|
||||||
_TestMatcher matcher = new _TestMatcher(2);
|
final _TestMatcher matcher = new _TestMatcher(2);
|
||||||
MatchResult fail = match(1, matcher);
|
final MatchResult fail = match(1, matcher);
|
||||||
expect(fail.hasMatched, isFalse);
|
expect(fail.hasMatched, isFalse);
|
||||||
expect(fail.mismatchDescription, 'mismatch!');
|
expect(fail.mismatchDescription, 'mismatch!');
|
||||||
expect(matcher.matchState1, matcher.matchState2);
|
expect(matcher.matchState1, matcher.matchState2);
|
||||||
|
|
|
@ -15,7 +15,7 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fakeAsync = new FakeAsync();
|
fakeAsync = new FakeAsync();
|
||||||
Clock fakeClock = fakeAsync.getClock(new DateTime.now());
|
final Clock fakeClock = fakeAsync.getClock(new DateTime.now());
|
||||||
stopwatchFactory = () {
|
stopwatchFactory = () {
|
||||||
return new FakeStopwatch(
|
return new FakeStopwatch(
|
||||||
() => fakeClock.now().millisecondsSinceEpoch,
|
() => fakeClock.now().millisecondsSinceEpoch,
|
||||||
|
|
|
@ -84,7 +84,7 @@ void main() {
|
||||||
|
|
||||||
group('computeMissedFrameBuildBudgetCount', () {
|
group('computeMissedFrameBuildBudgetCount', () {
|
||||||
test('computes the number of missed build budgets', () {
|
test('computes the number of missed build budgets', () {
|
||||||
TimelineSummary summary = summarize(<Map<String, dynamic>>[
|
final TimelineSummary summary = summarize(<Map<String, dynamic>>[
|
||||||
build(1000, 9000),
|
build(1000, 9000),
|
||||||
build(11000, 1000),
|
build(11000, 1000),
|
||||||
build(13000, 10000),
|
build(13000, 10000),
|
||||||
|
@ -176,7 +176,7 @@ void main() {
|
||||||
|
|
||||||
group('computeMissedFrameRasterizerBudgetCount', () {
|
group('computeMissedFrameRasterizerBudgetCount', () {
|
||||||
test('computes the number of missed rasterizer budgets', () {
|
test('computes the number of missed rasterizer budgets', () {
|
||||||
TimelineSummary summary = summarize(<Map<String, dynamic>>[
|
final TimelineSummary summary = summarize(<Map<String, dynamic>>[
|
||||||
begin(1000), end(10000),
|
begin(1000), end(10000),
|
||||||
begin(11000), end(12000),
|
begin(11000), end(12000),
|
||||||
begin(13000), end(23000),
|
begin(13000), end(23000),
|
||||||
|
@ -229,7 +229,7 @@ void main() {
|
||||||
test('writes timeline to JSON file', () async {
|
test('writes timeline to JSON file', () async {
|
||||||
await summarize(<Map<String, String>>[<String, String>{'foo': 'bar'}])
|
await summarize(<Map<String, String>>[<String, String>{'foo': 'bar'}])
|
||||||
.writeTimelineToFile('test', destinationDirectory: tempDir.path);
|
.writeTimelineToFile('test', destinationDirectory: tempDir.path);
|
||||||
String written =
|
final String written =
|
||||||
await fs.file(path.join(tempDir.path, 'test.timeline.json')).readAsString();
|
await fs.file(path.join(tempDir.path, 'test.timeline.json')).readAsString();
|
||||||
expect(written, '{"traceEvents":[{"foo":"bar"}]}');
|
expect(written, '{"traceEvents":[{"foo":"bar"}]}');
|
||||||
});
|
});
|
||||||
|
@ -243,7 +243,7 @@ void main() {
|
||||||
build(11000, 1000),
|
build(11000, 1000),
|
||||||
build(13000, 11000),
|
build(13000, 11000),
|
||||||
]).writeSummaryToFile('test', destinationDirectory: tempDir.path);
|
]).writeSummaryToFile('test', destinationDirectory: tempDir.path);
|
||||||
String written =
|
final String written =
|
||||||
await fs.file(path.join(tempDir.path, 'test.timeline_summary.json')).readAsString();
|
await fs.file(path.join(tempDir.path, 'test.timeline_summary.json')).readAsString();
|
||||||
expect(JSON.decode(written), <String, dynamic>{
|
expect(JSON.decode(written), <String, dynamic>{
|
||||||
'average_frame_build_time_millis': 7.0,
|
'average_frame_build_time_millis': 7.0,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:flutter_driver/src/timeline.dart';
|
||||||
void main() {
|
void main() {
|
||||||
group('Timeline', () {
|
group('Timeline', () {
|
||||||
test('parses JSON', () {
|
test('parses JSON', () {
|
||||||
Timeline timeline = new Timeline.fromJson(<String, dynamic>{
|
final Timeline timeline = new Timeline.fromJson(<String, dynamic>{
|
||||||
'traceEvents': <Map<String, dynamic>>[
|
'traceEvents': <Map<String, dynamic>>[
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'name': 'test event',
|
'name': 'test event',
|
||||||
|
@ -31,7 +31,7 @@ void main() {
|
||||||
|
|
||||||
expect(timeline.events, hasLength(2));
|
expect(timeline.events, hasLength(2));
|
||||||
|
|
||||||
TimelineEvent e1 = timeline.events[0];
|
final TimelineEvent e1 = timeline.events[0];
|
||||||
expect(e1.name, 'test event');
|
expect(e1.name, 'test event');
|
||||||
expect(e1.category, 'test category');
|
expect(e1.category, 'test category');
|
||||||
expect(e1.phase, 'B');
|
expect(e1.phase, 'B');
|
||||||
|
@ -43,7 +43,7 @@ void main() {
|
||||||
expect(e1.threadTimestampMicros, 567);
|
expect(e1.threadTimestampMicros, 567);
|
||||||
expect(e1.arguments, <String, dynamic>{ 'arg1': true });
|
expect(e1.arguments, <String, dynamic>{ 'arg1': true });
|
||||||
|
|
||||||
TimelineEvent e2 = timeline.events[1];
|
final TimelineEvent e2 = timeline.events[1];
|
||||||
expect(e2.name, isNull);
|
expect(e2.name, isNull);
|
||||||
expect(e2.category, isNull);
|
expect(e2.category, isNull);
|
||||||
expect(e2.phase, isNull);
|
expect(e2.phase, isNull);
|
||||||
|
|
Loading…
Reference in a new issue