Unverified Commit 9a76b420 authored by George Wright's avatar George Wright Committed by GitHub

Add support for getting a string representation of the LayerTree (#47014)

parent 467f3d49
// 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 'message.dart';
/// A Flutter Driver command that requests a string representation of the layer tree.
class GetLayerTree extends Command {
/// Create a command to request a string representation of the layer tree.
const GetLayerTree({ Duration timeout }) : super(timeout: timeout);
/// Deserializes this command from the value generated by [serialize].
GetLayerTree.deserialize(Map<String, String> json) : super.deserialize(json);
@override
String get kind => 'get_layer_tree';
}
/// A string representation of the layer tree, the result of a
/// [FlutterDriver.getLayerTree] method.
class LayerTree extends Result {
/// Creates a [LayerTree] object with the given string representation.
const LayerTree(this.tree);
/// String representation of the layer tree.
final String tree;
/// Deserializes the result from JSON.
static LayerTree fromJson(Map<String, dynamic> json) {
return LayerTree(json['tree'] as String);
}
@override
Map<String, dynamic> toJson() => <String, dynamic>{
'tree': tree,
};
}
...@@ -23,6 +23,7 @@ import '../common/fuchsia_compat.dart'; ...@@ -23,6 +23,7 @@ import '../common/fuchsia_compat.dart';
import '../common/geometry.dart'; import '../common/geometry.dart';
import '../common/gesture.dart'; import '../common/gesture.dart';
import '../common/health.dart'; import '../common/health.dart';
import '../common/layer_tree.dart';
import '../common/message.dart'; import '../common/message.dart';
import '../common/render_tree.dart'; import '../common/render_tree.dart';
import '../common/request_data.dart'; import '../common/request_data.dart';
...@@ -475,6 +476,11 @@ class FlutterDriver { ...@@ -475,6 +476,11 @@ class FlutterDriver {
return RenderTree.fromJson(await _sendCommand(GetRenderTree(timeout: timeout))); return RenderTree.fromJson(await _sendCommand(GetRenderTree(timeout: timeout)));
} }
/// Returns a dump of the layer tree.
Future<LayerTree> getLayerTree({ Duration timeout }) async {
return LayerTree.fromJson(await _sendCommand(GetLayerTree(timeout: timeout)));
}
/// Taps at the center of the widget located by [finder]. /// Taps at the center of the widget located by [finder].
Future<void> tap(SerializableFinder finder, { Duration timeout }) async { Future<void> tap(SerializableFinder finder, { Duration timeout }) async {
await _sendCommand(Tap(finder, timeout: timeout)); await _sendCommand(Tap(finder, timeout: timeout));
......
...@@ -24,6 +24,7 @@ import '../common/frame_sync.dart'; ...@@ -24,6 +24,7 @@ import '../common/frame_sync.dart';
import '../common/geometry.dart'; import '../common/geometry.dart';
import '../common/gesture.dart'; import '../common/gesture.dart';
import '../common/health.dart'; import '../common/health.dart';
import '../common/layer_tree.dart';
import '../common/message.dart'; import '../common/message.dart';
import '../common/render_tree.dart'; import '../common/render_tree.dart';
import '../common/request_data.dart'; import '../common/request_data.dart';
...@@ -107,6 +108,7 @@ class FlutterDriverExtension { ...@@ -107,6 +108,7 @@ class FlutterDriverExtension {
_commandHandlers.addAll(<String, CommandHandlerCallback>{ _commandHandlers.addAll(<String, CommandHandlerCallback>{
'get_health': _getHealth, 'get_health': _getHealth,
'get_layer_tree': _getLayerTree,
'get_render_tree': _getRenderTree, 'get_render_tree': _getRenderTree,
'enter_text': _enterText, 'enter_text': _enterText,
'get_text': _getText, 'get_text': _getText,
...@@ -130,6 +132,7 @@ class FlutterDriverExtension { ...@@ -130,6 +132,7 @@ class FlutterDriverExtension {
_commandDeserializers.addAll(<String, CommandDeserializerCallback>{ _commandDeserializers.addAll(<String, CommandDeserializerCallback>{
'get_health': (Map<String, String> params) => GetHealth.deserialize(params), 'get_health': (Map<String, String> params) => GetHealth.deserialize(params),
'get_layer_tree': (Map<String, String> params) => GetLayerTree.deserialize(params),
'get_render_tree': (Map<String, String> params) => GetRenderTree.deserialize(params), 'get_render_tree': (Map<String, String> params) => GetRenderTree.deserialize(params),
'enter_text': (Map<String, String> params) => EnterText.deserialize(params), 'enter_text': (Map<String, String> params) => EnterText.deserialize(params),
'get_text': (Map<String, String> params) => GetText.deserialize(params), 'get_text': (Map<String, String> params) => GetText.deserialize(params),
...@@ -229,6 +232,10 @@ class FlutterDriverExtension { ...@@ -229,6 +232,10 @@ class FlutterDriverExtension {
Future<Health> _getHealth(Command command) async => const Health(HealthStatus.ok); Future<Health> _getHealth(Command command) async => const Health(HealthStatus.ok);
Future<LayerTree> _getLayerTree(Command command) async {
return LayerTree(RendererBinding.instance?.renderView?.debugLayer?.toStringDeep());
}
Future<RenderTree> _getRenderTree(Command command) async { Future<RenderTree> _getRenderTree(Command command) async {
return RenderTree(RendererBinding.instance?.renderView?.toStringDeep()); return RenderTree(RendererBinding.instance?.renderView?.toStringDeep());
} }
......
...@@ -6,6 +6,7 @@ import 'dart:async'; ...@@ -6,6 +6,7 @@ import 'dart:async';
import 'package:flutter_driver/src/common/error.dart'; import 'package:flutter_driver/src/common/error.dart';
import 'package:flutter_driver/src/common/health.dart'; import 'package:flutter_driver/src/common/health.dart';
import 'package:flutter_driver/src/common/layer_tree.dart';
import 'package:flutter_driver/src/common/wait.dart'; import 'package:flutter_driver/src/common/wait.dart';
import 'package:flutter_driver/src/driver/driver.dart'; import 'package:flutter_driver/src/driver/driver.dart';
import 'package:flutter_driver/src/driver/timeline.dart'; import 'package:flutter_driver/src/driver/timeline.dart';
...@@ -231,6 +232,25 @@ void main() { ...@@ -231,6 +232,25 @@ void main() {
}); });
}); });
group('getLayerTree', () {
test('sends the getLayerTree command', () async {
when(mockIsolate.invokeExtension(any, any)).thenAnswer((Invocation i) {
expect(i.positionalArguments[1], <String, dynamic>{
'command': 'get_layer_tree',
'timeout': _kSerializedTestTimeout,
});
return makeMockResponse(<String, String>{
'tree': 'hello',
});
});
final LayerTree result = await driver.getLayerTree(timeout: _kTestTimeout);
final LayerTree referenceTree = LayerTree.fromJson(<String, String>{
'tree': 'hello',
});
expect(result.tree, referenceTree.tree);
});
});
group('waitFor', () { group('waitFor', () {
test('requires a target reference', () async { test('requires a target reference', () async {
expect(driver.waitFor(null), throwsA(isInstanceOf<DriverError>())); expect(driver.waitFor(null), throwsA(isInstanceOf<DriverError>()));
......
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