diff --git a/packages/patrol_finders/CHANGELOG.md b/packages/patrol_finders/CHANGELOG.md index 5dc092790..fa9d6a9b3 100644 --- a/packages/patrol_finders/CHANGELOG.md +++ b/packages/patrol_finders/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.4.0 + +- Wrap actions on finders with patrol logs. + ## 2.3.0 - Add option to disable printing patrol logs. Default value is disabled. diff --git a/packages/patrol_finders/lib/src/custom_finders/patrol_finder.dart b/packages/patrol_finders/lib/src/custom_finders/patrol_finder.dart index 495210290..e335df835 100644 --- a/packages/patrol_finders/lib/src/custom_finders/patrol_finder.dart +++ b/packages/patrol_finders/lib/src/custom_finders/patrol_finder.dart @@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:meta/meta.dart'; import 'package:patrol_finders/patrol_finders.dart'; import 'package:patrol_finders/src/custom_finders/utils.dart'; +import 'package:patrol_log/patrol_log.dart'; /// Thrown when some [PatrolFinder]'s method fails. class PatrolFinderException implements Exception { @@ -174,6 +175,45 @@ class PatrolFinder implements MatchFinder { /// [PatrolTester] that this [PatrolFinder] wraps. final PatrolTester tester; + /// Wraps a function with a log entry for the start and end of the function. + Future wrapWithPatrolLog({ + required String action, + String? value, + required String color, + required Future Function() function, + bool enablePatrolLog = true, + }) async { + if (!(tester.config.printLogs && enablePatrolLog)) { + return function(); + } + + final finderText = finder + .toString(describeSelf: true) + .replaceAll('A finder that searches for', '') + .replaceAll(' (considering only hit-testable ones)', '') + .replaceAll(' (ignoring all but first)', ''); + + final valueText = value != null ? ' "$value"' : ''; + final text = '$color$action${AnsiCodes.reset}$valueText$finderText'; + tester.patrolLog + .log(StepEntry(action: text, status: StepEntryStatus.start)); + try { + final result = await function(); + tester.patrolLog + .log(StepEntry(action: text, status: StepEntryStatus.success)); + return result; + } catch (err) { + tester.patrolLog.log( + StepEntry( + action: text, + status: StepEntryStatus.failure, + exception: err.toString(), + ), + ); + rethrow; + } + } + /// Waits until this finder finds at least 1 visible widget and then taps on /// it. /// @@ -203,14 +243,18 @@ class PatrolFinder implements MatchFinder { SettlePolicy? settlePolicy, Duration? visibleTimeout, Duration? settleTimeout, - }) async { - await tester.tap( - this, - settlePolicy: settlePolicy, - visibleTimeout: visibleTimeout, - settleTimeout: settleTimeout, - ); - } + }) async => + wrapWithPatrolLog( + action: 'tap', + color: AnsiCodes.yellow, + function: () => tester.tap( + this, + settlePolicy: settlePolicy, + visibleTimeout: visibleTimeout, + settleTimeout: settleTimeout, + enablePatrolLog: false, + ), + ); /// Waits until this finder finds at least 1 visible widget and then makes /// long press gesture on it. @@ -241,14 +285,18 @@ class PatrolFinder implements MatchFinder { SettlePolicy? settlePolicy, Duration? visibleTimeout, Duration? settleTimeout, - }) async { - await tester.longPress( - this, - settlePolicy: settlePolicy, - visibleTimeout: visibleTimeout, - settleTimeout: settleTimeout, - ); - } + }) async => + wrapWithPatrolLog( + action: 'longPress', + color: AnsiCodes.yellow, + function: () => tester.longPress( + this, + settlePolicy: settlePolicy, + visibleTimeout: visibleTimeout, + settleTimeout: settleTimeout, + enablePatrolLog: false, + ), + ); /// Waits until this finder finds at least 1 visible widget and then enters /// text into it. @@ -280,15 +328,19 @@ class PatrolFinder implements MatchFinder { SettlePolicy? settlePolicy, Duration? visibleTimeout, Duration? settleTimeout, - }) async { - await tester.enterText( - this, - text, - settlePolicy: settlePolicy, - visibleTimeout: visibleTimeout, - settleTimeout: settleTimeout, - ); - } + }) async => + wrapWithPatrolLog( + action: 'enterText', + color: AnsiCodes.magenta, + function: () => tester.enterText( + this, + text, + settlePolicy: settlePolicy, + visibleTimeout: visibleTimeout, + settleTimeout: settleTimeout, + enablePatrolLog: false, + ), + ); /// Shorthand for [PatrolTester.scrollUntilVisible]. /// @@ -309,15 +361,22 @@ class PatrolFinder implements MatchFinder { Duration? dragDuration, SettlePolicy? settlePolicy, }) { - return tester.scrollUntilVisible( - finder: finder, - view: view, - delta: step, - scrollDirection: scrollDirection, - maxScrolls: maxScrolls, - settleBetweenScrollsTimeout: settleBetweenScrollsTimeout, - settlePolicy: settlePolicy, - dragDuration: dragDuration, + return wrapWithPatrolLog( + action: 'scrollTo', + color: AnsiCodes.green, + function: () { + return tester.scrollUntilVisible( + finder: this, + view: view, + delta: step, + scrollDirection: scrollDirection, + maxScrolls: maxScrolls, + settleBetweenScrollsTimeout: settleBetweenScrollsTimeout, + settlePolicy: settlePolicy, + dragDuration: dragDuration, + enablePatrolLog: false, + ); + }, ); } @@ -327,9 +386,12 @@ class PatrolFinder implements MatchFinder { /// /// Timeout is globally set by [PatrolTester.config.visibleTimeout]. If you /// want to override this global setting, set [timeout]. - Future waitUntilExists({Duration? timeout}) { - return tester.waitUntilExists(this, timeout: timeout); - } + Future waitUntilExists({Duration? timeout}) => + wrapWithPatrolLog( + action: 'waitUntilExists', + color: AnsiCodes.cyan, + function: () => tester.waitUntilExists(this, timeout: timeout), + ); /// Waits until this finder finds at least one visible widget. /// @@ -338,9 +400,12 @@ class PatrolFinder implements MatchFinder { /// /// Timeout is globally set by [PatrolTester.config.visibleTimeout]. If you /// want to override this global setting, set [timeout]. - Future waitUntilVisible({Duration? timeout}) { - return tester.waitUntilVisible(this, timeout: timeout); - } + Future waitUntilVisible({Duration? timeout}) => + wrapWithPatrolLog( + action: 'waitUntilVisible', + color: AnsiCodes.cyan, + function: () => tester.waitUntilVisible(this, timeout: timeout), + ); /// Returns a finder matching widget of type [T] which also fulfills /// [predicate]. diff --git a/packages/patrol_finders/lib/src/custom_finders/patrol_tester.dart b/packages/patrol_finders/lib/src/custom_finders/patrol_tester.dart index df4a77657..ddb8d56d4 100644 --- a/packages/patrol_finders/lib/src/custom_finders/patrol_tester.dart +++ b/packages/patrol_finders/lib/src/custom_finders/patrol_tester.dart @@ -129,13 +129,13 @@ class PatrolTester { PatrolTester({ required this.tester, required this.config, - }) : _patrolLog = PatrolLogWriter(); + }) : patrolLog = PatrolLogWriter(); /// Global configuration of this tester. final PatrolTesterConfig config; /// Logs a message to the patrol log. - final PatrolLogWriter _patrolLog; + final PatrolLogWriter patrolLog; /// Flutter's widget tester that this [PatrolTester] wraps. final WidgetTester tester; @@ -161,13 +161,13 @@ class PatrolTester { ''; final valueText = value != null ? ' "$value"' : ''; final text = '$color$action${AnsiCodes.reset}$valueText$finderText'; - _patrolLog.log(StepEntry(action: text, status: StepEntryStatus.start)); + patrolLog.log(StepEntry(action: text, status: StepEntryStatus.start)); try { final result = await function(); - _patrolLog.log(StepEntry(action: text, status: StepEntryStatus.success)); + patrolLog.log(StepEntry(action: text, status: StepEntryStatus.success)); return result; } catch (err) { - _patrolLog.log( + patrolLog.log( StepEntry( action: text, status: StepEntryStatus.failure, diff --git a/packages/patrol_finders/pubspec.yaml b/packages/patrol_finders/pubspec.yaml index 211a582b1..efb362425 100644 --- a/packages/patrol_finders/pubspec.yaml +++ b/packages/patrol_finders/pubspec.yaml @@ -1,6 +1,6 @@ name: patrol_finders description: Streamlined, high-level API on top of flutter_test. -version: 2.3.0 +version: 2.4.0 homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol/tree/master/packages/patrol_finders issue_tracker: https://github.com/leancodepl/patrol/issues?q=is%3Aopen+is%3Aissue+label%3Apackage%3Apatrol_finders @@ -20,7 +20,7 @@ dependencies: flutter_test: sdk: flutter meta: ^1.10.0 - patrol_log: ^0.0.1+2 + patrol_log: ^0.1.0 dev_dependencies: leancode_lint: ^14.2.0