@@ -6,7 +6,6 @@ import 'dart:ui' as ui;
6
6
7
7
import 'package:flutter/material.dart' hide Image;
8
8
import 'package:flutter_test/flutter_test.dart' ;
9
- import 'package:flutter_test_goldens/golden_bricks.dart' ;
10
9
import 'package:flutter_test_goldens/src/flutter/flutter_test_extensions.dart' ;
11
10
import 'package:flutter_test_goldens/src/goldens/golden_camera.dart' ;
12
11
import 'package:flutter_test_goldens/src/goldens/golden_collections.dart' ;
@@ -16,7 +15,6 @@ import 'package:flutter_test_goldens/src/goldens/golden_scenes.dart';
16
15
import 'package:flutter_test_goldens/src/goldens/pixel_comparisons.dart' ;
17
16
import 'package:flutter_test_goldens/src/logging.dart' ;
18
17
import 'package:flutter_test_goldens/src/png/png_metadata.dart' ;
19
- import 'package:flutter_test_goldens/src/scenes/golden_files.dart' ;
20
18
import 'package:flutter_test_goldens/src/scenes/golden_scene.dart' ;
21
19
import 'package:flutter_test_goldens/src/scenes/scene_layout.dart' ;
22
20
import 'package:image/image.dart' ;
@@ -26,33 +24,30 @@ import 'package:path/path.dart';
26
24
/// renders those into a single scene file, or compares them against an existing
27
25
/// scene file.
28
26
class Gallery {
29
- Gallery (
30
- this ._tester, {
27
+ Gallery ({
31
28
Directory ? directory,
32
29
required String fileName,
33
30
required String sceneDescription,
34
31
required SceneLayout layout,
35
- GalleryItemScaffold itemScaffold = defaultGalleryItemScaffold ,
36
- GalleryItemDecorator ? itemDecorator = defaultGalleryItemDecorator ,
37
- Widget ? goldenBackground,
32
+ GoldenSceneItemScaffold ? itemScaffold,
33
+ GoldenSceneItemDecorator ? itemDecorator,
34
+ GoldenSceneBackground ? goldenBackground,
38
35
}) : _fileName = fileName,
39
36
_sceneDescription = sceneDescription,
40
37
_layout = layout,
41
38
_itemScaffold = itemScaffold,
42
39
_itemDecorator = itemDecorator,
43
40
_goldenBackground = goldenBackground {
44
- _directory = directory ?? defaultGoldenDirectory ;
41
+ _directory = directory ?? GoldenSceneTheme .current.directory ;
45
42
}
46
43
47
- final WidgetTester _tester;
48
-
49
44
/// A scaffold built around each item in this scene.
50
45
///
51
- /// Defaults to [defaultGalleryItemScaffold ] .
52
- final GalleryItemScaffold _itemScaffold;
46
+ /// Defaults to [defaultGoldenSceneItemScaffold ] .
47
+ final GoldenSceneItemScaffold ? _itemScaffold;
53
48
54
49
/// A decoration applied to each item in this scene.
55
- final GalleryItemDecorator ? _itemDecorator;
50
+ final GoldenSceneItemDecorator ? _itemDecorator;
56
51
57
52
/// All screenshots within this scene.
58
53
final _items = < GalleryItem > [];
@@ -70,7 +65,7 @@ class Gallery {
70
65
final SceneLayout _layout;
71
66
72
67
/// The background behind the items in this scene.
73
- final Widget ? _goldenBackground;
68
+ final GoldenSceneBackground ? _goldenBackground;
74
69
75
70
/// Adds a screenshot item to the scene, based on a given [widget] .
76
71
Gallery itemFromWidget ({
@@ -147,41 +142,43 @@ class Gallery {
147
142
148
143
/// Either renders a new golden to a scene file, or compares new screenshots against an existing
149
144
/// golden scene file.
150
- Future <void > renderOrCompareGolden () async {
145
+ Future <void > renderOrCompareGolden (WidgetTester tester ) async {
151
146
FtgLog .pipeline.info ("Rendering or comparing golden - $_sceneDescription " );
152
147
153
148
// Build each gallery item and screenshot it.
149
+ final itemScaffold = _itemScaffold ?? GoldenSceneTheme .current.itemScaffold;
150
+ print ("Rendering gallery: Given scaffold: $_itemScaffold , chosen scaffold: $itemScaffold " );
151
+ final itemDecorator = _itemDecorator ?? GoldenSceneTheme .current.itemDecorator;
154
152
final camera = GoldenCamera ();
153
+
155
154
for (final item in _items) {
156
155
FtgLog .pipeline.info ("Building gallery item: ${item .description }, item decorated: $_itemDecorator " );
157
156
158
157
if (item.pumper != null ) {
159
158
// Defer to the `pumper` to pump the entire widget tree for this gallery item.
160
- await item.pumper! .call (_tester, _itemScaffold, _itemDecorator );
159
+ await item.pumper! .call (tester, itemScaffold, item.description, itemDecorator );
161
160
} else if (item.builder != null ) {
162
161
// Pump this gallery item, deferring to a `WidgetBuilder` for the content.
163
- await _tester.pumpWidget (
164
- _itemScaffold (
165
- _tester,
166
- _itemDecorator != null
167
- ? _itemDecorator.call (
168
- _tester,
169
- Builder (builder: item.builder! ),
170
- )
171
- : Builder (builder: item.builder! ),
162
+ await tester.pumpWidget (
163
+ itemScaffold (
164
+ tester,
165
+ itemDecorator.call (
166
+ tester,
167
+ item.description,
168
+ Builder (builder: item.builder! ),
169
+ ),
172
170
),
173
171
);
174
172
} else {
175
173
// Pump this gallery item, deferring to a `Widget` for the content.
176
- await _tester.pumpWidget (
177
- _itemScaffold (
178
- _tester,
179
- _itemDecorator != null
180
- ? _itemDecorator.call (
181
- _tester,
182
- item.child! ,
183
- )
184
- : item.child! ,
174
+ await tester.pumpWidget (
175
+ itemScaffold (
176
+ tester,
177
+ itemDecorator.call (
178
+ tester,
179
+ item.description,
180
+ item.child! ,
181
+ ),
185
182
),
186
183
);
187
184
}
@@ -201,7 +198,7 @@ class Gallery {
201
198
final photos = camera.photos;
202
199
// TODO: cleanup the modeling of these photos vs renderable photos once things are working
203
200
final renderablePhotos = < GoldenPhoto , (Uint8List , GlobalKey )> {};
204
- await _tester .runAsync (() async {
201
+ await tester .runAsync (() async {
205
202
for (final photo in photos) {
206
203
final byteData = await photo.pixels.toByteData (format: ui.ImageByteFormat .png);
207
204
renderablePhotos[photo] = (byteData! .buffer.asUint8List (), GlobalKey ());
@@ -210,34 +207,35 @@ class Gallery {
210
207
211
208
// Layout photos in the gallery so we can lookup their final offsets and sizes.
212
209
var sceneMetadata = await _layoutPhotos (
210
+ tester,
213
211
photos,
214
212
renderablePhotos,
215
213
_layout,
216
214
goldenBackground: _goldenBackground,
217
215
);
218
216
219
217
FtgLog .pipeline.finer ("Running momentary delay for render flakiness" );
220
- await _tester .runAsync (() async {
218
+ await tester .runAsync (() async {
221
219
// Without this delay, the screenshot loading is spotty. However, with
222
220
// this delay, we seem to always get screenshots displayed in the widget tree.
223
221
// FIXME: Root cause this render flakiness and see if we can fix it.
224
222
await Future .delayed (const Duration (milliseconds: 1 ));
225
223
});
226
224
227
- await _tester .pumpAndSettle ();
225
+ await tester .pumpAndSettle ();
228
226
229
227
if (autoUpdateGoldenFiles) {
230
228
// Generate new goldens.
231
229
await _updateGoldenScene (
232
- _tester ,
230
+ tester ,
233
231
_fileName,
234
232
sceneMetadata,
235
233
);
236
234
} else {
237
235
// Compare to existing goldens.
238
236
FtgLog .pipeline.finer ("Comparing existing goldens..." );
239
237
await _compareGoldens (
240
- _tester ,
238
+ tester ,
241
239
sceneMetadata,
242
240
_fileName,
243
241
find.byType (GoldenSceneBounds ),
@@ -250,10 +248,11 @@ class Gallery {
250
248
251
249
// TODO: de-dup this with FilmStrip
252
250
Future <GoldenSceneMetadata > _layoutPhotos (
251
+ WidgetTester tester,
253
252
List <GoldenPhoto > photos,
254
253
Map <GoldenPhoto , (Uint8List , GlobalKey )> renderablePhotos,
255
254
SceneLayout layout, {
256
- Widget ? goldenBackground,
255
+ GoldenSceneBackground ? goldenBackground,
257
256
}) async {
258
257
// Layout the final strip within an OverflowBox to let it be whatever
259
258
// size it wants. Then check the content render object for final dimensions.
@@ -282,13 +281,13 @@ class Gallery {
282
281
goldenBackground: goldenBackground,
283
282
);
284
283
285
- await _tester .pumpWidgetAndAdjustWindow (gallery);
284
+ await tester .pumpWidgetAndAdjustWindow (gallery);
286
285
287
- await _tester .runAsync (() async {
286
+ await tester .runAsync (() async {
288
287
for (final entry in renderablePhotos.entries) {
289
288
await precacheImage (
290
289
MemoryImage (entry.value.$1),
291
- _tester .element (find.byKey (entry.value.$2)),
290
+ tester .element (find.byKey (entry.value.$2)),
292
291
);
293
292
}
294
293
});
@@ -313,7 +312,7 @@ class Gallery {
313
312
GlobalKey contentKey,
314
313
Map <GoldenPhoto , (Uint8List , GlobalKey )> renderablePhotos, {
315
314
Key ? galleryKey,
316
- Widget ? goldenBackground,
315
+ GoldenSceneBackground ? goldenBackground,
317
316
}) {
318
317
return GoldenSceneBounds (
319
318
child: IntrinsicWidth (
@@ -334,8 +333,8 @@ class Gallery {
334
333
String goldenFileName,
335
334
GoldenSceneMetadata sceneMetadata,
336
335
) async {
337
- FtgLog .pipeline.finer ("Doing golden generation - window height: ${_tester .view .physicalSize .height }" );
338
- await expectLater (find.byType (GoldenSceneBounds ), matchesGoldenFile ("$ goldenFileName .png" ));
336
+ FtgLog .pipeline.finer ("Doing golden generation - window height: ${tester .view .physicalSize .height }" );
337
+ await expectLater (find.byType (GoldenSceneBounds ), matchesGoldenFile (_goldenFilePath () ));
339
338
340
339
final goldenFile = File (_goldenFilePath ());
341
340
var pngData = goldenFile.readAsBytesSync ();
@@ -489,8 +488,9 @@ class Gallery {
489
488
/// {@macro gallery_item_pumper_requirements}
490
489
typedef GalleryItemPumper = Future <void > Function (
491
490
WidgetTester tester,
492
- GalleryItemScaffold scaffold,
493
- GalleryItemDecorator ? decorator,
491
+ GoldenSceneItemScaffold scaffold,
492
+ String description,
493
+ GoldenSceneItemDecorator ? decorator,
494
494
);
495
495
496
496
/// Scaffolds a gallery item, such as building a `MaterialApp` with a `Scaffold` .
@@ -503,12 +503,12 @@ typedef GalleryItemPumper = Future<void> Function(
503
503
/// Gallery item decorator
504
504
/// Gallery item (the content)
505
505
/// {@endtemplate}
506
- typedef GalleryItemScaffold = Widget Function (WidgetTester tester, Widget content);
506
+ typedef GoldenSceneItemScaffold = Widget Function (WidgetTester tester, Widget content);
507
507
508
508
/// Decorates a golden screenshot by wrapping the given [content] in a new widget tree.
509
509
///
510
510
/// {@macro gallery_item_structure}
511
- typedef GalleryItemDecorator = Widget Function (WidgetTester tester, Widget content);
511
+ typedef GoldenSceneItemDecorator = Widget Function (WidgetTester tester, String description , Widget content);
512
512
513
513
/// A single UI screenshot within a gallery of gallery items.
514
514
class GalleryItem {
@@ -564,30 +564,3 @@ class GalleryItem {
564
564
/// item is created with a [pumper] or a [builder] .
565
565
final Widget ? child;
566
566
}
567
-
568
- /// The ancestor widget tree for every item in a gallery, unless overridden by
569
- /// the gallery configuration.
570
- Widget defaultGalleryItemScaffold (WidgetTester tester, Widget content) {
571
- return MaterialApp (
572
- home: Scaffold (
573
- body: Builder (builder: (context) {
574
- return DefaultTextStyle (
575
- style: DefaultTextStyle .of (context).style.copyWith (
576
- fontFamily: goldenBricks,
577
- ),
578
- child: Center (
579
- child: GoldenImageBounds (child: content),
580
- ),
581
- );
582
- }),
583
- ),
584
- debugShowCheckedModeBanner: false ,
585
- );
586
- }
587
-
588
- Widget defaultGalleryItemDecorator (WidgetTester tester, Widget content) {
589
- return Padding (
590
- padding: const EdgeInsets .all (24 ),
591
- child: content,
592
- );
593
- }
0 commit comments