Repository: flutter
Issue: WidgetTester.takeException does not catch FlutterError when tap gesture fails
Labels: a: tests,framework,has reproducible steps,P3,team-framework,triaged-framework,found in release: 3.22,found in release: 3.24

### Steps to reproduce

Run the following test code:

<details open><summary>Code sample</summary>

```dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  WidgetController.hitTestWarningShouldBeFatal = true;

  testWidgets('Tapping button should fail', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: IgnorePointer(
          ignoring: true,
          child: Center(
            child: TextButton(
              onPressed: () {},
              child: const Text('button'),
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.byType(TextButton), warnIfMissed: true);
    expect(tester.takeException(), isA<FlutterError>());
  });
}
```

</details>

### Expected results

The test passes.

### Actual results

The test fails with the following error message that the button tap failed.

<details open><summary>Logs</summary>

```console
$ flutter test

00:01 +0: Tapping button should fail
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
Finder specifies a widget that would not receive pointer events.
A call to tap() with finder "Found 1 widget with type "TextButton": [
  TextButton(dependencies: [MediaQuery, _InheritedTheme, _LocalizationsScope-[GlobalKey#59ce0]],
state: _ButtonStyleState#8a191),
]" 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: RenderSemanticsAnnotations#75a2d relayoutBoundary=up1(creator: Semantics ← TextButton ← Center ← IgnorePointer ← Semantics ← Builder ← RepaintBoundary-[GlobalKey#a0269] ← IgnorePointer ← ListenableBuilder ← SnapshotWidget ← _ZoomExitTransition ← SnapshotWidget ← ⋯, parentData: offset=Offset(345.7, 276.0) (can use size), constraints: BoxConstraints(0.0<=w<=800.0, 0.0<=h<=600.0), semantics node: SemanticsNode#4, semantic boundary, size: Size(108.6, 48.0))
The hit test result at that offset is: HitTestResult(RenderMouseRegion#d70d5@Offset(400.0, 300.0),
RenderSemanticsAnnotations#0baf0@Offset(400.0, 300.0), RenderPointerListener#48980@Offset(400.0,
300.0), RenderSemanticsGestureHandler#fca6b@Offset(400.0, 300.0),
RenderExcludeSemantics#44ca8@Offset(400.0, 300.0), RenderBlockSemantics#fcaa8@Offset(400.0, 300.0),
RenderIgnorePointer#b0bef@Offset(400.0, 300.0), _RenderTheater#9d20e@Offset(400.0, 300.0),
RenderAbsorbPointer#5793e@Offset(400.0, 300.0), RenderPointerListener#d7e55@Offset(400.0, 300.0),
RenderSemanticsAnnotations#1b705@Offset(400.0, 300.0), RenderCustomPaint#4f01f@Offset(400.0, 300.0),
RenderSemanticsAnnotations#8f82c@Offset(400.0, 300.0),
RenderSemanticsAnnotations#13642@Offset(400.0, 300.0), RenderTapRegionSurface#09c4b@Offset(400.0,
300.0), RenderSemanticsAnnotations#93692@Offset(400.0, 300.0),
RenderSemanticsAnnotations#49ce1@Offset(400.0, 300.0),
RenderSemanticsAnnotations#f330f@Offset(400.0, 300.0),
HitTestEntry<HitTestTarget>#2b7ea(_ReusableRenderView#ec4b4),
HitTestEntry<HitTestTarget>#a1da6(<AutomatedTestWidgetsFlutterBinding>))
If you expected this target not to be able to receive pointer events, pass "warnIfMissed: false" to
"tap()".
To make this error into a non-fatal warning, set WidgetController.hitTestWarningShouldBeFatal to
false.

When the exception was thrown, this was the stack:
#0      WidgetController._getElementPoint (package:flutter_test/src/controller.dart:1914:11)
#1      WidgetController.getCenter (package:flutter_test/src/controller.dart:1784:12)
#2      WidgetController.tap (package:flutter_test/src/controller.dart:1032:18)
#3      main.<anonymous closure> (file:///Users/fujidaiti/Dev/issue103/test/widget_test.dart:22:18)
<asynchronous suspension>
#4      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:183:15)
<asynchronous suspension>
#5      TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1017:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

The test description was:
  Tapping button should fail
════════════════════════════════════════════════════════════════════════════════════════════════════
00:01 +0 -1: Tapping button should fail [E]
  Test failed. See exception logs above.
  The test description was: Tapping button should fail


To run this test again: /Users/fujidaiti/.fvm/versions/stable/bin/cache/dart-sdk/bin/dart test /Users/fujidaiti/Dev/issue103/test/widget_test.dart -p vm --plain-name 'Tapping button should fail'
00:01 +0 -1: Some tests failed.
```

</details>

### Workaround

We can work around this issue by defining a flag (e.g. `var didTapButton = false;`) that is set to`true` in `onTap` callback of the button, and then validate it using `expect` function:

```dart
expect(didTapButton, isFalse);
```

However, there are still situations where it is difficult to specify a custom gesture handler for the target widget due to various reasons (e.g., the public API doesn't expose a slot for such a callback). The same is true for other gesture simulation APIs such as `drag` and `press`.

### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
$ flutter doctor -v

[✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-arm64, locale ja-JP)
    • Flutter version 3.22.2 on channel stable at /Users/fujidaiti/.fvm/versions/stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 761747bfc5 (6 weeks ago), 2024-06-05 22:15:13 +0200
    • Engine revision edd8546116
    • Dart version 3.4.3
    • DevTools version 2.34.3

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/fujidaiti/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)

[✓] VS Code (version 1.90.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.74.0

[✓] Connected device (4 available)
    • iPhone 13 (iOS 17.5) (mobile)   • 9F89D57D-2C9E-434E-B414-FD65A9182262 • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-17-5 (simulator)
    • macOS (desktop)                 • macos                                • darwin-arm64   •
      macOS 14.5 23F79 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad                • darwin         •
      macOS 14.5 23F79 darwin-arm64
    • Chrome (web)                    • chrome                               • web-javascript •
      Google Chrome 126.0.6478.182
    ! Error: Browsing on the local area network for iPhone. Ensure the device is unlocked and
      attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
    ! Error: Browsing on the local area network for 藤田大地のiPhone. Ensure the device is unlocked and
      attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)

[✓] Network resources
    • All expected network resources are available.

• No issues found!
```

</details>