From 48bb12dfbe4560fb263201158115af70266991b8 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Mon, 27 Mar 2023 13:31:49 -0700 Subject: [PATCH] Make Element tree root generic (#123352) Make Element tree root generic --- .../lib/foundation/all_elements_bench.dart | 8 ++-- .../flutter_gallery/test/smoke_test.dart | 2 +- .../lib/fix_data/fix_widgets/fix_widgets.yaml | 11 +++++ packages/flutter/lib/src/widgets/binding.dart | 48 +++++++++++-------- .../flutter/lib/src/widgets/framework.dart | 27 ++++++++--- .../lib/src/widgets/widget_inspector.dart | 8 ++-- .../test/widgets/fast_reassemble_test.dart | 10 ++-- .../test/widgets/memory_allocations_test.dart | 2 +- .../test/widgets/run_app_async_test.dart | 4 +- .../test/widgets/widget_inspector_test.dart | 6 +-- .../widgets/widget_inspector_test_utils.dart | 4 +- .../flutter/test_fixes/widgets/widgets.dart | 3 ++ .../test_fixes/widgets/widgets.dart.expect | 3 ++ .../widgets/memory_allocations_test.dart | 2 +- .../flutter_test/lib/src/_matchers_web.dart | 2 +- packages/flutter_test/lib/src/binding.dart | 4 +- packages/flutter_test/lib/src/controller.dart | 2 +- packages/flutter_test/lib/src/finders.dart | 2 +- .../flutter_test/lib/src/widget_tester.dart | 4 +- 19 files changed, 96 insertions(+), 56 deletions(-) diff --git a/dev/benchmarks/microbenchmarks/lib/foundation/all_elements_bench.dart b/dev/benchmarks/microbenchmarks/lib/foundation/all_elements_bench.dart index 22f386946f..23dd6d5169 100644 --- a/dev/benchmarks/microbenchmarks/lib/foundation/all_elements_bench.dart +++ b/dev/benchmarks/microbenchmarks/lib/foundation/all_elements_bench.dart @@ -56,19 +56,19 @@ Future main() async { final Stopwatch watch = Stopwatch(); - print('flutter_test allElements benchmark... (${WidgetsBinding.instance.renderViewElement})'); + print('flutter_test allElements benchmark... (${WidgetsBinding.instance.rootElement})'); // Make sure we get enough elements to process for consistent benchmark runs - int elementCount = collectAllElementsFrom(WidgetsBinding.instance.renderViewElement!, skipOffstage: false).length; + int elementCount = collectAllElementsFrom(WidgetsBinding.instance.rootElement!, skipOffstage: false).length; while (elementCount < 2458) { await Future.delayed(Duration.zero); - elementCount = collectAllElementsFrom(WidgetsBinding.instance.renderViewElement!, skipOffstage: false).length; + elementCount = collectAllElementsFrom(WidgetsBinding.instance.rootElement!, skipOffstage: false).length; } print('element count: $elementCount'); watch.start(); for (int i = 0; i < _kNumIters; i += 1) { final List allElements = collectAllElementsFrom( - WidgetsBinding.instance.renderViewElement!, + WidgetsBinding.instance.rootElement!, skipOffstage: false, ).toList(); allElements.clear(); diff --git a/dev/integration_tests/flutter_gallery/test/smoke_test.dart b/dev/integration_tests/flutter_gallery/test/smoke_test.dart index f2154c00f0..77478f93c4 100644 --- a/dev/integration_tests/flutter_gallery/test/smoke_test.dart +++ b/dev/integration_tests/flutter_gallery/test/smoke_test.dart @@ -78,7 +78,7 @@ Future smokeDemo(WidgetTester tester, GalleryDemo demo) async { // Verify that the dumps are pretty. final String routeName = demo.routeName; - verifyToStringOutput('debugDumpApp', routeName, WidgetsBinding.instance.renderViewElement!.toStringDeep()); + verifyToStringOutput('debugDumpApp', routeName, WidgetsBinding.instance.rootElement!.toStringDeep()); verifyToStringOutput('debugDumpRenderTree', routeName, RendererBinding.instance.renderView.toStringDeep()); verifyToStringOutput('debugDumpLayerTree', routeName, RendererBinding.instance.renderView.debugLayer?.toStringDeep() ?? ''); diff --git a/packages/flutter/lib/fix_data/fix_widgets/fix_widgets.yaml b/packages/flutter/lib/fix_data/fix_widgets/fix_widgets.yaml index e7798262d8..42692a91f0 100644 --- a/packages/flutter/lib/fix_data/fix_widgets/fix_widgets.yaml +++ b/packages/flutter/lib/fix_data/fix_widgets/fix_widgets.yaml @@ -23,6 +23,17 @@ # * ListWheelScrollView: fix_list_wheel_scroll_view.yaml version: 1 transforms: + # Changes made in https://github.com/flutter/flutter/pull/123352 + - title: "Migrate to 'rootElement'" + date: 2023-03-13 + element: + uris: [ 'widgets.dart', 'material.dart', 'cupertino.dart' ] + field: 'renderViewElement' + inClass: 'WidgetsBinding' + changes: + - kind: 'rename' + newName: 'rootElement' + # Changes made in https://github.com/flutter/flutter/pull/122555 - title: "Migrate to 'decorationClipBehavior'" date: 2023-03-13 diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart index c472cfd173..9ccff18545 100644 --- a/packages/flutter/lib/src/widgets/binding.dart +++ b/packages/flutter/lib/src/widgets/binding.dart @@ -479,8 +479,8 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB } Future _forceRebuild() { - if (renderViewElement != null) { - buildOwner!.reassemble(renderViewElement!, null); + if (rootElement != null) { + buildOwner!.reassemble(rootElement!, null); return endOfFrame; } return Future.value(); @@ -889,8 +889,8 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB } try { - if (renderViewElement != null) { - buildOwner!.buildScope(renderViewElement!); + if (rootElement != null) { + buildOwner!.buildScope(rootElement!); } super.drawFrame(); buildOwner!.finalizeTree(); @@ -914,12 +914,20 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB } } - /// The [Element] that is at the root of the hierarchy (and which wraps the - /// [RenderView] object at the root of the rendering hierarchy). + /// The [Element] that is at the root of the element tree hierarchy. /// /// This is initialized the first time [runApp] is called. - Element? get renderViewElement => _renderViewElement; - Element? _renderViewElement; + Element? get rootElement => _rootElement; + Element? _rootElement; + + /// Deprecated. Will be removed in a future version of Flutter. + /// + /// Use [rootElement] instead. + @Deprecated( + 'Use rootElement instead. ' + 'This feature was deprecated after v3.9.0-16.0.pre.' + ) + Element? get renderViewElement => rootElement; bool _readyToProduceFrames = false; @@ -951,7 +959,7 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB }); } - /// Takes a widget and attaches it to the [renderViewElement], creating it if + /// Takes a widget and attaches it to the [rootElement], creating it if /// necessary. /// /// This is called by [runApp] to configure the widget tree. @@ -961,23 +969,23 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB /// * [RenderObjectToWidgetAdapter.attachToRenderTree], which inflates a /// widget and attaches it to the render tree. void attachRootWidget(Widget rootWidget) { - final bool isBootstrapFrame = renderViewElement == null; + final bool isBootstrapFrame = rootElement == null; _readyToProduceFrames = true; - _renderViewElement = RenderObjectToWidgetAdapter( + _rootElement = RenderObjectToWidgetAdapter( container: renderView, debugShortDescription: '[root]', child: rootWidget, - ).attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement?); + ).attachToRenderTree(buildOwner!, rootElement as RenderObjectToWidgetElement?); if (isBootstrapFrame) { SchedulerBinding.instance.ensureVisualUpdate(); } } - /// Whether the [renderViewElement] has been initialized. + /// Whether the [rootElement] has been initialized. /// /// This will be false until [runApp] is called (or [WidgetTester.pumpWidget] /// is called in the context of a [TestWidgetsFlutterBinding]). - bool get isRootWidgetAttached => _renderViewElement != null; + bool get isRootWidgetAttached => _rootElement != null; @override Future performReassemble() { @@ -986,8 +994,8 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB return true; }()); - if (renderViewElement != null) { - buildOwner!.reassemble(renderViewElement!, BindingBase.debugReassembleConfig); + if (rootElement != null) { + buildOwner!.reassemble(rootElement!, BindingBase.debugReassembleConfig); } return super.performReassemble(); } @@ -1069,8 +1077,8 @@ String _debugDumpAppString() { const String mode = kDebugMode ? 'DEBUG MODE' : kReleaseMode ? 'RELEASE MODE' : 'PROFILE MODE'; final StringBuffer buffer = StringBuffer(); buffer.writeln('${WidgetsBinding.instance.runtimeType} - $mode'); - if (WidgetsBinding.instance.renderViewElement != null) { - buffer.writeln(WidgetsBinding.instance.renderViewElement!.toStringDeep()); + if (WidgetsBinding.instance.rootElement != null) { + buffer.writeln(WidgetsBinding.instance.rootElement!.toStringDeep()); } else { buffer.writeln(''); } @@ -1148,7 +1156,7 @@ class RenderObjectToWidgetAdapter extends RenderObjectWi String toStringShort() => debugShortDescription ?? super.toStringShort(); } -/// A [RootRenderObjectElement] that is hosted by a [RenderObject]. +/// The root of the element tree that is hosted by a [RenderObject]. /// /// This element class is the instantiation of a [RenderObjectToWidgetAdapter] /// widget. It can be used only as the root of an [Element] tree (it cannot be @@ -1158,7 +1166,7 @@ class RenderObjectToWidgetAdapter extends RenderObjectWi /// whose container is the [RenderView] that connects to the Flutter engine. In /// this usage, it is normally instantiated by the bootstrapping logic in the /// [WidgetsFlutterBinding] singleton created by [runApp]. -class RenderObjectToWidgetElement extends RootRenderObjectElement { +class RenderObjectToWidgetElement extends RenderObjectElement with RootElementMixin { /// Creates an element that is hosted by a [RenderObject]. /// /// The [RenderObject] created by this element is not automatically set as a diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 7c06cecb06..526d41cb14 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -2499,7 +2499,7 @@ abstract class BuildContext { /// Additional build owners can be built to manage off-screen widget trees. /// /// To assign a build owner to a tree, use the -/// [RootRenderObjectElement.assignOwner] method on the root element of the +/// [RootElementMixin.assignOwner] method on the root element of the /// widget tree. /// /// {@tool dartpad} @@ -6323,14 +6323,29 @@ abstract class RenderObjectElement extends Element { } } -/// The element at the root of the tree. +/// Deprecated. Unused in the framework and will be removed in a future version +/// of Flutter. +/// +/// Classes that extend this class can extend [RenderObjectElement] and mixin +/// [RootElementMixin] instead. +@Deprecated( + 'Use RootElementMixin instead. ' + 'This feature was deprecated after v3.9.0-16.0.pre.' +) +abstract class RootRenderObjectElement extends RenderObjectElement with RootElementMixin { + /// Initializes fields for subclasses. + @Deprecated( + 'Use RootElementMixin instead. ' + 'This feature was deprecated after v3.9.0-16.0.pre.' + ) + RootRenderObjectElement(super.widget); +} + +/// Mixin for the element at the root of the tree. /// /// Only root elements may have their owner set explicitly. All other /// elements inherit their owner from their parent. -abstract class RootRenderObjectElement extends RenderObjectElement { - /// Initializes fields for subclasses. - RootRenderObjectElement(super.widget); - +mixin RootElementMixin on Element { /// Set the owner of the element. The owner will be propagated to all the /// descendants of this element. /// diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index d2b5f7d282..54607226d2 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -914,8 +914,8 @@ mixin WidgetInspectorService { @protected Future forceRebuild() { final WidgetsBinding binding = WidgetsBinding.instance; - if (binding.renderViewElement != null) { - binding.buildOwner!.reassemble(binding.renderViewElement!, null); + if (binding.rootElement != null) { + binding.buildOwner!.reassemble(binding.rootElement!, null); return binding.endOfFrame; } return Future.value(); @@ -1832,7 +1832,7 @@ mixin WidgetInspectorService { } Map? _getRootWidget(String groupName) { - return _nodeToJson(WidgetsBinding.instance.renderViewElement?.toDiagnosticsNode(), InspectorSerializationDelegate(groupName: groupName, service: this)); + return _nodeToJson(WidgetsBinding.instance.rootElement?.toDiagnosticsNode(), InspectorSerializationDelegate(groupName: groupName, service: this)); } /// Returns a JSON representation of the [DiagnosticsNode] for the root @@ -1846,7 +1846,7 @@ mixin WidgetInspectorService { Map? Function(DiagnosticsNode, InspectorSerializationDelegate)? addAdditionalPropertiesCallback, }) { return _nodeToJson( - WidgetsBinding.instance.renderViewElement?.toDiagnosticsNode(), + WidgetsBinding.instance.rootElement?.toDiagnosticsNode(), InspectorSerializationDelegate( groupName: groupName, subtreeDepth: 1000000, diff --git a/packages/flutter/test/widgets/fast_reassemble_test.dart b/packages/flutter/test/widgets/fast_reassemble_test.dart index 128b5a561a..1269992c11 100644 --- a/packages/flutter/test/widgets/fast_reassemble_test.dart +++ b/packages/flutter/test/widgets/fast_reassemble_test.dart @@ -17,34 +17,34 @@ void main() { expect(Fizz.count, 0); DebugReassembleConfig config = DebugReassembleConfig(widgetName: 'Bar'); - WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.renderViewElement!, config); + WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.rootElement!, config); expect(Foo.count, 0); expect(Bar.count, 1); expect(Fizz.count, 1); config = DebugReassembleConfig(widgetName: 'Fizz'); - WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.renderViewElement!, config); + WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.rootElement!, config); expect(Foo.count, 0); expect(Bar.count, 1); expect(Fizz.count, 2); config = DebugReassembleConfig(widgetName: 'NoMatch'); - WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.renderViewElement!, config); + WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.rootElement!, config); expect(Foo.count, 0); expect(Bar.count, 1); expect(Fizz.count, 2); config = DebugReassembleConfig(); - WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.renderViewElement!, config); + WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.rootElement!, config); expect(Foo.count, 1); expect(Bar.count, 2); expect(Fizz.count, 3); - WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.renderViewElement!, null); + WidgetsBinding.instance.buildOwner!.reassemble(WidgetsBinding.instance.rootElement!, null); expect(Foo.count, 2); expect(Bar.count, 3); diff --git a/packages/flutter/test/widgets/memory_allocations_test.dart b/packages/flutter/test/widgets/memory_allocations_test.dart index 26c9586a06..dbb44ac661 100644 --- a/packages/flutter/test/widgets/memory_allocations_test.dart +++ b/packages/flutter/test/widgets/memory_allocations_test.dart @@ -58,7 +58,7 @@ class _TestLeafRenderObjectWidget extends LeafRenderObjectWidget { } } -class _TestElement extends RootRenderObjectElement{ +class _TestElement extends RenderObjectElement with RootElementMixin { _TestElement(): super(_TestLeafRenderObjectWidget()); void makeInactive() { diff --git a/packages/flutter/test/widgets/run_app_async_test.dart b/packages/flutter/test/widgets/run_app_async_test.dart index d0901ec08c..38b30e87ed 100644 --- a/packages/flutter/test/widgets/run_app_async_test.dart +++ b/packages/flutter/test/widgets/run_app_async_test.dart @@ -50,9 +50,9 @@ void main() { ), ); // Rendering tree is not built synchronously. - expect(WidgetsBinding.instance.renderViewElement, isNull); + expect(WidgetsBinding.instance.rootElement, isNull); fakeAsync.flushTimers(); - expect(WidgetsBinding.instance.renderViewElement, isNotNull); + expect(WidgetsBinding.instance.rootElement, isNotNull); }); }); } diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index bf9342c803..e19476dc7e 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -873,7 +873,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { final List chainElements = jsonList! as List; final List expectedChain = elementB.debugGetDiagnosticChain().reversed.toList(); // Sanity check that the chain goes back to the root. - expect(expectedChain.first, tester.binding.renderViewElement); + expect(expectedChain.first, tester.binding.rootElement); expect(chainElements.length, equals(expectedChain.length)); for (int i = 0; i < expectedChain.length; i += 1) { @@ -2081,7 +2081,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { final List chainElements = jsonList! as List; final List expectedChain = elementB.debugGetDiagnosticChain().reversed.toList(); // Sanity check that the chain goes back to the root. - expect(expectedChain.first, tester.binding.renderViewElement); + expect(expectedChain.first, tester.binding.rootElement); expect(chainElements.length, equals(expectedChain.length)); for (int i = 0; i < expectedChain.length; i += 1) { @@ -2327,7 +2327,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { // directories so we get an empty tree other than the root that is always // included. final Object? rootWidget = service.toObject(rootJson['valueId']! as String); - expect(rootWidget, equals(WidgetsBinding.instance.renderViewElement)); + expect(rootWidget, equals(WidgetsBinding.instance.rootElement)); List childrenJson = rootJson['children']! as List; // There are no summary tree children. expect(childrenJson.length, equals(0)); diff --git a/packages/flutter/test/widgets/widget_inspector_test_utils.dart b/packages/flutter/test/widgets/widget_inspector_test_utils.dart index 0ac9091ed7..f7b3686638 100644 --- a/packages/flutter/test/widgets/widget_inspector_test_utils.dart +++ b/packages/flutter/test/widgets/widget_inspector_test_utils.dart @@ -106,8 +106,8 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService { rebuildCount++; final WidgetsBinding binding = WidgetsBinding.instance; - if (binding.renderViewElement != null) { - binding.buildOwner!.reassemble(binding.renderViewElement!, null); + if (binding.rootElement != null) { + binding.buildOwner!.reassemble(binding.rootElement!, null); } } diff --git a/packages/flutter/test_fixes/widgets/widgets.dart b/packages/flutter/test_fixes/widgets/widgets.dart index 97c0b47a3b..0ba50ed692 100644 --- a/packages/flutter/test_fixes/widgets/widgets.dart +++ b/packages/flutter/test_fixes/widgets/widgets.dart @@ -12,6 +12,9 @@ void main() { Object object; TickerProvider vsync; + // Changes made in https://github.com/flutter/flutter/pull/123352 + WidgetsBinding.instance.renderViewElement; + // Changes made in https://github.com/flutter/flutter/pull/119647 MediaQueryData.fromWindow(View.of(context)); diff --git a/packages/flutter/test_fixes/widgets/widgets.dart.expect b/packages/flutter/test_fixes/widgets/widgets.dart.expect index f5c55ddc64..a74fa0e7c5 100644 --- a/packages/flutter/test_fixes/widgets/widgets.dart.expect +++ b/packages/flutter/test_fixes/widgets/widgets.dart.expect @@ -12,6 +12,9 @@ void main() { Object object; TickerProvider vsync; + // Changes made in https://github.com/flutter/flutter/pull/123352 + WidgetsBinding.instance.rootElement; + // Changes made in https://github.com/flutter/flutter/pull/119647 MediaQueryData.fromView(View.of(context)); diff --git a/packages/flutter/test_release/widgets/memory_allocations_test.dart b/packages/flutter/test_release/widgets/memory_allocations_test.dart index 7ae5790984..166725ab6b 100644 --- a/packages/flutter/test_release/widgets/memory_allocations_test.dart +++ b/packages/flutter/test_release/widgets/memory_allocations_test.dart @@ -55,7 +55,7 @@ class _TestRenderObject extends RenderObject { Rect get semanticBounds => throw UnimplementedError(); } -class _TestElement extends RootRenderObjectElement{ +class _TestElement extends RenderObjectElement with RootElementMixin { _TestElement(): super(_TestLeafRenderObjectWidget()); void makeInactive() { diff --git a/packages/flutter_test/lib/src/_matchers_web.dart b/packages/flutter_test/lib/src/_matchers_web.dart index 11c8d815b1..33740b76f0 100644 --- a/packages/flutter_test/lib/src/_matchers_web.dart +++ b/packages/flutter_test/lib/src/_matchers_web.dart @@ -57,7 +57,7 @@ class MatchesGoldenFile extends AsyncMatcher { final RenderObject renderObject = _findRepaintBoundary(element); final Size size = renderObject.paintBounds.size; final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.instance; - final Element e = binding.renderViewElement!; + final Element e = binding.rootElement!; final ui.FlutterView view = binding.platformDispatcher.implicitView!; // Unlike `flutter_tester`, we don't have the ability to render an element diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart index 44ce461903..e8511b2695 100644 --- a/packages/flutter_test/lib/src/binding.dart +++ b/packages/flutter_test/lib/src/binding.dart @@ -908,7 +908,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase // directly called again. DiagnosticsNode treeDump; try { - treeDump = renderViewElement?.toDiagnosticsNode() ?? DiagnosticsNode.message(''); + treeDump = rootElement?.toDiagnosticsNode() ?? DiagnosticsNode.message(''); // We try to stringify the tree dump here (though we immediately discard the result) because // we want to make sure that if it can't be serialised, we replace it with a message that // says the tree could not be serialised. Otherwise, the real exception might get obscured @@ -1372,7 +1372,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { assert(inTest); try { debugBuildingDirtyElements = true; - buildOwner!.buildScope(renderViewElement!); + buildOwner!.buildScope(rootElement!); if (_phase != EnginePhase.build) { pipelineOwner.flushLayout(); if (_phase != EnginePhase.layout) { diff --git a/packages/flutter_test/lib/src/controller.dart b/packages/flutter_test/lib/src/controller.dart index fcdb3a26aa..1aa29aa798 100644 --- a/packages/flutter_test/lib/src/controller.dart +++ b/packages/flutter_test/lib/src/controller.dart @@ -379,7 +379,7 @@ abstract class WidgetController { /// using [Iterator.moveNext]. Iterable get allElements { TestAsyncUtils.guardSync(); - return collectAllElementsFrom(binding.renderViewElement!, skipOffstage: false); + return collectAllElementsFrom(binding.rootElement!, skipOffstage: false); } /// The matching element in the widget tree. diff --git a/packages/flutter_test/lib/src/finders.dart b/packages/flutter_test/lib/src/finders.dart index 33cac7eb06..649df646f0 100644 --- a/packages/flutter_test/lib/src/finders.dart +++ b/packages/flutter_test/lib/src/finders.dart @@ -493,7 +493,7 @@ abstract class Finder { @protected Iterable get allCandidates { return collectAllElementsFrom( - WidgetsBinding.instance.renderViewElement!, + WidgetsBinding.instance.rootElement!, skipOffstage: skipOffstage, ); } diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart index c36c632240..fcd24720aa 100644 --- a/packages/flutter_test/lib/src/widget_tester.dart +++ b/packages/flutter_test/lib/src/widget_tester.dart @@ -750,7 +750,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker 'your widget tree in a RootRestorationScope?', ); return TestAsyncUtils.guard(() async { - final Widget widget = ((binding.renderViewElement! as RenderObjectToWidgetElement).widget as RenderObjectToWidgetAdapter).child!; + final Widget widget = ((binding.rootElement! as RenderObjectToWidgetElement).widget as RenderObjectToWidgetAdapter).child!; final TestRestorationData restorationData = binding.restorationManager.restorationData; runApp(Container(key: UniqueKey())); await pump(); @@ -863,7 +863,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker .whereType() .first; final Element? innerTargetElement = _lastWhereOrNull( - collectAllElementsFrom(binding.renderViewElement!, skipOffstage: true), + collectAllElementsFrom(binding.rootElement!, skipOffstage: true), (Element element) => element.renderObject == innerTarget, ); if (innerTargetElement == null) {