Skip to content

False positives for "missed hit test" warning for RenderObjects that don't add themselves to the HitTestResult #100758

Closed

Description

@spkersten

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

Activity

  1. darshankawar commented on Mar 25, 2022

    @darshankawar
    Member

    Thanks for the report. I do see same behavior on latest stable and master.

    stable, master flutter doctor -v
    
    [✓] Flutter (Channel stable, 2.10.3, on macOS 12.2.1 21D62 darwin-x64, locale
        en-GB)
        • Flutter version 2.10.3 at /Users/dhs/documents/fluttersdk/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 7e9793dee1 (11 hours ago), 2022-03-02 11:23:12 -0600
        • Engine revision bd539267b4
        • Dart version 2.16.1
        • DevTools version 2.9.2
    
    [!] Xcode - develop for iOS and macOS (Xcode 12.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        ! Flutter recommends a minimum Xcode version of 13.
          Download the latest version or update via the Mac App Store.
        • CocoaPods version 1.11.2
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] VS Code (version 1.62.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.21.0
    
    [✓] Connected device (5 available)
        • SM G975F (mobile)       • RZ8M802WY0X • android-arm64   • Android 11 (API 30)
        • Darshan's iphone (mobile)  • 21150b119064aecc249dfcfe05e259197461ce23 •
          ios            • iOS 14.4.1 18D61
        • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729     •
          ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
        • macOS (desktop)            • macos                                    •
          darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
        • Chrome (web)               • chrome                                   •
          web-javascript • Google Chrome 98.0.4758.80
    
    [✓] HTTP Host Availability
        • All required HTTP hosts are available
    
    ! Doctor found issues in 1 category.
    
    [✓] Flutter (Channel master, 2.13.0-0.0.pre.242, on macOS 12.2.1 21D62
        darwin-x64, locale en-GB)
        • Flutter version 2.13.0-0.0.pre.242 at
          /Users/dhs/documents/fluttersdk/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 10142b5817 (4 hours ago), 2022-03-24 18:47:19 -0700
        • Engine revision 816c8651d8
        • Dart version 2.17.0 (build 2.17.0-232.0.dev)
        • DevTools version 2.11.4
    
    [!] Xcode - develop for iOS and macOS (Xcode 12.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        ! Flutter recommends a minimum Xcode version of 13.
          Download the latest version or update via the Mac App Store.
        • CocoaPods version 1.11.2
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] VS Code (version 1.62.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.21.0
    
    [✓] Connected device (5 available)
        • SM G975F (mobile)       • RZ8M802WY0X • android-arm64   • Android 11 (API 30)
        • Darshan's iphone (mobile)  • 21150b119064aecc249dfcfe05e259197461ce23 •
          ios            • iOS 14.4.1 18D61
        • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729     •
          ios            • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
        • macOS (desktop)            • macos                                    •
          darwin-x64     • Mac OS X 10.15.4 19E2269 darwin-x64
        • Chrome (web)               • chrome                                   •
          web-javascript • Google Chrome 98.0.4758.80
    
    [✓] HTTP Host Availability
        • All required HTTP hosts are available
    
    ! Doctor found issues in 1 category.
    
    
    
    

    Similar / related: #99302

  2. added
    a: tests"flutter test", flutter_test, or one of our tests
    frameworkflutter/packages/flutter repository. See also f: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Mar 25, 2022
  3. added
    P2Important issues not at the top of the work list
    on Mar 30, 2022
  4. bartekpacia commented on Oct 4, 2022

    @bartekpacia
    Member

    This issue also breaks Finder.hitTestable(). I modified @spkersten's example to demonstrate this:

    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.waitUntilVisible(find.byType(Button));
        await tester.tap(find.byType(Button));
      });
    }
    
    class Button extends StatelessWidget {
      const Button({super.key, required this.onTap});
    
      final VoidCallback onTap;
    
      @override
      Widget build(BuildContext context) {
        return Transform.scale(
          scale: 1.1,
          child: GestureDetector(
            onTap: onTap,
            child: Container(
              width: 40,
              height: 40,
              color: const Color(0xffff0000),
            ),
          ),
        );
      }
    }
    
    extension WidgetTesterX on WidgetTester {
      Future<void> waitUntilVisible(Finder finder) async {
        const duration = Duration(seconds: 10);
        final end = binding.clock.now().add(duration);
    
        while (finder.hitTestable().evaluate().isEmpty) {
          final now = binding.clock.now();
          if (now.isAfter(end)) {
            throw Exception('waitUntilVisible() timed out');
          }
    
          await pump(const Duration(milliseconds: 100));
        }
      }
    }

    And here's the output:

    $ flutter test test/flutter_test_2.dart
    00:01 +0: with Transform
    ══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
    The following _Exception was thrown running a test:
    Exception: waitUntilVisible() timed out
    
    When the exception was thrown, this was the stack:
    #0      WidgetTesterX.waitUntilVisible (file:///Users/bartek/dev/random/patrol_example/test/flutter_test_2.dart:46:9)
    <asynchronous suspension>
    <asynchronous suspension>
    (elided one frame from package:stack_trace)
    
    The test description was:
      with Transform
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    00:01 +0 -1: with Transform [E]
      Test failed. See exception logs above.
      The test description was: with Transform
    
    
    To run this test again: /Users/bartek/fvm/versions/stable/bin/cache/dart-sdk/bin/dart test /Users/bartek/dev/random/patrol_example/test/flutter_test_2.dart -p vm --plain-name 'with Transform'
    00:01 +0 -1: Some tests failed.
    

    This is really annoying, I hope this issue gets more attention.

  5. dmrickey commented on Apr 27, 2023

    @dmrickey

    Wow this is annoying

  6. desmond206x commented on Jul 18, 2024

    @desmond206x

    I invested so much time into this today, but can't create a small example code to post here.
    I think we have a problem where the Widget is not hitTestable after a headline Text widget wraps to the second line. If we set the maxLines property of Text to 1 it works. I don't know if somebody can create a small example of this..

    But after hours of testing I have another question:

    Can somebody please explain me why this example works:

    import 'package:flutter/material.dart';
    import 'package:flutter_test/flutter_test.dart';
    
    void main() {
      testWidgets('with text wrap', (tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Material(
              child: ButtonWithHeadline(
                onTap: () => print("tap 1"),
              ),
            ),
          ),
        );
    
        await tester.waitUntilVisible(find.byType(ButtonWithHeadline));
        await tester.tap(find.byType(ButtonWithHeadline));
      });
    }
    
    class ButtonWithHeadline extends StatelessWidget {
      const ButtonWithHeadline({super.key, required this.onTap});
    
      final VoidCallback onTap;
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: onTap,
          child: Container(
            width: 40,
            height: 40,
            color: const Color(0xffff0000),
          ),
        );
      }
    }
    
    extension WidgetTesterX on WidgetTester {
      Future<void> waitUntilVisible(Finder finder) async {
        const duration = Duration(seconds: 10);
        final end = binding.clock.now().add(duration);
    
        while (finder.hitTestable().evaluate().isEmpty) {
          final now = binding.clock.now();
          if (now.isAfter(end)) {
            throw Exception('waitUntilVisible() timed out');
          }
    
          await pump(const Duration(milliseconds: 100));
        }
      }
    }

    But not after I wrap the container inside the GestureDetector with a Column or Row?:

    @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: onTap,
          child: Column(
            children: [
              Container(
                width: 40,
                height: 40,
                color: const Color(0xffff0000),
              ),
            ],
          ),
        );
      }
    @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: onTap,
          child: Row(
            children: [
              Container(
                width: 40,
                height: 40,
                color: const Color(0xffff0000),
              ),
            ],
          ),
        );
      }
  7. added a commit that references this issue on Feb 26, 2026
    a056c27
  8. added a commit that references this issue on Feb 27, 2026
    35b1b63
  9. added a commit that references this issue on Mar 10, 2026
    9cdf796
  10. github-actions commented on Mar 12, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  11. locked as resolved and limited conversation to collaborators on Mar 12, 2026
  12. added a commit that references this issue on Mar 26, 2026
    83bf0dd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: tests"flutter test", flutter_test, or one of our testsfound in release: 2.10Found to occur in 2.10found in release: 2.13Found to occur in 2.13frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions