@@ -88,7 +88,7 @@ Future<Image> paintGoldenMismatchImages(GoldenMismatch mismatch) async {
88
88
}
89
89
90
90
/// Given a [report] , generates that shows all the mismatches found in the report.
91
- Future <Image > paintFailureScene (WidgetTester tester, GoldenSceneReport report) async {
91
+ Future <( Image , FailureSceneMetadata ) > paintFailureScene (WidgetTester tester, GoldenSceneReport report) async {
92
92
final photos = < GoldenFailurePhoto > [];
93
93
94
94
for (final item in report.items) {
@@ -143,11 +143,12 @@ Future<Image> paintFailureScene(WidgetTester tester, GoldenSceneReport report) a
143
143
);
144
144
}
145
145
146
- return _layoutFailureScene (tester, photos);
146
+ return _layoutFailureScene (tester, report, photos);
147
147
}
148
148
149
149
/// Generates a single image that shows all the golden failures.
150
- Future <Image > _layoutFailureScene (WidgetTester tester, List <GoldenFailurePhoto > images) async {
150
+ Future <(Image , FailureSceneMetadata )> _layoutFailureScene (
151
+ WidgetTester tester, GoldenSceneReport report, List <GoldenFailurePhoto > images) async {
151
152
final renderablePhotos = < GoldenFailurePhoto , (Uint8List , GlobalKey )> {};
152
153
for (final photo in images) {
153
154
final image = await _convertImagePackageToUiImage (photo.pixels);
@@ -161,7 +162,7 @@ Future<Image> _layoutFailureScene(WidgetTester tester, List<GoldenFailurePhoto>
161
162
child: IntrinsicHeight (
162
163
child: GoldenFailureScene (
163
164
key: sceneKey,
164
- direction: Axis .horizontal ,
165
+ direction: Axis .vertical ,
165
166
renderablePhotos: renderablePhotos,
166
167
background: null ,
167
168
),
@@ -180,13 +181,29 @@ Future<Image> _layoutFailureScene(WidgetTester tester, List<GoldenFailurePhoto>
180
181
181
182
final uiImage = await captureImage (find.byKey (sceneKey).evaluate ().single);
182
183
final bytes = await uiImage.toByteData (format: ui.ImageByteFormat .rawRgba);
183
- final result = Image .fromBytes (
184
+ final failureImage = Image .fromBytes (
184
185
width: uiImage.width,
185
186
height: uiImage.height,
186
187
bytes: bytes! .buffer,
187
188
order: ChannelOrder .rgba,
188
189
);
189
- return result;
190
+
191
+ // Lookup and return metadata for the position and size of each failure image
192
+ // within the scene.
193
+ final metadata = FailureSceneMetadata (
194
+ description: report.metadata.description,
195
+ images: [
196
+ for (final golden in renderablePhotos.keys)
197
+ FailureImageMetadata (
198
+ id: golden.description,
199
+ topLeft:
200
+ (renderablePhotos[golden]! .$2.currentContext! .findRenderObject () as RenderBox ).localToGlobal (Offset .zero),
201
+ size: renderablePhotos[golden]! .$2.currentContext! .size! ,
202
+ ),
203
+ ],
204
+ );
205
+
206
+ return (failureImage, metadata);
190
207
}
191
208
192
209
/// Generates a single image that shows the golden, the candidate, and the
@@ -456,11 +473,15 @@ class GoldenFailureScene extends StatelessWidget {
456
473
Container (
457
474
color: material.Colors .white,
458
475
padding: const EdgeInsets .all (16 ),
459
- child: Text (
460
- entry.key.description,
461
- style: TextStyle (
462
- color: material.Colors .black,
463
- fontFamily: "packages/flutter_test_goldens/OpenSans" ,
476
+ child: FittedBox (
477
+ fit: BoxFit .scaleDown,
478
+ child: Text (
479
+ entry.key.description,
480
+ softWrap: false ,
481
+ style: TextStyle (
482
+ color: material.Colors .black,
483
+ fontFamily: "packages/flutter_test_goldens/OpenSans" ,
484
+ ),
464
485
),
465
486
),
466
487
),
@@ -485,3 +506,70 @@ class GoldenFailurePhoto {
485
506
final String description;
486
507
final Image pixels;
487
508
}
509
+
510
+ class FailureSceneMetadata {
511
+ static FailureSceneMetadata fromJson (Map <String , dynamic > json) {
512
+ return FailureSceneMetadata (
513
+ description: json["description" ] ?? "" ,
514
+ images: [
515
+ for (final photoJson in (json["images" ] as List <dynamic >)) //
516
+ FailureImageMetadata .fromJson (photoJson),
517
+ ],
518
+ );
519
+ }
520
+
521
+ const FailureSceneMetadata ({
522
+ required this .description,
523
+ required this .images,
524
+ });
525
+
526
+ final String description;
527
+ final List <FailureImageMetadata > images;
528
+
529
+ Map <String , dynamic > toJson () {
530
+ return {
531
+ "description" : description,
532
+ "images" : images.map ((photo) => photo.toJson ()).toList (),
533
+ };
534
+ }
535
+ }
536
+
537
+ class FailureImageMetadata {
538
+ static FailureImageMetadata fromJson (Map <String , dynamic > json) {
539
+ return FailureImageMetadata (
540
+ id: json["id" ],
541
+ topLeft: ui.Offset (
542
+ (json["topLeft" ]["x" ] as num ).toDouble (),
543
+ (json["topLeft" ]["y" ] as num ).toDouble (),
544
+ ),
545
+ size: ui.Size (
546
+ (json["size" ]["width" ] as num ).toDouble (),
547
+ (json["size" ]["height" ] as num ).toDouble (),
548
+ ),
549
+ );
550
+ }
551
+
552
+ FailureImageMetadata ({
553
+ required this .id,
554
+ required this .topLeft,
555
+ required this .size,
556
+ });
557
+
558
+ final String id;
559
+ final ui.Offset topLeft;
560
+ final ui.Size size;
561
+
562
+ Map <String , dynamic > toJson () {
563
+ return {
564
+ "id" : id,
565
+ "topLeft" : {
566
+ "x" : topLeft.dx,
567
+ "y" : topLeft.dy,
568
+ },
569
+ "size" : {
570
+ "width" : size.width,
571
+ "height" : size.height,
572
+ },
573
+ };
574
+ }
575
+ }
0 commit comments