While I am working on hero animation in flutter, I want to write a test for it which tests that when we tap on an image in a message list page the navigation takes place to lightbox page and the image animates smoothly. I am finding a difficulty in tracking the image during the hero animation. Below is the code for the same that I have implemented:
Setup code:
late PerAccountStore store;
late FakeApiConnection connection;
final channel = eg.stream();
final message = eg.streamMessage(stream: channel,
contentMarkdown: ContentExample.imageSingle.html, topic: 'test topic');
Future<void> setupMessageListPage(WidgetTester tester) async {
addTearDown(testBinding.reset);
final subscription = eg.subscription(channel);
await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot(
streams: [channel], subscriptions: [subscription]));
store = await testBinding.globalStore.perAccount(eg.selfAccount.id);
connection = store.connection as FakeApiConnection;
await store.addUser(eg.selfUser);
connection.prepare(json:
eg.newestGetMessagesResult(foundOldest: true, messages: [message]).toJson());
await tester.pumpWidget(TestZulipApp(accountId: eg.selfAccount.id,
child: MessageListPage(initNarrow: const CombinedFeedNarrow())));
await tester.pumpAndSettle();
}
Test code:
testWidgets('hero animation occurs when opening lightbox from message list', (tester) async {
prepareBoringImageHttpClient();
await setupMessageListPage(tester);
// Find the initial message image
final messageContentFinder = find.byWidgetPredicate((widget) =>
widget is MessageContent && widget.message.id == message.id
);
expect(messageContentFinder, findsOneWidget);
final imageFinder = find.descendant(
of: messageContentFinder,
matching: find.byType(RealmContentNetworkImage)
);
expect(imageFinder, findsOneWidget);
// Find the Hero and get its initial position via RenderObject
final heroFinder = find.ancestor(
of: imageFinder,
matching: find.byType(Hero)
);
expect(heroFinder, findsOneWidget);
final initialElement = tester.element(heroFinder);
final initialRenderBox = initialElement.renderObject as RenderBox;
final initialPosition = initialRenderBox.localToGlobal(Offset.zero);
// Get the Hero's tag - this will be consistent throughout the animation
final heroTag = tester.widget<Hero>(heroFinder).tag;
// Start the animation
await tester.tap(imageFinder);
await tester.pump(); // Build the new page
// Wait a bit to let the animation start
await tester.pump(const Duration(milliseconds: 50));
// Find the destination Hero Element by looking in the lightbox route
final heroElement = tester.elementList(find.byType(Hero))
.where((element) => (element.widget as Hero).tag == heroTag)
.where((element) =>
element.findAncestorWidgetOfExactType<InteractiveViewer>() != null)
.single;
final heroRenderBox = heroElement.renderObject as RenderBox;
// Pump incremental frames during the 300ms animation
final animationDuration = const Duration(milliseconds: 250); // Remaining time
final steps = 5; // Check 5 points during animation
for (int i = 1; i <= steps; i++) {
await tester.pump(animationDuration ~/ steps);
// Look up the hero by its element identity
final currentElement = tester.element(
find.byElementPredicate((element) => element == heroElement));
expect(currentElement, same(heroElement)); // Element should stay the same
// Get current position via RenderObject
final currentPosition = heroRenderBox.localToGlobal(Offset.zero);
print('Step $i position: $currentPosition (initial: $initialPosition)');
// By this point in the animation, the position should definitely be changing
check(currentPosition).anyOf([
(it) => it.dy.not((it) => it.equals(initialPosition.dy)),
(it) => it.dx.not((it) => it.equals(initialPosition.dx))
]);
}
await tester.pumpAndSettle();
debugNetworkImageHttpClientProvider = null;
});
I am getting the logs as:
LightboxHero hero animation occurs when opening lightbox from message list
Step 1 position: Offset(0.0, 0.0) (initial: Offset(37.0, 385.0))
Step 2 position: Offset(0.0, 0.0) (initial: Offset(37.0, 385.0))
Step 3 position: Offset(0.0, 0.0) (initial: Offset(37.0, 385.0))
Step 4 position: Offset(0.0, 0.0) (initial: Offset(37.0, 385.0))
Step 5 position: Offset(0.0, 0.0) (initial: Offset(37.0, 385.0))
Why at each time frame I am getting same current position and I think it is the final position after the hero animation is completed. But I want to track the image during the hero animation. How can I do the same?
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744402127a4572442.html
评论列表(0条)