When the RenderObject "of" a StatelessWidget (the RenderObject of its first child Element that has one) does not add itself to the HitTestResult when hit, tapping that StatelessWidget in a test results in a "missed hit test" warning. Examples of such RenderObjects are those created by Transform, Opacity, and AbsorbPointer.
I think there should be no warning in these cases as the StatelessWidget in clearly hit.
Two examples:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('with $Transform', (tester) async {
await tester.pumpWidget(Center(
child: Button(
onTap: () => print("tap 1"),
),
));
await tester.tap(find.byType(Button));
});
testWidgets('with $AbsorbPointer', (tester) async {
await tester.pumpWidget(Center(
child: GestureDetector(
onTap: () => print("tap 2"),
child: const Dummy(),
),
));
await tester.tap(find.byType(Dummy));
});
}
class Button extends StatelessWidget {
const Button({Key? key, required this.onTap}) : super(key: key);
final VoidCallback onTap;
@override
Widget build(BuildContext context) => Transform.scale(
scale: 1.1,
child: GestureDetector(
onTap: onTap,
child: Container(
width: 40,
height: 40,
color: const Color(0xffff0000),
),
),
);
}
class Dummy extends StatelessWidget {
const Dummy({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => const AbsorbPointer(
child: Padding(
padding: EdgeInsets.all(10),
child: SizedBox(
width: 20,
height: 20,
),
),
);
}
Output:
Warning: A call to tap() with finder "exactly one widget with type "Button" (ignoring offstage widgets): Button" derived an Offset (Offset(400.0, 300.0)) that would not hit test on the specified widget.
Maybe the widget is actually off-screen, or another widget is obscuring it, or the widget cannot receive pointer events.
The finder corresponds to this RenderBox: RenderTransform#bdd63 relayoutBoundary=up1
The hit test result at that offset is: HitTestResult(_RenderColoredBox#1700a@Offset(20.0, 20.0), RenderConstrainedBox#5cc34@Offset(20.0, 20.0), RenderPointerListener#3ffda@Offset(20.0, 20.0), RenderSemanticsGestureHandler#f5878@Offset(20.0, 20.0), RenderPositionedBox#29595@Offset(400.0, 300.0), HitTestEntry#5c7be(RenderView#0c197), HitTestEntry#cedf5(<AutomatedTestWidgetsFlutterBinding>))
#0 WidgetController._getElementPoint (package:flutter_test/src/controller.dart:956:25)
#1 WidgetController.getCenter (package:flutter_test/src/controller.dart:839:12)
#2 WidgetController.tap (package:flutter_test/src/controller.dart:273:18)
#3 main.<anonymous closure> (file:///Users/sander/Development/flutter_bug/test/widget_test.dart:12:18)
<asynchronous suspension>
#4 StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:125:47)
<asynchronous suspension>
To silence this warning, pass "warnIfMissed: false" to "tap()".
To make this warning fatal, set WidgetController.hitTestWarningShouldBeFatal to true.
and the same for the other test.
Expected output: no warning.
[✓] Flutter (Channel unknown, 2.10.2, on macOS 12.3 21E230 darwin-arm, locale en-NL)
• Flutter version 2.10.2 at /Users/.../flutter
• Upstream repository unknown
• Framework revision 097d3313d8 (5 weeks ago), 2022-02-18 19:33:08 -0600
• Engine revision a83ed0e5e3
• Dart version 2.16.1
• DevTools version 2.9.2
When the
RenderObject"of" aStatelessWidget(theRenderObjectof its first childElementthat has one) does not add itself to theHitTestResultwhen hit, tapping thatStatelessWidgetin a test results in a "missed hit test" warning. Examples of suchRenderObjects are those created byTransform,Opacity, andAbsorbPointer.I think there should be no warning in these cases as the
StatelessWidgetin clearly hit.Two examples:
Output:
and the same for the other test.
Expected output: no warning.