diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart index bd0d5882ec9..cb6db1d0865 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart @@ -4,7 +4,6 @@ // Do not delete these arguments. They are parsed by test runner. // test-argument:appPath="test/test_infra/fixtures/memory_app" -// test-argument:experimentsOn=true // ignore_for_file: avoid_print diff --git a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart index 33a11dd87de..56415df00a0 100644 --- a/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector/inspector_controller.dart @@ -454,7 +454,7 @@ class InspectorController extends DisposableController final group = treeGroups.next; final node = await (detailsSubtree ? group.getDetailsSubtree(subtreeRoot, subtreeDepth: subtreeDepth) - : group.getRoot(treeType)); + : group.getRoot(treeType, isSummaryTree: true)); if (node == null || group.disposed || _disposed) { return; } diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart index a7018bb0c52..ebee91a96b9 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart @@ -454,7 +454,7 @@ class InspectorController extends DisposableController final group = treeGroups.next; final node = await (detailsSubtree ? group.getDetailsSubtree(subtreeRoot, subtreeDepth: subtreeDepth) - : group.getRoot(treeType)); + : group.getRoot(treeType, isSummaryTree: false)); if (node == null || group.disposed || _disposed) { return; } diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart index 037427a70f1..a25708e748a 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart @@ -1313,6 +1313,7 @@ class InspectorRowContent extends StatelessWidget { isSelected: row.isSelected, searchValue: searchValue, errorText: error?.errorMessage, + emphasizeNodesFromLocalProject: true, nodeDescriptionHighlightStyle: searchValue.isEmpty || !row.isSearchMatch ? DiagnosticsTextStyles.regular( diff --git a/packages/devtools_app/lib/src/shared/console/widgets/description.dart b/packages/devtools_app/lib/src/shared/console/widgets/description.dart index 8ed54aff98d..01858ae7ae3 100644 --- a/packages/devtools_app/lib/src/shared/console/widgets/description.dart +++ b/packages/devtools_app/lib/src/shared/console/widgets/description.dart @@ -42,6 +42,7 @@ class DiagnosticsNodeDescription extends StatelessWidget { this.multiline = false, this.style, this.nodeDescriptionHighlightStyle, + this.emphasizeNodesFromLocalProject = false, }); final RemoteDiagnosticsNode? diagnostic; @@ -51,6 +52,10 @@ class DiagnosticsNodeDescription extends StatelessWidget { final bool multiline; final TextStyle? style; final TextStyle? nodeDescriptionHighlightStyle; + // TODO(https://github.com/flutter/devtools/issues/7860): Remove and default + // to true when turning on inspector V2. This is currently true for the V2 + // inspector and false for the legacy inspector. + final bool emphasizeNodesFromLocalProject; static Widget _paddedIcon(Widget icon) { return Padding( @@ -264,7 +269,6 @@ class DiagnosticsNodeDescription extends StatelessWidget { colorScheme, ), ); - var descriptionTextStyle = textStyle; // TODO(jacobr): use TextSpans and SelectableText instead of Text. if (diagnosticLocal.isProperty) { // Display of inline properties. @@ -280,8 +284,7 @@ class DiagnosticsNodeDescription extends StatelessWidget { ); // provide some contrast between the name and description if both are // present. - descriptionTextStyle = - descriptionTextStyle.merge(theme.subtleTextStyle); + textStyle = textStyle.merge(theme.subtleTextStyle); } if (diagnosticLocal.isCreatedByLocalProject) { @@ -332,7 +335,7 @@ class DiagnosticsNodeDescription extends StatelessWidget { Flexible( child: buildDescription( description: description, - textStyle: descriptionTextStyle, + textStyle: textStyle, colorScheme: colorScheme, diagnostic: diagnostic, searchValue: searchValue, @@ -382,14 +385,25 @@ class DiagnosticsNodeDescription extends StatelessWidget { } } - if (!diagnosticLocal.isSummaryTree && + // TODO(https://github.com/flutter/devtools/issues/7860): Remove this + // if-block once the widget details tree is gone. This bolding is only + // used there. + if (!emphasizeNodesFromLocalProject && + !diagnosticLocal.isSummaryTree && diagnosticLocal.isCreatedByLocalProject) { textStyle = textStyle.merge(DiagnosticsTextStyles.regularBold); } + // Grey out nodes that were not created by the local project to emphasize + // those that were: + if (emphasizeNodesFromLocalProject && + !diagnosticLocal.isCreatedByLocalProject) { + textStyle = textStyle.merge(theme.subtleTextStyle); + } + var diagnosticDescription = buildDescription( description: diagnosticLocal.description ?? '', - textStyle: descriptionTextStyle, + textStyle: textStyle, colorScheme: colorScheme, diagnostic: diagnostic, searchValue: searchValue, diff --git a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart index 833cdacdc69..af9881b5d82 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart @@ -948,21 +948,29 @@ class ObjectGroup extends InspectorObjectGroupBase { @override bool canSetSelectionInspector = true; - Future getRoot(FlutterTreeType type) { + Future getRoot( + FlutterTreeType type, { + required bool isSummaryTree, + }) { // There is no excuse to call this method on a disposed group. assert(!disposed); switch (type) { case FlutterTreeType.widget: - return getRootWidget(); + return getRootWidgetTree(isSummaryTree: isSummaryTree); } } - Future getRootWidget() { + Future getRootWidgetTree({ + required bool isSummaryTree, + }) { return parseDiagnosticsNodeDaemon( invokeServiceMethodDaemonParams( - WidgetInspectorServiceExtensions - .getRootWidgetSummaryTreeWithPreviews.name, - {'groupName': groupName}, + WidgetInspectorServiceExtensions.getRootWidgetTree.name, + { + 'groupName': groupName, + 'isSummaryTree': '$isSummaryTree', + 'withPreviews': 'true', + }, ), ); } diff --git a/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart b/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart index 8a520662632..3766b87ab2f 100644 --- a/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart +++ b/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart @@ -51,28 +51,14 @@ void main() { group('screenshot tests', () { testWidgetsWithWindowSize( - 'navigation', + 'initial load', windowSize, (WidgetTester tester) async { - await env.setupEnvironment(); expect(serviceConnection.serviceManager.service, equals(env.service)); expect(serviceConnection.serviceManager.isolateManager, isNotNull); - final screen = InspectorScreen(); - await tester.pumpWidget( - wrapWithInspectorControllers( - Builder(builder: screen.build), - v2: true, - ), - ); - await tester.pump(const Duration(seconds: 1)); - final InspectorScreenBodyState state = - tester.state(find.byType(InspectorScreenBody)); - final controller = state.controller; - while (!controller.flutterAppFrameReady) { - await controller.maybeLoadUI(); - await tester.pumpAndSettle(); - } + await _loadInspectorUI(tester); + // Give time for the initial animation to complete. await tester.pumpAndSettle(inspectorChangeSettleTime); await expectLater( @@ -82,6 +68,19 @@ void main() { ), ); + await env.tearDownEnvironment(); + }, + ); + + testWidgetsWithWindowSize( + 'navigation', + windowSize, + (WidgetTester tester) async { + await _loadInspectorUI(tester); + + // Give time for the initial animation to complete. + await tester.pumpAndSettle(inspectorChangeSettleTime); + // Click on the Center widget (row index #5) await tester.tap(find.richText('Center')); await tester.pumpAndSettle(inspectorChangeSettleTime); @@ -152,6 +151,9 @@ void main() { await env.tearDownEnvironment(); }, + // TODO(https://github.com/flutter/devtools/issues/7911): Re-enable once + // the implementation details are collapsed. + skip: true, ); // TODO(jacobr): convert these tests to screenshot tests like the initial @@ -462,3 +464,21 @@ void main() { ); }); } + +Future _loadInspectorUI(WidgetTester tester) async { + final screen = InspectorScreen(); + await tester.pumpWidget( + wrapWithInspectorControllers( + Builder(builder: screen.build), + v2: true, + ), + ); + await tester.pump(const Duration(seconds: 1)); + final InspectorScreenBodyState state = + tester.state(find.byType(InspectorScreenBody)); + final controller = state.controller; + while (!controller.flutterAppFrameReady) { + await controller.maybeLoadUI(); + await tester.pumpAndSettle(); + } +} diff --git a/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart b/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart index 39904c00d2c..b37c3da1251 100644 --- a/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart +++ b/packages/devtools_app/test/shared/diagnostics/inspector_service_test.dart @@ -264,92 +264,134 @@ void main() { }); }); - test('widget tree', () async { - await env.setupEnvironment(); - final group = inspectorService!.createObjectGroup('test-group'); - final root = (await group.getRoot(FlutterTreeType.widget))!; - // Tree only contains widgets from local app. - expect( - treeToDebugString(root), - equalsIgnoringHashCodes( - ''' -[root] - └─MyApp - └─MaterialApp - └─Scaffold - ├─Center - │ └─Text - ├─AppBar - │ └─Text - └─FloatingActionButton - └─Icon -''', - ), - ); - RemoteDiagnosticsNode nodeInSummaryTree = - findNodeMatching(root, 'MaterialApp')!; - expect(nodeInSummaryTree, isNotNull); - expect( - treeToDebugString(nodeInSummaryTree), - equalsIgnoringHashCodes( - ''' -MaterialApp - └─Scaffold - ├─Center - │ └─Text - ├─AppBar - │ └─Text - └─FloatingActionButton - └─Icon -''', - ), - ); - RemoteDiagnosticsNode nodeInDetailsTree = - (await group.getDetailsSubtree(nodeInSummaryTree))!; - // When flutter rolls, this string may sometimes change due to - // implementation details. - expect( - treeToDebugStringTruncated(nodeInDetailsTree, 30), - equalsGoldenIgnoringHashCodes('inspector_service_details_tree.txt'), - ); + group('widget trees', () { + test('isSummaryTree = true', () async { + await env.setupEnvironment(); + final group = inspectorService!.createObjectGroup('test-group'); + final RemoteDiagnosticsNode root = (await group.getRoot( + FlutterTreeType.widget, + isSummaryTree: true, + ))!; + // Tree only contains widgets from local app. + expect( + treeToDebugString(root), + equals( + equalsGoldenIgnoringHashCodes( + 'inspector_service_tree_summary.txt', + ), + ), + ); + final nodeInSummaryTree = findNodeMatching(root, 'MaterialApp')!; + expect(nodeInSummaryTree, isNotNull); - nodeInSummaryTree = findNodeMatching(root, 'Text')!; - expect(nodeInSummaryTree, isNotNull); - expect( - treeToDebugString(nodeInSummaryTree), - equalsIgnoringHashCodes( - 'Text\n', - ), - ); + expect( + treeToDebugString(nodeInSummaryTree), + equals( + equalsGoldenIgnoringHashCodes( + 'inspector_service_node_summary.txt', + ), + ), + ); - nodeInDetailsTree = (await group.getDetailsSubtree(nodeInSummaryTree))!; + await group.dispose(); + }); - expect( - treeToDebugString(nodeInDetailsTree), - equalsGoldenIgnoringHashCodes( - 'inspector_service_text_details_tree.txt', - ), - ); + test('isSummaryTree = false', () async { + await env.setupEnvironment(); + final group = inspectorService!.createObjectGroup('test-group'); + final RemoteDiagnosticsNode root = (await group.getRoot( + FlutterTreeType.widget, + isSummaryTree: false, + ))!; + // Tree contains all widgets. + expect( + treeToDebugString(root), + equals( + equalsGoldenIgnoringHashCodes( + 'inspector_service_tree_no_summary.txt', + ), + ), + ); + final nodeInTree = findNodeMatching(root, 'MaterialApp')!; + expect(nodeInTree, isNotNull); + expect( + treeToDebugString(nodeInTree), + equals( + equalsGoldenIgnoringHashCodes( + 'inspector_service_node_no_summary.txt', + ), + ), + ); - expect(nodeInDetailsTree.valueRef, equals(nodeInSummaryTree.valueRef)); - - await group.setSelectionInspector(nodeInDetailsTree.valueRef, true); - final selection = (await group.getSelection( - null, - FlutterTreeType.widget, - isSummaryTree: false, - ))!; - expect(selection, isNotNull); - expect(selection.valueRef, equals(nodeInDetailsTree.valueRef)); - expect( - treeToDebugString(selection), - equalsIgnoringHashCodes( - 'Text\n' - ' └─RichText\n', - ), - ); + await group.dispose(); + }); + + test('details tree', () async { + await env.setupEnvironment(); + + // First get a node in the summary tree: + final group = inspectorService!.createObjectGroup('test-group'); + final RemoteDiagnosticsNode root = (await group.getRoot( + FlutterTreeType.widget, + isSummaryTree: true, + ))!; + RemoteDiagnosticsNode nodeInSummaryTree = + findNodeMatching(root, 'MaterialApp')!; + expect(nodeInSummaryTree, isNotNull); + + // Then get the details tree for the node in the summary tree: + RemoteDiagnosticsNode nodeInDetailsTree = + (await group.getDetailsSubtree(nodeInSummaryTree))!; + + // When flutter rolls, this string may sometimes change due to + // implementation details. + expect( + treeToDebugStringTruncated(nodeInDetailsTree, 30), + equalsGoldenIgnoringHashCodes('inspector_service_details_tree.txt'), + ); + + nodeInSummaryTree = findNodeMatching(root, 'Text')!; + expect(nodeInSummaryTree, isNotNull); + expect( + treeToDebugString(nodeInSummaryTree), + equalsIgnoringHashCodes( + 'Text\n', + ), + ); + + nodeInDetailsTree = + (await group.getDetailsSubtree(nodeInSummaryTree))!; - await group.dispose(); + expect( + treeToDebugString(nodeInDetailsTree), + equalsGoldenIgnoringHashCodes( + 'inspector_service_text_details_tree.txt', + ), + ); + + expect( + nodeInDetailsTree.valueRef, + equals(nodeInSummaryTree.valueRef), + ); + + await group.setSelectionInspector(nodeInDetailsTree.valueRef, true); + final selection = (await group.getSelection( + null, + FlutterTreeType.widget, + isSummaryTree: false, + ))!; + expect(selection, isNotNull); + expect(selection.valueRef, equals(nodeInDetailsTree.valueRef)); + expect( + treeToDebugString(selection), + equalsIgnoringHashCodes( + 'Text\n' + ' └─RichText\n', + ), + ); + + await group.dispose(); + }); }); test('enables hover eval mode by default', () async { diff --git a/packages/devtools_app/test/test_infra/goldens/inspector_service_node_no_summary.txt b/packages/devtools_app/test/test_infra/goldens/inspector_service_node_no_summary.txt new file mode 100644 index 00000000000..880a11273cb --- /dev/null +++ b/packages/devtools_app/test/test_infra/goldens/inspector_service_node_no_summary.txt @@ -0,0 +1,246 @@ +MaterialApp + └─ScrollConfiguration + └─HeroControllerScope + └─Focus + └─_FocusInheritedScope + └─Semantics + └─WidgetsApp-[GlobalObjectKey _MaterialAppState#00000] + └─RootRestorationScope + └─UnmanagedRestorationScope + └─RestorationScope + └─UnmanagedRestorationScope + └─SharedAppData + └─_SharedAppModel + └─NotificationListener + └─Shortcuts + └─Focus + └─_FocusInheritedScope + └─Semantics + └─DefaultTextEditingShortcuts + └─Shortcuts + └─Focus + └─_FocusInheritedScope + └─Semantics + └─Actions + └─_ActionsScope + └─FocusTraversalGroup + └─Focus + └─_FocusInheritedScope + └─TapRegionSurface + └─ShortcutRegistrar + └─_ShortcutRegistrarScope + └─Shortcuts + └─Focus + └─_FocusInheritedScope + └─Semantics + └─Localizations + └─Semantics + └─_LocalizationsScope-[GlobalKey#00000] + └─Directionality + └─Title + └─CheckedModeBanner + └─Banner + └─CustomPaint + └─ValueListenableBuilder + └─DefaultTextStyle + └─Builder + └─ScaffoldMessenger + └─_ScaffoldMessengerScope + └─DefaultSelectionStyle + └─AnimatedTheme + └─Theme + └─_InheritedTheme + └─CupertinoTheme + └─InheritedCupertinoTheme + └─IconTheme + └─IconTheme + └─DefaultSelectionStyle + └─FocusScope + └─Semantics + └─_FocusInheritedScope + └─Navigator-[GlobalObjectKey _WidgetsAppState#00000] + └─HeroControllerScope + └─NotificationListener + └─Listener + └─AbsorbPointer + └─FocusTraversalGroup + └─Focus + └─_FocusInheritedScope + └─Focus + └─_FocusInheritedScope + └─UnmanagedRestorationScope + └─Overlay-[LabeledGlobalKey#00000] + └─_Theater + ├─_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#00000] + │ └─TickerMode + │ └─_EffectiveTickerMode + │ └─_RenderTheaterMarker + │ └─IgnorePointer + │ └─ModalBarrier + │ └─BlockSemantics + │ └─ExcludeSemantics + │ └─_ModalBarrierGestureDetector + │ └─RawGestureDetector + │ └─_GestureSemantics + │ └─Listener + │ └─Semantics + │ └─MouseRegion + │ └─ConstrainedBox + └─_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#00000] + └─TickerMode + └─_EffectiveTickerMode + └─_RenderTheaterMarker + └─Semantics + └─_ModalScope-[LabeledGlobalKey<_ModalScopeState>#00000] + └─AnimatedBuilder + └─RestorationScope + └─UnmanagedRestorationScope + └─_ModalScopeStatus + └─Offstage + └─PageStorage + └─Builder + └─Actions + └─_ActionsScope + └─PrimaryScrollController + └─_FocusScopeWithExternalFocusNode + └─Semantics + └─_FocusInheritedScope + └─RepaintBoundary + └─ListenableBuilder + └─_PageTransitionsThemeTransitions + └─_ZoomPageTransition + └─DualTransitionBuilder + └─_ZoomEnterTransition + └─SnapshotWidget + └─_ZoomExitTransition + └─SnapshotWidget + └─DualTransitionBuilder + └─_ZoomEnterTransition + └─SnapshotWidget + └─_ZoomExitTransition + └─SnapshotWidget + └─ListenableBuilder + └─IgnorePointer + └─RepaintBoundary-[GlobalKey#00000] + └─Builder + └─Semantics + └─Scaffold + └─_ScaffoldScope + └─ScrollNotificationObserver + └─NotificationListener + └─NotificationListener + └─_ScrollNotificationObserverScope + └─Material + └─AnimatedPhysicalModel + └─PhysicalModel + └─NotificationListener + └─_InkFeatures-[GlobalKey#00000 ink renderer] + └─AnimatedDefaultTextStyle + └─DefaultTextStyle + └─AnimatedBuilder + └─Actions + └─_ActionsScope + └─CustomMultiChildLayout + ├─LayoutId-[<_ScaffoldSlot.body>] + │ └─MediaQuery + │ └─_BodyBuilder + │ └─KeyedSubtree-[GlobalKey#00000] + │ └─Center + │ └─Text + │ └─RichText + ├─LayoutId-[<_ScaffoldSlot.appBar>] + │ └─MediaQuery + │ └─ConstrainedBox + │ └─FlexibleSpaceBarSettings + │ └─AppBar + │ └─Semantics + │ └─AnnotatedRegion + │ └─Material + │ └─AnimatedPhysicalModel + │ └─PhysicalModel + │ └─NotificationListener + │ └─_InkFeatures-[GlobalKey#00000 ink renderer] + │ └─AnimatedDefaultTextStyle + │ └─DefaultTextStyle + │ └─Semantics + │ └─Align + │ └─SafeArea + │ └─Padding + │ └─MediaQuery + │ └─ClipRect + │ └─CustomSingleChildLayout + │ └─Builder + │ └─IconTheme + │ └─DefaultTextStyle + │ └─NavigationToolbar + │ └─CustomMultiChildLayout + │ └─LayoutId-[<_ToolbarSlot.middle>] + │ └─Builder + │ └─MediaQuery + │ └─DefaultTextStyle + │ └─Semantics + │ └─_AppBarTitleBox + │ └─Text + │ └─RichText + └─LayoutId-[<_ScaffoldSlot.floatingActionButton>] + └─MediaQuery + └─_FloatingActionButtonTransition + └─Stack + └─ScaleTransition + └─Transform + └─RotationTransition + └─Transform + └─FloatingActionButton + └─MergeSemantics + └─Hero + └─SizedBox + └─Offstage + └─TickerMode + └─_EffectiveTickerMode + └─KeyedSubtree-[GlobalKey#00000] + └─Tooltip + └─OverlayPortal + └─_OverlayPortal + └─_ExclusiveMouseRegion + └─Listener + └─Semantics + └─RawMaterialButton + └─Semantics + └─_InputPadding + └─ConstrainedBox + └─Material + └─_MaterialInterior + └─PhysicalShape + └─_ShapeBorderPaint + └─CustomPaint + └─NotificationListener + └─_InkFeatures-[GlobalKey#00000 ink renderer] + └─AnimatedDefaultTextStyle + └─DefaultTextStyle + └─InkWell + └─_InkResponseStateWidget + └─_ParentInkResponseProvider + └─Actions + └─_ActionsScope + └─Focus + └─_FocusInheritedScope + └─Semantics + └─MouseRegion + └─Builder + └─DefaultSelectionStyle + └─Semantics + └─GestureDetector + └─RawGestureDetector + └─Listener + └─Builder + └─IconTheme + └─Padding + └─Center + └─Builder + └─IconTheme + └─Icon + └─Semantics + └─ExcludeSemantics + └─SizedBox + └─Center + └─RichText diff --git a/packages/devtools_app/test/test_infra/goldens/inspector_service_node_summary.txt b/packages/devtools_app/test/test_infra/goldens/inspector_service_node_summary.txt new file mode 100644 index 00000000000..b842776e6c8 --- /dev/null +++ b/packages/devtools_app/test/test_infra/goldens/inspector_service_node_summary.txt @@ -0,0 +1,8 @@ +MaterialApp + └─Scaffold + ├─Center + │ └─Text + ├─AppBar + │ └─Text + └─FloatingActionButton + └─Icon diff --git a/packages/devtools_app/test/test_infra/goldens/inspector_service_tree_no_summary.txt b/packages/devtools_app/test/test_infra/goldens/inspector_service_tree_no_summary.txt new file mode 100644 index 00000000000..0f624db3db7 --- /dev/null +++ b/packages/devtools_app/test/test_infra/goldens/inspector_service_tree_no_summary.txt @@ -0,0 +1,260 @@ +[root] + └─View + └─RawView + └─_RawViewInternal-[_DeprecatedRawViewKey FlutterView#00000] + └─_ViewScope + └─_PipelineOwnerScope + └─_MediaQueryFromView + └─MediaQuery + └─FocusTraversalGroup + └─Focus + └─_FocusInheritedScope + └─_FocusScopeWithExternalFocusNode + └─_FocusInheritedScope + └─MyApp + └─MaterialApp + └─ScrollConfiguration + └─HeroControllerScope + └─Focus + └─_FocusInheritedScope + └─Semantics + └─WidgetsApp-[GlobalObjectKey _MaterialAppState#00000] + └─RootRestorationScope + └─UnmanagedRestorationScope + └─RestorationScope + └─UnmanagedRestorationScope + └─SharedAppData + └─_SharedAppModel + └─NotificationListener + └─Shortcuts + └─Focus + └─_FocusInheritedScope + └─Semantics + └─DefaultTextEditingShortcuts + └─Shortcuts + └─Focus + └─_FocusInheritedScope + └─Semantics + └─Actions + └─_ActionsScope + └─FocusTraversalGroup + └─Focus + └─_FocusInheritedScope + └─TapRegionSurface + └─ShortcutRegistrar + └─_ShortcutRegistrarScope + └─Shortcuts + └─Focus + └─_FocusInheritedScope + └─Semantics + └─Localizations + └─Semantics + └─_LocalizationsScope-[GlobalKey#00000] + └─Directionality + └─Title + └─CheckedModeBanner + └─Banner + └─CustomPaint + └─ValueListenableBuilder + └─DefaultTextStyle + └─Builder + └─ScaffoldMessenger + └─_ScaffoldMessengerScope + └─DefaultSelectionStyle + └─AnimatedTheme + └─Theme + └─_InheritedTheme + └─CupertinoTheme + └─InheritedCupertinoTheme + └─IconTheme + └─IconTheme + └─DefaultSelectionStyle + └─FocusScope + └─Semantics + └─_FocusInheritedScope + └─Navigator-[GlobalObjectKey _WidgetsAppState#00000] + └─HeroControllerScope + └─NotificationListener + └─Listener + └─AbsorbPointer + └─FocusTraversalGroup + └─Focus + └─_FocusInheritedScope + └─Focus + └─_FocusInheritedScope + └─UnmanagedRestorationScope + └─Overlay-[LabeledGlobalKey#00000] + └─_Theater + ├─_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#00000] + │ └─TickerMode + │ └─_EffectiveTickerMode + │ └─_RenderTheaterMarker + │ └─IgnorePointer + │ └─ModalBarrier + │ └─BlockSemantics + │ └─ExcludeSemantics + │ └─_ModalBarrierGestureDetector + │ └─RawGestureDetector + │ └─_GestureSemantics + │ └─Listener + │ └─Semantics + │ └─MouseRegion + │ └─ConstrainedBox + └─_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#00000] + └─TickerMode + └─_EffectiveTickerMode + └─_RenderTheaterMarker + └─Semantics + └─_ModalScope-[LabeledGlobalKey<_ModalScopeState>#00000] + └─AnimatedBuilder + └─RestorationScope + └─UnmanagedRestorationScope + └─_ModalScopeStatus + └─Offstage + └─PageStorage + └─Builder + └─Actions + └─_ActionsScope + └─PrimaryScrollController + └─_FocusScopeWithExternalFocusNode + └─Semantics + └─_FocusInheritedScope + └─RepaintBoundary + └─ListenableBuilder + └─_PageTransitionsThemeTransitions + └─_ZoomPageTransition + └─DualTransitionBuilder + └─_ZoomEnterTransition + └─SnapshotWidget + └─_ZoomExitTransition + └─SnapshotWidget + └─DualTransitionBuilder + └─_ZoomEnterTransition + └─SnapshotWidget + └─_ZoomExitTransition + └─SnapshotWidget + └─ListenableBuilder + └─IgnorePointer + └─RepaintBoundary-[GlobalKey#00000] + └─Builder + └─Semantics + └─Scaffold + └─_ScaffoldScope + └─ScrollNotificationObserver + └─NotificationListener + └─NotificationListener + └─_ScrollNotificationObserverScope + └─Material + └─AnimatedPhysicalModel + └─PhysicalModel + └─NotificationListener + └─_InkFeatures-[GlobalKey#00000 ink renderer] + └─AnimatedDefaultTextStyle + └─DefaultTextStyle + └─AnimatedBuilder + └─Actions + └─_ActionsScope + └─CustomMultiChildLayout + ├─LayoutId-[<_ScaffoldSlot.body>] + │ └─MediaQuery + │ └─_BodyBuilder + │ └─KeyedSubtree-[GlobalKey#00000] + │ └─Center + │ └─Text + │ └─RichText + ├─LayoutId-[<_ScaffoldSlot.appBar>] + │ └─MediaQuery + │ └─ConstrainedBox + │ └─FlexibleSpaceBarSettings + │ └─AppBar + │ └─Semantics + │ └─AnnotatedRegion + │ └─Material + │ └─AnimatedPhysicalModel + │ └─PhysicalModel + │ └─NotificationListener + │ └─_InkFeatures-[GlobalKey#00000 ink renderer] + │ └─AnimatedDefaultTextStyle + │ └─DefaultTextStyle + │ └─Semantics + │ └─Align + │ └─SafeArea + │ └─Padding + │ └─MediaQuery + │ └─ClipRect + │ └─CustomSingleChildLayout + │ └─Builder + │ └─IconTheme + │ └─DefaultTextStyle + │ └─NavigationToolbar + │ └─CustomMultiChildLayout + │ └─LayoutId-[<_ToolbarSlot.middle>] + │ └─Builder + │ └─MediaQuery + │ └─DefaultTextStyle + │ └─Semantics + │ └─_AppBarTitleBox + │ └─Text + │ └─RichText + └─LayoutId-[<_ScaffoldSlot.floatingActionButton>] + └─MediaQuery + └─_FloatingActionButtonTransition + └─Stack + └─ScaleTransition + └─Transform + └─RotationTransition + └─Transform + └─FloatingActionButton + └─MergeSemantics + └─Hero + └─SizedBox + └─Offstage + └─TickerMode + └─_EffectiveTickerMode + └─KeyedSubtree-[GlobalKey#00000] + └─Tooltip + └─OverlayPortal + └─_OverlayPortal + └─_ExclusiveMouseRegion + └─Listener + └─Semantics + └─RawMaterialButton + └─Semantics + └─_InputPadding + └─ConstrainedBox + └─Material + └─_MaterialInterior + └─PhysicalShape + └─_ShapeBorderPaint + └─CustomPaint + └─NotificationListener + └─_InkFeatures-[GlobalKey#00000 ink renderer] + └─AnimatedDefaultTextStyle + └─DefaultTextStyle + └─InkWell + └─_InkResponseStateWidget + └─_ParentInkResponseProvider + └─Actions + └─_ActionsScope + └─Focus + └─_FocusInheritedScope + └─Semantics + └─MouseRegion + └─Builder + └─DefaultSelectionStyle + └─Semantics + └─GestureDetector + └─RawGestureDetector + └─Listener + └─Builder + └─IconTheme + └─Padding + └─Center + └─Builder + └─IconTheme + └─Icon + └─Semantics + └─ExcludeSemantics + └─SizedBox + └─Center + └─RichText diff --git a/packages/devtools_app/test/test_infra/goldens/inspector_service_tree_summary.txt b/packages/devtools_app/test/test_infra/goldens/inspector_service_tree_summary.txt new file mode 100644 index 00000000000..05b579be5fb --- /dev/null +++ b/packages/devtools_app/test/test_infra/goldens/inspector_service_tree_summary.txt @@ -0,0 +1,10 @@ +[root] + └─MyApp + └─MaterialApp + └─Scaffold + ├─Center + │ └─Text + ├─AppBar + │ └─Text + └─FloatingActionButton + └─Icon diff --git a/packages/devtools_app/test/test_infra/goldens/integration_animated_physical_model_selected.png b/packages/devtools_app/test/test_infra/goldens/integration_animated_physical_model_selected.png index bee6b8ea7e5..21619330d73 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_animated_physical_model_selected.png and b/packages/devtools_app/test/test_infra/goldens/integration_animated_physical_model_selected.png differ diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_richtext_selected.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_richtext_selected.png index eabe0b1e298..b248e2ba1b3 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_inspector_richtext_selected.png and b/packages/devtools_app/test/test_infra/goldens/integration_inspector_richtext_selected.png differ diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_scaffold_selected.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_scaffold_selected.png index 5036dc29fd9..82b6a83205b 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_inspector_scaffold_selected.png and b/packages/devtools_app/test/test_infra/goldens/integration_inspector_scaffold_selected.png differ diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_select_center_details_tree.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_select_center_details_tree.png index 36c98de6922..81e5c81a052 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_inspector_select_center_details_tree.png and b/packages/devtools_app/test/test_infra/goldens/integration_inspector_select_center_details_tree.png differ diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_1_initial_load.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_1_initial_load.png index 708ce471a98..d264c96ca4b 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_1_initial_load.png and b/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_1_initial_load.png differ diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_2_error_selected.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_2_error_selected.png index 8abe4433803..1dcfaf04528 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_2_error_selected.png and b/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_errors_2_error_selected.png differ diff --git a/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_initial_load.png b/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_initial_load.png index 52ef297ed21..cf87f0d4d7e 100644 Binary files a/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_initial_load.png and b/packages/devtools_app/test/test_infra/goldens/integration_inspector_v2_initial_load.png differ