Reputation: 2549
I'm trying to do a widget test in flutter to one widget which uses WidgetsBinding.instance.addPostFrameCallback() to show a dialog at the very beggining of the widget lifecycle.
The widget works fine, but I cannot figure out how to do a widget test, because the very first expect() of the test is executed before this post frame is triggered.
Anyway to "tell" the test to wait until all the post frames are dispatched?
PD: tester.pump(), tester.pumpAndSettle(), etc. are not working.
Upvotes: 12
Views: 5055
Reputation: 1088
To schedule a frame (and force postFrameCallback
to be called) in flutter test environment you need to call tester.binding.scheduleFrame()
before tester.pump()
.
Alternatively, if you don't care about the whole widget tree being rebuilt, you could call tester.pumpWidget(widget)
instead of tester.pump()
Example test:
testWidgets('testing frames', (tester) async {
final w = Container();
int framesCount = 0;
tester.binding.addPersistentFrameCallback((timeStamp) {
framesCount++;
});
await tester.pumpWidget(w);
expect(framesCount, equals(1));
// pumpWidget calls [scheduleFrame]
await tester.pumpWidget(w);
expect(framesCount, equals(2));
await tester.pump();
// no frame was scheduled, so framesCount is still 2
expect(framesCount, equals(2));
tester.binding.scheduleFrame(); // --
await tester.pump(); // |
expect(framesCount, equals(3)); // <-
// pumpWidget calls [scheduleFrame]
await tester.pumpWidget(w);
expect(framesCount, equals(4));
});
Upvotes: 6
Reputation: 21
This worked for me:
// press button
await tester.tap(find.text("Save"));
// await the flushbar or snackbar to appear
await tester.pumpAndSettle(const Duration(seconds: 1));
// find by text or key
expect(find.text("Error saving note"), findsOneWidget);
// this prevents this error:
// A Timer is still pending even after the widget tree was disposed.
// the flushbar in my code is displayed for 5 seconds. So we wait for it to
// go away.
await tester.pumpAndSettle(const Duration(seconds: 5));
I dont know if this is the proper way to do. But it works. Good luck!
Upvotes: 2
Reputation: 1034
But what do you know... suddenly it popped up:
tester.binding.scheduleWarmUpFrame();
Run that :-)
Taken from here: https://chromium.googlesource.com/external/github.com/flutter/flutter/+/v0.9.2/packages/flutter/test/widgets/binding_test.dart
Upvotes: 10