Skip to content

[flutter_test]scrollUntilVisible has different results if ListTile's onTap is null or not #143921

@megur0

Description

@megur0

Steps to reproduce

  1. Paste sample code to tests/xxx_test.dart in Flutter project
  2. Execute test by flutter test --plain-name 'scrollUntilVisible'

Expected results

The test passes, whether or not the ListTile's onTap attribute is null.

Actual results

The test will fail if ListTile's onTap attribute is not null.

Code sample

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

// flutter test --plain-name 'scrollUntilVisible'
void main() {
  group("scrollUntilVisible", () {
    Future<void> pumpListViewAndScrollToEndContent(
        WidgetTester tester, bool hasOnTap) async {
      int itemCount = 30;
      final controller = ScrollController();
      await tester.pumpWidget(MaterialApp(
          home: Scaffold(
        body: ListView.builder(
          controller: controller,
          itemBuilder: (context, index) {
            if (index <= itemCount) {
              return ListTile(
                onTap: hasOnTap
                    ? () {
                        //debugPrint("tapped");
                      }
                    : null,
                title: Text("$index"),
              );
            }
            return null;
          },
        ),
      )));

      // controller.addListener(() {
      //   debugPrint(
      //       "${controller.position.pixels}, ${controller.position.maxScrollExtent}");
      // });

      await tester.scrollUntilVisible(
        find.text("${itemCount - 1}"),
        20,
        maxScrolls: 2000,
        duration: const Duration(milliseconds: 50),
        scrollable: find.byType(Scrollable),
      );
    }

    testWidgets("This results success", (tester) async {
      // ListTile has "onTap" as null
      await pumpListViewAndScrollToEndContent(tester, false);
    });

    testWidgets("This results failed", (tester) async {
      // ListTile has "onTap" as not null
      await pumpListViewAndScrollToEndContent(tester, true);
    });
  });
}

Screenshots or Video

No response

Logs

Logs
% flutter test --plain-name 'scrollUntilVisible'
00:06 +1: /xxx/xxx.dart: scrollUntilVisible This results failed                                                      
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No element

When the exception was thrown, this was the stack:
#0      Iterable.single (dart:core/iterable.dart:674:25)
#1      WidgetController.element (package:flutter_test/src/controller.dart:448:30)
#2      WidgetController.dragUntilVisible.<anonymous closure> (package:flutter_test/src/controller.dart:1709:38)
<asynchronous suspension>
#3      TestAsyncUtils.guard.<anonymous closure> (package:flutter_test/src/test_async_utils.dart:117:7)
<asynchronous suspension>
#4      WidgetController.scrollUntilVisible.<anonymous closure> (package:flutter_test/src/controller.dart:1675:7)
<asynchronous suspension>
#5      TestAsyncUtils.guard.<anonymous closure> (package:flutter_test/src/test_async_utils.dart:117:7)
<asynchronous suspension>
#6      main.<anonymous closure>.pumpListViewAndScrollToEndContent (/xxx/xxx_test.dart:36:7)
<asynchronous suspension>
#7      main.<anonymous closure>.<anonymous closure> (/xxx/xxx_test.dart:52:7)
<asynchronous suspension>
#8      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:168:15)
<asynchronous suspension>
#9      TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1013:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

Flutter Doctor output

I have not installed the Android environment, but it is not related to the test.
% flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.9, on macOS 14.1.1 23B81 darwin-arm64, locale ja-JP)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] VS Code (version 1.86.0)
[✓] Connected device (4 available)
[✓] Network resources

! Doctor found issues in 2 categories.

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: material designflutter/packages/flutter/material repository.found in release: 3.19Found to occur in 3.19found in release: 3.20Found to occur in 3.20has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions