Skip to content

Commit

Permalink
Merge pull request #2420 from leancodepl/change-patrol-logs-in-finders
Browse files Browse the repository at this point in the history
Wrap actions on finders with patrol logs.
  • Loading branch information
pdenert authored Nov 20, 2024
2 parents bc76dda + 8813f55 commit e4dc3a4
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 47 deletions.
4 changes: 4 additions & 0 deletions packages/patrol_finders/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
145 changes: 105 additions & 40 deletions packages/patrol_finders/lib/src/custom_finders/patrol_finder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<T> wrapWithPatrolLog<T>({
required String action,
String? value,
required String color,
required Future<T> 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.
///
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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].
///
Expand All @@ -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,
);
},
);
}

Expand All @@ -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<PatrolFinder> waitUntilExists({Duration? timeout}) {
return tester.waitUntilExists(this, timeout: timeout);
}
Future<PatrolFinder> 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.
///
Expand All @@ -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<PatrolFinder> waitUntilVisible({Duration? timeout}) {
return tester.waitUntilVisible(this, timeout: timeout);
}
Future<PatrolFinder> 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].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions packages/patrol_finders/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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

0 comments on commit e4dc3a4

Please sign in to comment.