dispatchEvent method

  1. @override
void dispatchEvent (PointerEvent event, HitTestResult result)
override

Handler for device events caught by the binding in live test mode.

Implementation

@override
void dispatchEvent(PointerEvent event, HitTestResult result) {
  if (event is PointerDownEvent) {
    final RenderObject innerTarget = result.path.firstWhere(
      (HitTestEntry candidate) => candidate.target is RenderObject,
    ).target;
    final Element innerTargetElement = collectAllElementsFrom(
      binding.renderViewElement,
      skipOffstage: true,
    ).lastWhere(
      (Element element) => element.renderObject == innerTarget,
      orElse: () => null,
    );
    if (innerTargetElement == null) {
      debugPrint('No widgets found at ${binding.globalToLocal(event.position)}.');
      return;
    }
    final List<Element> candidates = <Element>[];
    innerTargetElement.visitAncestorElements((Element element) {
      candidates.add(element);
      return true;
    });
    assert(candidates.isNotEmpty);
    String descendantText;
    int numberOfWithTexts = 0;
    int numberOfTypes = 0;
    int totalNumber = 0;
    debugPrint('Some possible finders for the widgets at ${binding.globalToLocal(event.position)}:');
    for (Element element in candidates) {
      if (totalNumber > 13) // an arbitrary number of finders that feels useful without being overwhelming
        break;
      totalNumber += 1; // optimistically assume we'll be able to describe it

      if (element.widget is Tooltip) {
        final Tooltip widget = element.widget;
        final Iterable<Element> matches = find.byTooltip(widget.message).evaluate();
        if (matches.length == 1) {
          debugPrint('  find.byTooltip(\'${widget.message}\')');
          continue;
        }
      }

      if (element.widget is Text) {
        assert(descendantText == null);
        final Text widget = element.widget;
        final Iterable<Element> matches = find.text(widget.data).evaluate();
        descendantText = widget.data;
        if (matches.length == 1) {
          debugPrint('  find.text(\'${widget.data}\')');
          continue;
        }
      }

      if (element.widget.key is ValueKey<dynamic>) {
        final ValueKey<dynamic> key = element.widget.key;
        String keyLabel;
        if (key is ValueKey<int> ||
            key is ValueKey<double> ||
            key is ValueKey<bool>) {
          keyLabel = 'const ${element.widget.key.runtimeType}(${key.value})';
        } else if (key is ValueKey<String>) {
          keyLabel = 'const Key(\'${key.value}\')';
        }
        if (keyLabel != null) {
          final Iterable<Element> matches = find.byKey(key).evaluate();
          if (matches.length == 1) {
            debugPrint('  find.byKey($keyLabel)');
            continue;
          }
        }
      }

      if (!_isPrivate(element.widget.runtimeType)) {
        if (numberOfTypes < 5) {
          final Iterable<Element> matches = find.byType(element.widget.runtimeType).evaluate();
          if (matches.length == 1) {
            debugPrint('  find.byType(${element.widget.runtimeType})');
            numberOfTypes += 1;
            continue;
          }
        }

        if (descendantText != null && numberOfWithTexts < 5) {
          final Iterable<Element> matches = find.widgetWithText(element.widget.runtimeType, descendantText).evaluate();
          if (matches.length == 1) {
            debugPrint('  find.widgetWithText(${element.widget.runtimeType}, \'$descendantText\')');
            numberOfWithTexts += 1;
            continue;
          }
        }
      }

      if (!_isPrivate(element.runtimeType)) {
        final Iterable<Element> matches = find.byElementType(element.runtimeType).evaluate();
        if (matches.length == 1) {
          debugPrint('  find.byElementType(${element.runtimeType})');
          continue;
        }
      }

      totalNumber -= 1; // if we got here, we didn't actually find something to say about it
    }
    if (totalNumber == 0)
      debugPrint('  <could not come up with any unique finders>');
  }
}