dispatchEvent method
- PointerEvent event,
- HitTestResult result
override
Handler for device events caught by the binding in live test mode.
PointerDownEvents received here will only print a diagnostic message
showing possible Finders that can be used to interact with the widget at
the location of result
.
Implementation
@override
void dispatchEvent(PointerEvent event, HitTestResult result) {
if (event is PointerDownEvent) {
final RenderObject innerTarget = result.path
.map((HitTestEntry candidate) => candidate.target)
.whereType<RenderObject>()
.first;
final Element? innerTargetElement = binding.renderViews.contains(innerTarget)
? null
: _lastWhereOrNull(
collectAllElementsFrom(binding.rootElement!, skipOffstage: true),
(Element element) => element.renderObject == innerTarget,
);
if (innerTargetElement == null) {
printToConsole('No widgets found at ${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;
printToConsole('Some possible finders for the widgets at ${event.position}:');
for (final Element element in candidates) {
if (totalNumber > 13) {
break;
}
totalNumber += 1; // optimistically assume we'll be able to describe it
final Widget widget = element.widget;
if (widget is Tooltip) {
final String message = widget.message ?? widget.richMessage!.toPlainText();
final Iterable<Element> matches = find.byTooltip(message).evaluate();
if (matches.length == 1) {
printToConsole(" find.byTooltip('$message')");
continue;
}
}
if (widget is Text) {
assert(descendantText == null);
assert(widget.data != null || widget.textSpan != null);
final String text = widget.data ?? widget.textSpan!.toPlainText();
final Iterable<Element> matches = find.text(text).evaluate();
descendantText = widget.data;
if (matches.length == 1) {
printToConsole(" find.text('$text')");
continue;
}
}
final Key? key = widget.key;
if (key is ValueKey<dynamic>) {
final String? keyLabel = switch (key.value) {
int() || double() || bool() => 'const ${key.runtimeType}(${key.value})',
final String value => "const Key('$value')",
_ => null,
};
if (keyLabel != null) {
final Iterable<Element> matches = find.byKey(key).evaluate();
if (matches.length == 1) {
printToConsole(' find.byKey($keyLabel)');
continue;
}
}
}
if (!_isPrivate(widget.runtimeType)) {
if (numberOfTypes < 5) {
final Iterable<Element> matches = find.byType(widget.runtimeType).evaluate();
if (matches.length == 1) {
printToConsole(' find.byType(${widget.runtimeType})');
numberOfTypes += 1;
continue;
}
}
if (descendantText != null && numberOfWithTexts < 5) {
final Iterable<Element> matches = find.widgetWithText(widget.runtimeType, descendantText).evaluate();
if (matches.length == 1) {
printToConsole(" find.widgetWithText(${widget.runtimeType}, '$descendantText')");
numberOfWithTexts += 1;
continue;
}
}
}
if (!_isPrivate(element.runtimeType)) {
final Iterable<Element> matches = find.byElementType(element.runtimeType).evaluate();
if (matches.length == 1) {
printToConsole(' find.byElementType(${element.runtimeType})');
continue;
}
}
totalNumber -= 1; // if we got here, we didn't actually find something to say about it
}
if (totalNumber == 0) {
printToConsole(' <could not come up with any unique finders>');
}
}
}