createWidgetTree function

WidgetTreeNode? createWidgetTree(
  1. Element e, {
  2. required WidgetTester tester,
  3. required WidgetTreeOptions options,
})

Recursively creates a widget tree from the given element.

Implementation

WidgetTreeNode? createWidgetTree(
  Element e, {
  required WidgetTester tester,
  required WidgetTreeOptions options,
}) {
  final widget = e.widget;
  final children = <WidgetTreeNode>[];

  e.visitChildren((element) {
    final child = createWidgetTree(
      element,
      tester: tester,
      options: options,
    );
    if (child != null) children.add(child);
  });

  final finder = find.byElementPredicate((el) => el == e);

  final type = widget.runtimeType.toString();
  final typeWithoutGeneric = type.split('<').first;
  final bounds = switch (options.includeWidgetBounds) {
    IncludeWidgetBounds.none => null,
    IncludeWidgetBounds.relative => () {
        final renderObject = e.renderObject;
        if (renderObject is RenderBox) {
          final pos = renderObject.localToGlobal(Offset.zero,
              ancestor: e.renderObject?.parent);
          return Rect.fromLTWH(
            pos.dx,
            pos.dy,
            renderObject.size.width,
            renderObject.size.height,
          );
        }

        if (renderObject is RenderSliverList) {
          // We cannot just get the bounds of the RenderSliverList
          final constraints = renderObject.constraints;

          // Get the SliverGeometry which contains positioning info
          final geometry = renderObject.geometry;

          if (geometry != null && !geometry.visible) {
            // If the sliver is not visible, return null or an empty rect
            return null;
          }

          // Calculate the bounds based on paintOrigin and paintExtent
          return Rect.fromLTWH(
            constraints.axis == Axis.vertical ? 0 : geometry!.paintOrigin,
            constraints.axis == Axis.vertical ? geometry!.paintOrigin : 0,
            constraints.axis == Axis.vertical
                ? constraints.crossAxisExtent
                : geometry!.paintExtent,
            constraints.axis == Axis.vertical
                ? geometry!.paintExtent
                : constraints.crossAxisExtent,
          );
        }

        return null;
      }(),
    IncludeWidgetBounds.absolute => tester.getRect(finder),
  };

  // ignore: invalid_use_of_protected_member
  final constraints = e.renderObject?.constraints;

  if (options.strippedWidgets.contains(type) ||
      options.strippedWidgets.contains(typeWithoutGeneric) ||
      (options.stripPrivateWidgets && type.startsWith('_'))) {
    if (children.isNotEmpty) {
      return children.length == 1
          ? children.first
          : WidgetTreeNode(widget, children, finder,
              bounds: bounds, constraints: constraints);
    } else {
      return null;
    }
  }

  return WidgetTreeNode(widget, children, finder,
      bounds: bounds, constraints: constraints);
}