diff --git a/lib/src/spot/snapshot.dart b/lib/src/spot/snapshot.dart index a413ea2d..e747f049 100644 --- a/lib/src/spot/snapshot.dart +++ b/lib/src/spot/snapshot.dart @@ -267,7 +267,8 @@ extension ValidateQuantity on WidgetSnapshot { throw QuantityTestFailure( message: 'Could not find ${unconstrainedSelector.toStringBreadcrumb()} in widget tree, ' - 'expected at least $minimumConstraint', + 'expected at least $minimumConstraint.\n' + 'Check the timeline at the very bottom for more information.', significantWidgetTree: significantWidgetTree(), snapshot: this, ); @@ -278,7 +279,8 @@ extension ValidateQuantity on WidgetSnapshot { throw QuantityTestFailure( message: 'Found $count elements matching ${unconstrainedSelector.toStringBreadcrumb()} in widget tree, ' - 'expected at least $minimumConstraint', + 'expected at least $minimumConstraint.\n' + 'Check the timeline at the very bottom for more information.', significantWidgetTree: significantWidgetTree(), snapshot: this, ); @@ -290,7 +292,8 @@ extension ValidateQuantity on WidgetSnapshot { throw QuantityTestFailure( message: 'Found $count elements matching ${unconstrainedSelector.toStringBreadcrumb()} in widget tree, ' - 'expected at most $maximumConstraint', + 'expected at most $maximumConstraint.\n' + 'Check the timeline at the very bottom for more information.', significantWidgetTree: significantWidgetTree(), snapshot: this, ); @@ -309,7 +312,8 @@ extension ValidateQuantity on WidgetSnapshot { throw QuantityTestFailure( message: 'Could not find ${unconstrainedSelector.toStringBreadcrumb()} in widget tree, ' - 'expected exactly $exactCount', + 'expected exactly $exactCount.\n' + 'Check the timeline at the very bottom for more information.', significantWidgetTree: significantWidgetTree(), snapshot: this, ); @@ -318,7 +322,8 @@ extension ValidateQuantity on WidgetSnapshot { throw QuantityTestFailure( message: 'Found $count elements matching ${unconstrainedSelector.toStringBreadcrumb()} in widget tree, ' - 'expected exactly $exactCount', + 'expected exactly $exactCount.\n' + 'Check the timeline at the very bottom for more information.', significantWidgetTree: significantWidgetTree(), snapshot: this, ); @@ -329,7 +334,8 @@ extension ValidateQuantity on WidgetSnapshot { throw QuantityTestFailure( message: 'Found $count elements matching ${unconstrainedSelector.toStringBreadcrumb()} in widget tree, ' - 'expected between $minimumConstraint and $maximumConstraint', + 'expected between $minimumConstraint and $maximumConstraint.\n' + 'Check the timeline at the very bottom for more information.', significantWidgetTree: significantWidgetTree(), snapshot: this, ); @@ -377,9 +383,7 @@ class QuantityTestFailure implements TestFailure { @override String toString() { - return '$message\n' - '$significantWidgetTree\n' - '$message'; + return message; } } @@ -438,7 +442,6 @@ extension MultiWidgetSelectorMatcher on WidgetSnapshot { final errorBuilder = StringBuffer(); errorBuilder.writeln('Could not find $selector in widget tree'); _dumpWidgetTree(errorBuilder); - errorBuilder.writeln('Could not find $selector in widget tree'); timeline.addEvent( eventType: 'Assertion Failed', details: errorBuilder.toString(), @@ -449,7 +452,7 @@ extension MultiWidgetSelectorMatcher on WidgetSnapshot { ], ), ); - fail(errorBuilder.toString()); + fail('Could not find $selector in widget tree'); } } @@ -602,7 +605,6 @@ void _tryMatchingLessSpecificCriteria(WidgetSnapshot snapshot) { details: '$errorBuilder\nFound in widget Tree:\n$significantTree', ); } - errorBuilder.writeln('\nFound in widget Tree:\n$significantTree'); fail(errorBuilder.toString()); } } diff --git a/lib/src/timeline/print_console.dart b/lib/src/timeline/print_console.dart index eefbaa0f..386c49bb 100644 --- a/lib/src/timeline/print_console.dart +++ b/lib/src/timeline/print_console.dart @@ -1,3 +1,4 @@ +import 'package:ci/ci.dart'; import 'package:spot/src/timeline/timeline.dart'; /// Extension that adds a method to print the timeline to the console. @@ -23,10 +24,16 @@ extension ConsoleTimelinePrinter on Timeline { final caller = frame != null ? 'at ${frame.member} ${frame.uri}:${frame.line}:${frame.column}' : 'N/A'; - final details = event.details.split('\n').first; + final details = + isCI ? event.details : event.details.split('\n').firstOrNull; buffer.writeln('==================== Timeline Event ===================='); buffer.writeln('Event Type: ${event.eventType}'); - buffer.writeln('Details: $details'); + if (details != null) { + buffer.writeln('Details: $details'); + } + if (event.description != null) { + buffer.writeln('Description: ${event.description}'); + } buffer.writeln('Caller: $caller'); if (event.screenshot != null) { buffer.writeln('Screenshot: file://${event.screenshot!.file.path}'); diff --git a/test/spot/existence_comparison_test.dart b/test/spot/existence_comparison_test.dart index 6e2e4600..77f3f53a 100644 --- a/test/spot/existence_comparison_test.dart +++ b/test/spot/existence_comparison_test.dart @@ -292,7 +292,13 @@ void main() { .whereText((text) => text.startsWith('a')) .existsExactlyNTimes(3), throwsSpotErrorContaining([ - 'Found 4 elements matching Text with prop "data" starts with \'a\' in widget tree, expected exactly 3', + 'Found 4 elements matching Text with prop "data" starts with \'a\' in widget tree, expected exactly 3.', + 'Check the timeline at the very bottom for more information.', + ]), + ); + expect( + timeline.events.last.details, + stringContainsInOrder([ 'Text("aa"', 'Text("ab"', 'Text("ac"', diff --git a/test/spot/exists_once_test.dart b/test/spot/exists_once_test.dart index e24b1108..b5eaddec 100644 --- a/test/spot/exists_once_test.dart +++ b/test/spot/exists_once_test.dart @@ -79,44 +79,58 @@ void main() { ); expect( () => spot().existsOnce(), - throwsSpotErrorContaining( - [ - 'Found 2 elements', - 'expected exactly 1', - '\nWrap(', // at the beginning of the line, common ancestor - 'Text("World"', - 'Text("Hello"', - ], - not: ['root'], - ), + throwsSpotErrorContaining([ + 'Found 2 elements', + 'expected exactly 1', + ]), ); + expect( + timeline.events.last.details, + stringContainsInOrder([ + 'Found 2 elements', + 'expected exactly 1', + '\nWrap(', // at the beginning of the line, common ancestor + 'Text("Hello"', + 'Text("World"', + ]), + ); + expect(timeline.events.last.details, isNot(contains('root'))); expect( () => spot().amount(1).existsOnce(), - throwsSpotErrorContaining( - [ - 'Found 2 elements', - 'expected exactly 1', - '\nWrap(', // at the beginning of the line, common ancestor - 'Text("World"', - 'Text("Hello"', - ], - not: ['root'], - ), + throwsSpotErrorContaining([ + 'Found 2 elements', + 'expected exactly 1', + ]), + ); + expect( + timeline.events.last.details, + stringContainsInOrder([ + 'Found 2 elements', + 'expected exactly 1', + '\nWrap(', // at the beginning of the line, common ancestor + 'Text("Hello"', + 'Text("World"', + ]), ); + expect(timeline.events.last.details, isNot(contains('root'))); expect( () => spot(parents: [spot()]).amount(1).existsOnce(), throwsSpotErrorContaining( - [ - 'Found 2 elements', - "Wrap ᗕ Text", - 'expected exactly 1', - '\nWrap(', // at the beginning of the line, common ancestor - 'Text("World"', - 'Text("Hello"', - ], - not: ['root'], + ['Found 2 elements', "Wrap ᗕ Text", 'expected exactly 1'], ), ); + expect( + timeline.events.last.details, + stringContainsInOrder([ + 'Found 2 elements', + "Wrap ᗕ Text", + 'expected exactly 1', + '\nWrap(', // at the beginning of the line, common ancestor + 'Text("Hello"', + 'Text("World"', + ]), + ); + expect(timeline.events.last.details, isNot(contains('root'))); }); testWidgets('existsOnce() finds the correct widget differentiating by props', (tester) async {