diff --git a/lib/src/scenes/golden_scene_report_printer.dart b/lib/src/scenes/golden_scene_report_printer.dart index 92af41a..8f4dd06 100644 --- a/lib/src/scenes/golden_scene_report_printer.dart +++ b/lib/src/scenes/golden_scene_report_printer.dart @@ -12,7 +12,7 @@ class GoldenSceneReportPrinter { final buffer = StringBuffer(); // Report the summary of passed/failed tests and missing/extra candidates. - buffer.write("Golden scene has failures: ${report.metadata.description} ("); + buffer.write("Golden scene failed ("); buffer.write("✅ ${report.totalPassed}/${report.items.length}, "); buffer.write("❌ ${report.totalFailed}/${report.items.length}"); if (report.missingCandidates.isNotEmpty || report.extraCandidates.isNotEmpty) { @@ -29,10 +29,9 @@ class GoldenSceneReportPrinter { buffer.write(" +${report.extraCandidates.length}"); } } - buffer.writeln(")"); + buffer.writeln("):"); if (report.totalFailed > 0) { - buffer.writeln(""); for (final item in report.items) { if (item.status == GoldenTestStatus.success) { buffer.writeln("✅ ${item.metadata.id}"); @@ -43,12 +42,37 @@ class GoldenSceneReportPrinter { final mismatch = item.mismatch; switch (mismatch) { case WrongSizeGoldenMismatch(): + buffer.writeln('❌ ${item.metadata.id} (wrong size)'); + buffer.writeln( + ' - Golden size: (${mismatch.golden.size.width.toInt()}, ${mismatch.golden.size.height.toInt()})'); buffer.writeln( - '"❌ ${item.metadata.id}" has an unexpected size (expected: ${mismatch.golden.size}, actual: ${mismatch.screenshot.size})'); + ' - Candidate size: (${mismatch.screenshot.size.width.toInt()}, ${mismatch.screenshot.size.height.toInt()})'); + buffer.write(' - '); + // Print the width comparison. + if (mismatch.golden.size.width > mismatch.screenshot.size.width) { + buffer.write( + "Candidate is ${(mismatch.golden.size.width - mismatch.screenshot.size.width).toInt()}px too narrow."); + } else if (mismatch.golden.size.width < mismatch.screenshot.size.width) { + buffer.write( + "Candidate is ${(mismatch.screenshot.size.width - mismatch.golden.size.width).toInt()}px too wide."); + } else { + buffer.write("Candidate has correct width."); + } + // Print the height comparison. + if (mismatch.golden.size.height > mismatch.screenshot.size.height) { + buffer.write( + " Candidate is ${(mismatch.golden.size.height - mismatch.screenshot.size.height).toInt()}px too short."); + } else if (mismatch.golden.size.height < mismatch.screenshot.size.height) { + buffer.write( + " Candidate is ${(mismatch.screenshot.size.height - mismatch.golden.size.height.toInt())}px too tall."); + } else { + buffer.write(" Candidate has correct height."); + } + buffer.writeln(""); break; case PixelGoldenMismatch(): buffer.writeln( - '"❌ ${item.metadata.id}" has a ${(mismatch.percent * 100).toStringAsFixed(2)}% (${mismatch.mismatchPixelCount}px) mismatch'); + '❌ ${item.metadata.id} (${mismatch.mismatchPixelCount}px, ${(mismatch.percent * 100).toStringAsFixed(2)}%)'); break; case MissingGoldenMismatch(): case MissingCandidateMismatch(): diff --git a/test_goldens/failure_reporting/failure_reporting_test.dart b/test_goldens/failure_reporting/failure_reporting_test.dart new file mode 100644 index 0000000..7d2aa24 --- /dev/null +++ b/test_goldens/failure_reporting/failure_reporting_test.dart @@ -0,0 +1,94 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test_goldens/flutter_test_goldens.dart'; +import 'package:flutter_test_goldens/golden_bricks.dart'; + +void main() { + testGoldenScene('reports multiple failures', (tester) async { + await Gallery( + tester, + directory: Directory("./goldens"), + fileName: "multiple_failures", + sceneDescription: "Example with multiple failures", + layout: SceneLayout.column, + ) + .itemFromWidget( + id: '1', + description: 'Android caret', + // Use _buildGoldenRectangle to build the original golden rectangle. + widget: _buildMismatchRectangle(), + ) + .itemFromWidget( + id: '2', + description: 'Android drag handles', + widget: Container( + width: 150, + height: 100, + color: Colors.green, + ), + ) + .itemFromWidget( + id: '3', + description: 'Hint text', + // Use _buildGoldenText to build the original golden text. + widget: _buildMismatchText(), + ) + // The following item is present in the golden file. + // .itemFromWidget( + // id: '4', + // description: 'iOS caret', + // widget: _buildGoldenRectangle(), + // ) + // The following item is not present in the golden file. + .itemFromWidget( + id: '5', + description: 'iOS drag handles', + widget: _buildGoldenRectangle(), + ) + .renderOrCompareGolden(); + }); +} + +/// The widget used to build the original golden rectangle. +Widget _buildGoldenRectangle() { + return Container( + width: 150, + height: 100, + color: Colors.red, + ); +} + +/// The widget used to build the mismatch rectangle. +/// +/// It has the same same size as the golden rectangle but a different color. +Widget _buildMismatchRectangle() { + return Container( + width: 150, + height: 100, + color: Colors.green, + ); +} + +/// The widget used to build the original golden text. +// ignore: unused_element +Widget _buildGoldenText() { + return Text( + 'A text widget', + style: TextStyle( + fontFamily: goldenBricks, + ), + ); +} + +/// The widget used to build the mismatch golden text. +/// +/// It has the same text but all uppercase. +Widget _buildMismatchText() { + return Text( + 'A TEXT WIDGET', + style: TextStyle( + fontFamily: goldenBricks, + ), + ); +} diff --git a/test_goldens/failure_reporting/goldens/multiple_failures.png b/test_goldens/failure_reporting/goldens/multiple_failures.png new file mode 100644 index 0000000..ab707ee Binary files /dev/null and b/test_goldens/failure_reporting/goldens/multiple_failures.png differ