Skip to content

[Tests] ListWheelScrollView tester.getCenter returns incorrect children coordinates #121343

@nt4f04uNd

Description

@nt4f04uNd

Steps to Reproduce

Noticed this while I was writing a test to #38803 in my PR #121342

  1. Execute flutter test on the code sample

Expected results: Test passes

Actual results: Test fails

Error output

Warning: A call to tap() with finder "exactly one widget with text "0" (ignoring offstage widgets): Text("0", dependencies: [MediaQuery])" derived an Offset (Offset(7.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: RenderParagraph#955f5 relayoutBoundary=up4
The hit test result at that offset is: HitTestResult(RenderPointerListener#b4b34@Offset(7.0, 300.0), RenderSemanticsGestureHandler#dbbd4@Offset(7.0, 300.0), RenderPointerListener#de626@Offset(7.0, 300.0), _RenderScrollSemantics#00b39@Offset(7.0, 300.0), RenderRepaintBoundary#83856@Offset(7.0, 300.0), RenderCustomPaint#e79c5@Offset(7.0, 300.0), RenderRepaintBoundary#0fa46@Offset(7.0, 300.0), HitTestEntry<HitTestTarget>#6e126(RenderView#00100), HitTestEntry<HitTestTarget>#09be3(<AutomatedTestWidgetsFlutterBinding>))
#0      WidgetController._getElementPoint (package:flutter_test/src/controller.dart:1290:25)
#1      WidgetController.getCenter (package:flutter_test/src/controller.dart:1175:12)
#2      WidgetController.tap (package:flutter_test/src/controller.dart:504:18)
#3      main.<anonymous closure> (file:///Users/nt4f04und/dev/prj/app/test/widget_test.dart:27:12)
<asynchronous suspension>
#4      StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:124:15)
<asynchronous suspension>
To silence this warning, pass "warnIfMissed: false" to "tap()".
To make this warning fatal, set WidgetController.hitTestWarningShouldBeFatal to true.
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
Guarded function conflict.
You must use "await" with all Future-returning test APIs.
The guarded method "tapAt" from class WidgetController was called from
file:///Users/nt4f04und/dev/prj/app/test/widget_test.dart on line 27.
Then, the "expect" function was called from
file:///Users/nt4f04und/dev/prj/app/test/widget_test.dart on line 28.
The first method (WidgetController.tapAt) had not yet finished executing at the time that the second
function (expect) was called. Since both are guarded, and the second was not a nested call inside
the first, the first must complete its execution before the second can be called. Typically, this is
achieved by putting an "await" statement in front of the call to the first.
If you are confident that all test APIs are being called using "await", and this expect() call is
not being called at the top level but is itself being called from some sort of callback registered
before the tapAt method was called, then consider using expectSync() instead.

When the first method (WidgetController.tapAt) was called, this was the stack:
#0      TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:69:54)
#1      WidgetController.tapAt (package:flutter_test/src/controller.dart:509:27)
#2      WidgetController.tap (package:flutter_test/src/controller.dart:504:12)
#3      main.<anonymous closure> (file:///Users/nt4f04und/dev/prj/app/test/widget_test.dart:27:12)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

When the exception was thrown, this was the stack:
#0      TestAsyncUtils.guardSync (package:flutter_test/src/test_async_utils.dart:273:5)
#1      expect (package:flutter_test/src/widget_tester.dart:458:18)
#2      main.<anonymous closure> (file:///Users/nt4f04und/dev/prj/app/test/widget_test.dart:28:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

The test description was:
  ListWheelScrollView allows taps for on its children
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: ListWheelScrollView allows taps for on its children

✖ ListWheelScrollView allows taps for on its children
Exited (1)

Code sample
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('ListWheelScrollView allows taps for on its children', (WidgetTester tester) async {
    final List<int> children = List<int>.generate(100, (int index) => index);
    final List<int> tappedChildren = <int>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListWheelScrollView(
          itemExtent: 100,
          children: children
              .map((int index) => GestureDetector(
                    key: ValueKey<int>(index),
                    onTap: () {
                      tappedChildren.add(index);
                    },
                    child: Text(index.toString()),
                  ))
              .toList(),
        ),
      ),
    );

    tester.tap(find.text(children.first.toString()));
    expect(tappedChildren, [children.first]);
  });
}

As we can see from the error, it finds the widget, but apparently the tester.getCenter function, which is used inside thetester.tap returns incorrect location of the widget, seemengly without accounting for the transform applied by the scroll view.

It doesn't prevent from hit testing, taps and other gestures to be working correctly both in tests and in real enviroment (when user performs them), but it makes it difficult to write consitent tests for gestures on children of ListWheelScrollView.

Logs
[!] Flutter (Channel unknown, 3.8.0-15.0.pre.26, on macOS 12.0.1 21A559 darwin-x64, locale ru-RU)
    ! Flutter version 3.8.0-15.0.pre.26 on channel unknown at /Users/nt4f04und/development/flutter
      Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
      If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
    ! Unknown upstream repository.
      Reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
    • Framework revision 19b2aa14c0 (3 hours ago), 2023-02-23 09:03:39 -0500
    • Engine revision c87028288a
    • Dart version 3.0.0 (build 3.0.0-266.0.dev)
    • DevTools version 2.22.1
    • Pub download mirror https://pub.dartlang.org
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and
      upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc1)
    • Android SDK at /Users/nt4f04und/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0-rc1
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 13F100
    • CocoaPods version 1.11.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1)
    • 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 11.0.11+0-b60-7590822)

[✓] VS Code (version 1.75.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.58.0

[✓] Connected device (4 available)
    • sdk gphone x86 (mobile)             • emulator-5554                        • android-x86    • Android 11 (API 30) (emulator)
    • iPhone SE (3rd generation) (mobile) • D4DF8A02-4DAA-40CF-9774-AF505CB3520B • ios            • com.apple.CoreSimulator.SimRuntime.iOS-15-5
      (simulator)
    • macOS (desktop)                     • macos                                • darwin-x64     • macOS 12.0.1 21A559 darwin-x64
    • Chrome (web)                        • chrome                               • web-javascript • Google Chrome 110.0.5481.100

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

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 testsf: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.r: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions