1

I want to do a test that allows me to verify if my widget is showing the AnimatedIcon that I provide, as well as to know if the animation is working (changing the icon in an animated way), the problem is that I can't find the way to do it.

  1. Is there a method similar to finder.byIcon(), but that accepts AnimatedIconData instead of IconData?
  2. How to verify that the animation is happening?
its-me-mahmud
  • 690
  • 1
  • 7
  • 14
devblock
  • 113
  • 7

1 Answers1

2

1. Finder for AnimatedIconData

To get a finder for AnimatedIconData, use the find.byWidgetPredicate method like below (assuming the AnimatedIconData being searched for is AnimatedIcons.menu_arrow):

final animatedIconFinder = find.byWidgetPredicate((widget) =>
        widget is AnimatedIcon && widget.icon == AnimatedIcons.menu_arrow); 

2. Verification that the animation is happening

To verify that the animation is happening, check the value of the AnimatedIcon widget's progress property.

Assuming the animation happens after a floating action button on the screen is tapped, the code sample below shows how to verify that the AnimatedIcon animates after the button is tapped.

// Gets the [AnimatedIcon] widget
final animatedIconWidget = tester.widget(animatedIconFinder) as AnimatedIcon;

final animatedIconProgress = animatedIconWidget.progress.value;

// Verifies that [AnimatedIcon] is not animating
expect(animatedIconProgress, 0);

// Finds [FloatingActionButton]
final floatingActionButtonFinder = 
    find.widgetWithIcon(FloatingActionButton, Icons.change_circle);

// Taps [FloatingActionButton]
await tester.tap(floatingActionButtonFinder);

await tester.pumpAndSettle();

final updatedAnimatedIconProgress = animatedIconWidget.progress.value;

// Verifies that the [AnimatedIcon] has completed its animation
expect(updatedAnimatedIconProgress, 1);

Using a Custom Finder

To make your finder more concise and similar to find.byIcon, do the following:

  1. Create a custom Finder by extending MatchFinder and add the matching logic in the matches method (This is a modification of the find.byIcon implementation).

    class _WidgetAnimatedIconFinder extends MatchFinder {
      _WidgetAnimatedIconFinder(this.icon, {super.skipOffstage});
    
      final AnimatedIconData icon;
    
      @override
      String get description => 'icon "$icon"';
    
      @override
      bool matches(Element candidate) {
        final Widget widget = candidate.widget;
        return widget is AnimatedIcon && widget.icon == icon;
      }
    }
    
  2. Create an extension on the CommonFinders class and add a byAnimatedIcon method that uses the custom Finder created in step 1. The CommonFinders class is provided by the flutter_test package and the find constant (as in find.byIcon) is an instance of CommonFinders.

    extension CustomFindersExtension on CommonFinders {
      Finder byAnimatedIcon(AnimatedIconData icon) =>
        _WidgetAnimatedIconFinder(icon);
    }
    
  3. Use find.byAnimatedIcon to find the AnimatedIcon by supplying the AnimatedIconData being searched for.

    Replace the Finder using find.byWidgetPredicate with this below:

    final animatedIconFinder = find.byAnimatedIcon(AnimatedIcons.menu_arrow);
    
Victor Eronmosele
  • 7,040
  • 2
  • 10
  • 33