Skip to content

Commit 7b902fd

Browse files
Merge pull request #21 from bancolombia/feature/animations
Add animations support
2 parents 5fd2b63 + db1b926 commit 7b902fd

26 files changed

+1792
-495
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: Install dependencies
2020
run: flutter pub get
2121
- name: Run tests
22-
run: flutter test
22+
run: flutter test --coverage
2323
- name: Upload golden failures
2424
if: always()
2525
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ migrate_working_dir/
3535
/pubspec.lock
3636
/coverage
3737
/.vscode/
38+
**/coverage/
3839

3940
# Web related
4041
lib/generated_plugin_registrant.dart

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,48 @@ The `GoldenCaptureConfig` class allows you to customize how multiple screenshots
177177
- `maxScreensPerRow`: Maximum screenshots per row (for grid layout)
178178
- `device`: Optional device configuration
179179

180+
### Animation Testing 🎬
181+
182+
For testing animations at specific timestamps, use `BcGoldenCapture.animation`:
183+
184+
```dart
185+
BcGoldenCapture.animation(
186+
'Button scale animation',
187+
AnimatedButton(),
188+
[
189+
GoldenAnimationStep(
190+
timestamp: Duration.zero,
191+
frameName: 'start',
192+
),
193+
GoldenAnimationStep(
194+
timestamp: Duration(milliseconds: 150),
195+
frameName: 'scaled',
196+
),
197+
GoldenAnimationStep(
198+
timestamp: Duration(milliseconds: 300),
199+
frameName: 'end',
200+
),
201+
],
202+
GoldenAnimationConfig(
203+
testName: 'button_animation',
204+
totalDuration: Duration(milliseconds: 300),
205+
animationSteps: [...], // Same steps as above
206+
layoutType: CaptureLayoutType.horizontal,
207+
showTimelineLabels: true,
208+
),
209+
animationSetup: (tester) async {
210+
// Trigger the animation
211+
await tester.tap(find.byType(AnimatedButton));
212+
await tester.pump();
213+
},
214+
);
215+
```
216+
217+
The animation testing feature captures frames at specific moments in your animation timeline, creating a comprehensive visual test that shows the animation's progression. This is particularly useful for:
218+
219+
- **UI Transitions**: Validating smooth transitions between states
220+
- **Loading Animations**: Ensuring consistent spinner or progress animations
221+
180222
## bcGoldenTest (Legacy) 🏗
181223
The is a legacy function that is still supported but deprecated. For new tests, please use `BcGoldenCapture.single` instead. This function is default tagged with "golden" and also has additional features for the tests, see the code below:
182224

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import 'package:bc_golden_plugin/bc_golden_plugin.dart';
2+
import 'package:flutter/material.dart';
3+
4+
void main() {
5+
// Test de ejemplo simple para demostrar la funcionalidad
6+
BcGoldenCapture.animation(
7+
'Simple fade animation test',
8+
const SimpleFadeAnimation(),
9+
GoldenAnimationConfig(
10+
testName: 'simple_fade',
11+
totalDuration: const Duration(milliseconds: 500),
12+
animationSteps: const [
13+
GoldenAnimationStep(
14+
timestamp: Duration.zero,
15+
frameName: 'start_invisible',
16+
),
17+
GoldenAnimationStep(
18+
timestamp: Duration(milliseconds: 290),
19+
frameName: 'half_visible',
20+
),
21+
GoldenAnimationStep(
22+
timestamp: Duration(milliseconds: 320),
23+
frameName: 'fully_visible',
24+
),
25+
GoldenAnimationStep(
26+
timestamp: Duration(milliseconds: 340),
27+
frameName: 'fully_visible',
28+
),
29+
GoldenAnimationStep(
30+
timestamp: Duration(milliseconds: 360),
31+
frameName: 'fully_visible',
32+
),
33+
GoldenAnimationStep(
34+
timestamp: Duration(milliseconds: 380),
35+
frameName: 'fully_visible',
36+
),
37+
GoldenAnimationStep(
38+
timestamp: Duration(milliseconds: 400),
39+
frameName: 'fully_visible',
40+
),
41+
GoldenAnimationStep(
42+
timestamp: Duration(milliseconds: 420),
43+
frameName: 'fully_visible',
44+
),
45+
GoldenAnimationStep(
46+
timestamp: Duration(milliseconds: 440),
47+
frameName: 'fully_visible',
48+
),
49+
GoldenAnimationStep(
50+
timestamp: Duration(milliseconds: 460),
51+
frameName: 'fully_visible',
52+
),
53+
GoldenAnimationStep(
54+
timestamp: Duration(milliseconds: 480),
55+
frameName: 'fully_visible',
56+
),
57+
GoldenAnimationStep(
58+
timestamp: Duration(milliseconds: 500),
59+
frameName: 'fully_visible',
60+
),
61+
],
62+
layoutType: CaptureLayoutType.horizontal,
63+
spacing: 20.0,
64+
showTimelineLabels: true,
65+
device: GoldenDeviceData.iPhone13,
66+
),
67+
);
68+
69+
BcGoldenCapture.animation(
70+
'Loading spinner rotation',
71+
const CircularProgressIndicator(),
72+
const GoldenAnimationConfig(
73+
testName: 'spinner_rotation',
74+
totalDuration: Duration(milliseconds: 1000),
75+
showTimelineLabels: true,
76+
animationSteps: [
77+
GoldenAnimationStep(
78+
timestamp: Duration.zero,
79+
frameName: '0_degrees',
80+
),
81+
GoldenAnimationStep(
82+
timestamp: Duration(milliseconds: 250),
83+
frameName: '90_degrees',
84+
),
85+
GoldenAnimationStep(
86+
timestamp: Duration(milliseconds: 500),
87+
frameName: '180_degrees',
88+
),
89+
GoldenAnimationStep(
90+
timestamp: Duration(milliseconds: 750),
91+
frameName: '270_degrees',
92+
),
93+
], // Mismos pasos
94+
layoutType: CaptureLayoutType.grid,
95+
maxScreensPerRow: 2,
96+
),
97+
);
98+
}
99+
100+
/// Widget de ejemplo simple con animación de fade
101+
class SimpleFadeAnimation extends StatefulWidget {
102+
const SimpleFadeAnimation({super.key});
103+
104+
@override
105+
State<SimpleFadeAnimation> createState() => _SimpleFadeAnimationState();
106+
}
107+
108+
class _SimpleFadeAnimationState extends State<SimpleFadeAnimation>
109+
with SingleTickerProviderStateMixin {
110+
late AnimationController _controller;
111+
late Animation<double> _fadeAnimation;
112+
113+
@override
114+
void initState() {
115+
super.initState();
116+
_controller = AnimationController(
117+
duration: const Duration(milliseconds: 500),
118+
vsync: this,
119+
);
120+
121+
_fadeAnimation = Tween<double>(
122+
begin: 0.0,
123+
end: 1.0,
124+
).animate(_controller);
125+
126+
// Iniciar la animación automáticamente
127+
WidgetsBinding.instance.addPostFrameCallback((_) {
128+
_controller.forward();
129+
});
130+
}
131+
132+
@override
133+
void dispose() {
134+
_controller.dispose();
135+
super.dispose();
136+
}
137+
138+
@override
139+
Widget build(BuildContext context) {
140+
return MaterialApp(
141+
home: Scaffold(
142+
backgroundColor: Colors.white,
143+
body: Center(
144+
child: AnimatedBuilder(
145+
animation: _fadeAnimation,
146+
builder: (context, child) {
147+
return Opacity(
148+
opacity: _fadeAnimation.value,
149+
child: Container(
150+
width: 200,
151+
height: 100,
152+
decoration: BoxDecoration(
153+
color: Colors.blue,
154+
borderRadius: BorderRadius.circular(12),
155+
boxShadow: [
156+
BoxShadow(
157+
color: Colors.grey.withValues(alpha: 0.3),
158+
spreadRadius: 2,
159+
blurRadius: 8,
160+
offset: const Offset(0, 4),
161+
),
162+
],
163+
),
164+
child: const Center(
165+
child: Text(
166+
'Fade Animation',
167+
style: TextStyle(
168+
color: Colors.white,
169+
fontSize: 18,
170+
fontWeight: FontWeight.bold,
171+
),
172+
),
173+
),
174+
),
175+
);
176+
},
177+
),
178+
),
179+
),
180+
);
181+
}
182+
}
87 KB
Loading
20.5 KB
Loading
5.83 KB
Loading
45.4 KB
Loading
44.5 KB
Loading
44.8 KB
Loading

0 commit comments

Comments
 (0)