From 627035b387f2ae03c7d25936ff2b2039801f8094 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 11:10:35 +0100 Subject: [PATCH 1/9] Reorganize ansi_codes --- packages/patrol_log/lib/src/ansi_codes.dart | 22 ++++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/patrol_log/lib/src/ansi_codes.dart b/packages/patrol_log/lib/src/ansi_codes.dart index 3ade90df6..8c4eec9ae 100644 --- a/packages/patrol_log/lib/src/ansi_codes.dart +++ b/packages/patrol_log/lib/src/ansi_codes.dart @@ -8,17 +8,15 @@ class AnsiCodes { /// `[1m` - Set text to bold. static const String bold = '$escape[1m'; - /// `[30m` - Set text color to gray. - static const String gray = '$escape[30m'; + static String color(String color) => '$escape[${color}m'; - /// `[38;5;87m` - Set text color to light blue. Used for native actions. - static const String lightBlue = '$escape[38;5;87m'; - - static String custom(String color) => '$escape[${color}m'; - - static String get green => custom('32'); - static String get yellow => custom('33'); - static String get blue => custom('34'); - static String get magenta => custom('35'); - static String get cyan => custom('36'); + static String gray = color('30'); + static String get red => color('31'); + static String get green => color('32'); + static String get yellow => color('33'); + static String get blue => color('34'); + static String get lightBlue => color('38;5;87'); + static String get magenta => color('35'); + static String get cyan => color('36'); + static String get orange => color('38;5;208'); } From beb90740aaa00efbdf3337e1e771236b2facd016 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 11:11:16 +0100 Subject: [PATCH 2/9] Print error entry using red color --- packages/patrol_log/lib/src/entries/error_entry.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/patrol_log/lib/src/entries/error_entry.dart b/packages/patrol_log/lib/src/entries/error_entry.dart index 8ce0993e0..a5635e7fb 100644 --- a/packages/patrol_log/lib/src/entries/error_entry.dart +++ b/packages/patrol_log/lib/src/entries/error_entry.dart @@ -21,7 +21,7 @@ class ErrorEntry extends Entry { @override String pretty() { - return message; + return '${AnsiCodes.red}$message${AnsiCodes.reset}'; } @override From 68c0d6560f324ea2e88a18a4b53d917d30761f34 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 11:11:36 +0100 Subject: [PATCH 3/9] Add warning entry --- .../patrol_log/lib/src/entries/entry.dart | 5 ++- .../patrol_log/lib/src/entries/entry.g.dart | 15 +++++++++ .../lib/src/entries/warning_entry.dart | 32 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/patrol_log/lib/src/entries/warning_entry.dart diff --git a/packages/patrol_log/lib/src/entries/entry.dart b/packages/patrol_log/lib/src/entries/entry.dart index 0b59184ba..68c248546 100644 --- a/packages/patrol_log/lib/src/entries/entry.dart +++ b/packages/patrol_log/lib/src/entries/entry.dart @@ -7,6 +7,7 @@ part 'error_entry.dart'; part 'log_entry.dart'; part 'step_entry.dart'; part 'test_entry.dart'; +part 'warning_entry.dart'; part 'entry.g.dart'; @@ -39,7 +40,8 @@ enum EntryType { error, step, test, - log; + log, + warning; static EntryType byName(String name) { return switch (name) { @@ -47,6 +49,7 @@ enum EntryType { 'step' => EntryType.step, 'test' => EntryType.test, 'log' => EntryType.log, + 'warning' => EntryType.warning, _ => throw ArgumentError('Unknown EntryType: $name') }; } diff --git a/packages/patrol_log/lib/src/entries/entry.g.dart b/packages/patrol_log/lib/src/entries/entry.g.dart index 789f2e7e7..969338629 100644 --- a/packages/patrol_log/lib/src/entries/entry.g.dart +++ b/packages/patrol_log/lib/src/entries/entry.g.dart @@ -25,6 +25,7 @@ const _$EntryTypeEnumMap = { EntryType.step: 'step', EntryType.test: 'test', EntryType.log: 'log', + EntryType.warning: 'warning', }; LogEntry _$LogEntryFromJson(Map json) => LogEntry( @@ -88,3 +89,17 @@ const _$TestEntryStatusEnumMap = { TestEntryStatus.failure: 'failure', TestEntryStatus.skip: 'skip', }; + +WarningEntry _$WarningEntryFromJson(Map json) => WarningEntry( + message: json['message'] as String, + timestamp: json['timestamp'] == null + ? null + : DateTime.parse(json['timestamp'] as String), + ); + +Map _$WarningEntryToJson(WarningEntry instance) => + { + 'timestamp': instance.timestamp.toIso8601String(), + 'type': _$EntryTypeEnumMap[instance.type]!, + 'message': instance.message, + }; diff --git a/packages/patrol_log/lib/src/entries/warning_entry.dart b/packages/patrol_log/lib/src/entries/warning_entry.dart new file mode 100644 index 000000000..ad9142615 --- /dev/null +++ b/packages/patrol_log/lib/src/entries/warning_entry.dart @@ -0,0 +1,32 @@ +part of 'entry.dart'; + +@JsonSerializable() +class WarningEntry extends Entry { + WarningEntry({ + required this.message, + DateTime? timestamp, + }) : super( + timestamp: timestamp ?? DateTime.now(), + type: EntryType.warning, + ); + + @override + factory WarningEntry.fromJson(Map json) => + _$WarningEntryFromJson(json); + + final String message; + + @override + Map toJson() => _$WarningEntryToJson(this); + + @override + String pretty() { + return '${AnsiCodes.yellow}$message${AnsiCodes.reset}'; + } + + @override + String toString() => 'WarningEntry(${toJson()})'; + + @override + List get props => [message, timestamp, type]; +} From 7454da356bc45835fb88da5e2e44ab9d38ebe7eb Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 11:12:06 +0100 Subject: [PATCH 4/9] Fix invalid test path on failed test list --- packages/patrol_log/lib/src/patrol_single_test_entry.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/patrol_log/lib/src/patrol_single_test_entry.dart b/packages/patrol_log/lib/src/patrol_single_test_entry.dart index 8b5bb7815..dec0da30a 100644 --- a/packages/patrol_log/lib/src/patrol_single_test_entry.dart +++ b/packages/patrol_log/lib/src/patrol_single_test_entry.dart @@ -34,7 +34,9 @@ class PatrolSingleTestEntry { closingTestEntry?.status ?? openingTestEntry.status; /// The name of the test with the path. - String get nameWithPath => openingTestEntry.nameWithPath; + /// + /// If test is not closed yet, the path is unknown, so return only test name. + String get nameWithPath => closingTestEntry?.nameWithPath ?? name; /// The execution time of the test. Duration get executionTime { From 71cd4128473ae4e11e036a15969b9b5a57c3db75 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 11:12:54 +0100 Subject: [PATCH 5/9] Replace ' ' in report path with %20 Handle warning entry in PatrolLogReader --- packages/patrol_log/lib/src/patrol_log_reader.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/patrol_log/lib/src/patrol_log_reader.dart b/packages/patrol_log/lib/src/patrol_log_reader.dart index 932c33ed9..157f68f12 100644 --- a/packages/patrol_log/lib/src/patrol_log_reader.dart +++ b/packages/patrol_log/lib/src/patrol_log_reader.dart @@ -146,6 +146,7 @@ class PatrolLogReader { EntryType.test => TestEntry.fromJson(json), EntryType.log => LogEntry.fromJson(json), EntryType.error => ErrorEntry.fromJson(json), + EntryType.warning => WarningEntry.fromJson(json), }; } @@ -205,6 +206,7 @@ class PatrolLogReader { log(entry.pretty()); case ErrorEntry(): + case WarningEntry(): log(entry.pretty()); } }, @@ -226,7 +228,7 @@ class PatrolLogReader { '${Emojis.failure} Failed: $failedTestsCount\n' '${failedTestsCount > 0 ? '$failedTestsList\n' : ''}' '${Emojis.skip} Skipped: $skippedTests\n' - '${Emojis.report} Report: $reportPath\n' + '${Emojis.report} Report: ${reportPath.replaceAll(' ', '%20')}\n' '${Emojis.duration} Duration: ${_stopwatch.elapsed.inSeconds}s\n'; /// Closes the stream subscription and the stream controller. From 2319292ac63c6f8daf7f50f7747ce4d94998dbb0 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 13:39:54 +0100 Subject: [PATCH 6/9] Bump version and update changelog --- packages/patrol_log/CHANGELOG.md | 5 +++++ packages/patrol_log/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/patrol_log/CHANGELOG.md b/packages/patrol_log/CHANGELOG.md index 6cd1eb6b1..87ab55a01 100644 --- a/packages/patrol_log/CHANGELOG.md +++ b/packages/patrol_log/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.0 + +- Fix report path when path contain spaces. +- Fix path to the test file on the failed test list in summary. + ## 0.1.0 - Add option to not clear test steps. diff --git a/packages/patrol_log/pubspec.yaml b/packages/patrol_log/pubspec.yaml index df3010d8f..56bcbfd6e 100644 --- a/packages/patrol_log/pubspec.yaml +++ b/packages/patrol_log/pubspec.yaml @@ -1,7 +1,7 @@ name: patrol_log description: > Log package for Patrol, a powerful Flutter-native UI testing framework. -version: 0.1.0 +version: 0.2.0 homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol/tree/master/packages/patrol_log issue_tracker: https://github.com/leancodepl/patrol/issues From 8cec6b8b179aa8d2488f936fd0f4e1651c533bbe Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 14:42:08 +0100 Subject: [PATCH 7/9] Add `ConfigEntry` to pass config from test to `PatrolLogReader` --- .../lib/src/entries/config_entry.dart | 30 +++++++++++++++++++ .../patrol_log/lib/src/entries/entry.dart | 5 +++- .../patrol_log/lib/src/entries/entry.g.dart | 15 ++++++++++ .../patrol_log/lib/src/patrol_log_reader.dart | 28 +++++++++++++++-- .../patrol_log/lib/src/patrol_log_writer.dart | 6 +++- 5 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 packages/patrol_log/lib/src/entries/config_entry.dart diff --git a/packages/patrol_log/lib/src/entries/config_entry.dart b/packages/patrol_log/lib/src/entries/config_entry.dart new file mode 100644 index 000000000..2055cf2b7 --- /dev/null +++ b/packages/patrol_log/lib/src/entries/config_entry.dart @@ -0,0 +1,30 @@ +part of 'entry.dart'; + +@JsonSerializable() +class ConfigEntry extends Entry { + ConfigEntry({ + required this.config, + DateTime? timestamp, + }) : super( + timestamp: timestamp ?? DateTime.now(), + type: EntryType.config, + ); + + @override + factory ConfigEntry.fromJson(Map json) => + _$ConfigEntryFromJson(json); + + final Map config; + + @override + Map toJson() => _$ConfigEntryToJson(this); + + @override + String pretty() => config.toString(); + + @override + String toString() => 'ConfigEntry(${toJson()})'; + + @override + List get props => [config, timestamp, type]; +} diff --git a/packages/patrol_log/lib/src/entries/entry.dart b/packages/patrol_log/lib/src/entries/entry.dart index 68c248546..fccdf753a 100644 --- a/packages/patrol_log/lib/src/entries/entry.dart +++ b/packages/patrol_log/lib/src/entries/entry.dart @@ -8,6 +8,7 @@ part 'log_entry.dart'; part 'step_entry.dart'; part 'test_entry.dart'; part 'warning_entry.dart'; +part 'config_entry.dart'; part 'entry.g.dart'; @@ -41,7 +42,8 @@ enum EntryType { step, test, log, - warning; + warning, + config; static EntryType byName(String name) { return switch (name) { @@ -50,6 +52,7 @@ enum EntryType { 'test' => EntryType.test, 'log' => EntryType.log, 'warning' => EntryType.warning, + 'config' => EntryType.config, _ => throw ArgumentError('Unknown EntryType: $name') }; } diff --git a/packages/patrol_log/lib/src/entries/entry.g.dart b/packages/patrol_log/lib/src/entries/entry.g.dart index 969338629..b9679f657 100644 --- a/packages/patrol_log/lib/src/entries/entry.g.dart +++ b/packages/patrol_log/lib/src/entries/entry.g.dart @@ -26,6 +26,7 @@ const _$EntryTypeEnumMap = { EntryType.test: 'test', EntryType.log: 'log', EntryType.warning: 'warning', + EntryType.config: 'config', }; LogEntry _$LogEntryFromJson(Map json) => LogEntry( @@ -103,3 +104,17 @@ Map _$WarningEntryToJson(WarningEntry instance) => 'type': _$EntryTypeEnumMap[instance.type]!, 'message': instance.message, }; + +ConfigEntry _$ConfigEntryFromJson(Map json) => ConfigEntry( + config: json['config'] as Map, + timestamp: json['timestamp'] == null + ? null + : DateTime.parse(json['timestamp'] as String), + ); + +Map _$ConfigEntryToJson(ConfigEntry instance) => + { + 'timestamp': instance.timestamp.toIso8601String(), + 'type': _$EntryTypeEnumMap[instance.type]!, + 'config': instance.config, + }; diff --git a/packages/patrol_log/lib/src/patrol_log_reader.dart b/packages/patrol_log/lib/src/patrol_log_reader.dart index 157f68f12..4fca3b91a 100644 --- a/packages/patrol_log/lib/src/patrol_log_reader.dart +++ b/packages/patrol_log/lib/src/patrol_log_reader.dart @@ -43,6 +43,8 @@ class PatrolLogReader { StreamController.broadcast(); late final StreamSubscription _streamSubscription; + final Map _config = {}; + void listen() { // Listen to the entry stream and pretty print the patrol logs. readEntries(); @@ -93,11 +95,10 @@ class PatrolLogReader { /// Take line containg PATROL_LOG tag, parse it to [Entry] and add to stream. void _parsePatrolLog(String line) { - final regExp = RegExp(r'PATROL_LOG \{(.*?)\}'); + final regExp = RegExp('PATROL_LOG (.*)'); final match = regExp.firstMatch(line); if (match != null) { - final matchedText = match.group(1)!; - final json = '{$matchedText}'; + final json = match.group(1)!; final entry = parseEntry(json); if (entry case TestEntry _) { @@ -147,6 +148,7 @@ class PatrolLogReader { EntryType.log => LogEntry.fromJson(json), EntryType.error => ErrorEntry.fromJson(json), EntryType.warning => WarningEntry.fromJson(json), + EntryType.config => ConfigEntry.fromJson(json), }; } @@ -208,11 +210,31 @@ class PatrolLogReader { case ErrorEntry(): case WarningEntry(): log(entry.pretty()); + case ConfigEntry(): + _readConfig(entry); } }, ); } + /// Read the config passed by [PatrolLogWriter]. + void _readConfig(ConfigEntry entry) { + if (_config.isNotEmpty) { + return; + } + + _config.addAll(entry.config); + + if (_config['printLogs'] == false) { + final warningEntry = WarningEntry( + message: 'Printing flutter steps is disabled in the config. ' + 'To enable it, set `PatrolTesterConfig(printLogs: true)`.', + ); + + log(warningEntry.pretty()); + } + } + /// Returns a summary of the test results. That contains: /// /// - Total number of tests diff --git a/packages/patrol_log/lib/src/patrol_log_writer.dart b/packages/patrol_log/lib/src/patrol_log_writer.dart index d9f2ce1ec..7b4a03ef0 100644 --- a/packages/patrol_log/lib/src/patrol_log_writer.dart +++ b/packages/patrol_log/lib/src/patrol_log_writer.dart @@ -4,8 +4,12 @@ import 'dart:convert'; import 'package:patrol_log/patrol_log.dart'; class PatrolLogWriter { - PatrolLogWriter() : _controller = StreamController.broadcast() { + PatrolLogWriter({Map config = const {}}) + : _controller = StreamController.broadcast() { write(); + + /// Pass config to the PatrolLogReader + log(ConfigEntry(config: config)); } final StreamController _controller; From fb690b97a786d641af0b0ea6baefef1b438c1831 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 14:42:33 +0100 Subject: [PATCH 8/9] Update changelog --- packages/patrol_log/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/patrol_log/CHANGELOG.md b/packages/patrol_log/CHANGELOG.md index 87ab55a01..5f95e7624 100644 --- a/packages/patrol_log/CHANGELOG.md +++ b/packages/patrol_log/CHANGELOG.md @@ -2,6 +2,7 @@ - Fix report path when path contain spaces. - Fix path to the test file on the failed test list in summary. +- Add `ConfigEntry`. ## 0.1.0 From 5bf814a1677ab9cf9c1ee7b4af195d44b45ebe83 Mon Sep 17 00:00:00 2001 From: pdenert Date: Fri, 22 Nov 2024 16:01:19 +0100 Subject: [PATCH 9/9] change getters to static variables --- packages/patrol_log/lib/src/ansi_codes.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/patrol_log/lib/src/ansi_codes.dart b/packages/patrol_log/lib/src/ansi_codes.dart index 8c4eec9ae..ee8d7a1bd 100644 --- a/packages/patrol_log/lib/src/ansi_codes.dart +++ b/packages/patrol_log/lib/src/ansi_codes.dart @@ -11,12 +11,12 @@ class AnsiCodes { static String color(String color) => '$escape[${color}m'; static String gray = color('30'); - static String get red => color('31'); - static String get green => color('32'); - static String get yellow => color('33'); - static String get blue => color('34'); - static String get lightBlue => color('38;5;87'); - static String get magenta => color('35'); - static String get cyan => color('36'); - static String get orange => color('38;5;208'); + static String red = color('31'); + static String green = color('32'); + static String yellow = color('33'); + static String blue = color('34'); + static String lightBlue = color('38;5;87'); + static String magenta = color('35'); + static String cyan = color('36'); + static String orange = color('38;5;208'); }