flutterdarthoverflutter-testwidget-test-flutter

Simulate hover in flutter test


I am working on a flutter web project and I have a widget I would like to write tests about. This widget is using a MouseRegion which does some actions when it is hovered or not by the user.

As an example:


class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  bool isHovered = false;
  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onExit: (_) {
        setState(() {
          isHovered = false;
        });
      },
      onEnter: (_) {
        setState(() {
          isHovered = true;
        });
      },
      child: Container(
        color: isHovered ? Colors.blue : Colors.red,
        height: 50,
        width: 50,
      )
    );
  }
}

I can write a widget test to test my container is red:

testWidgets('MyWidget should be red by default', (WidgetTester tester) async {
  await tester.pumpWidget(
    MyWidget(),
  );
  expect(find.byWidgetPredicate((Widget widget) => widget is Container && widget.color == Colors.red), findsOneWidget);
  expect(find.byWidgetPredicate((Widget widget) => widget is Container && widget.color == Colors.blue), findsNothing);
});

But how can I simulate the hovering in a test widget (to check that the container is blue)?


Solution

  • Here is how I managed to do it

    testWidgets('MyWidget should be red by default', (WidgetTester tester) async {
      await tester.pumpWidget(
        MyWidget(),
      );
      expect(find.byWidgetPredicate((Widget widget) => widget is Container && widget.color == Colors.red), findsOneWidget);
      expect(find.byWidgetPredicate((Widget widget) => widget is Container && widget.color == Colors.blue), findsNothing);
    
      final gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer(location: Offset.zero);
      addTearDown(gesture.removePointer);
      await tester.pump();
      await gesture.moveTo(tester.getCenter(find.byType(MyWidget)));
      await tester.pumpAndSettle();
    
      expect(find.byWidgetPredicate((Widget widget) => widget is Container && widget.color == Colors.red), findsNothing);
      expect(find.byWidgetPredicate((Widget widget) => widget is Container && widget.color == Colors.blue), findsOneWidget);
    });