Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change patrol output #2387

Merged
merged 47 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
489fa3b
Add patrol_log package and use it
pdenert Oct 23, 2024
4b4daa7
Wrap native2 with patrol logs
pdenert Oct 23, 2024
db52ab7
Assign PatrolLogWriter value directly in native
pdenert Oct 23, 2024
333dace
Log patrol test status in service
pdenert Oct 23, 2024
a43e1b4
Display test file path in logs
pdenert Oct 23, 2024
78f2def
Treat process error as detail logs
pdenert Oct 23, 2024
a17561b
Treat ios process error as detail logs
pdenert Oct 23, 2024
2fb2c7b
Add list of failed tests in summary
pdenert Oct 24, 2024
927e361
Change pretty of StepEntry status
pdenert Oct 25, 2024
3b4db45
Change pretty of TestEntry
pdenert Oct 25, 2024
a300e75
Log actions in patrol finders
pdenert Oct 25, 2024
47113be
Change LogEntry pretty
pdenert Oct 25, 2024
23d91f0
Remove : from StepEntry pretty
pdenert Oct 25, 2024
01216ae
Prepare logs for patrol develop
pdenert Oct 29, 2024
9bc7321
Print steps counter
pdenert Oct 29, 2024
e252b95
Change test start emoji
pdenert Oct 29, 2024
2509749
Show flutter logs and test steps with flag
pdenert Oct 30, 2024
54da5b0
Don't clear lines when flutter logs are enabled
pdenert Oct 30, 2024
2fbcda5
Remove unused import
pdenert Oct 30, 2024
3b0c3ed
Create proper report path on android app with flavor
pdenert Oct 30, 2024
b3d9898
Fix taking directory to report in cli
pdenert Oct 31, 2024
ca9da64
Use switch expression
pdenert Nov 4, 2024
57ed1dc
Use const indentation
pdenert Nov 4, 2024
7ebc5ec
Keep emojis in single class
pdenert Nov 5, 2024
ab49ea9
Initialize PatrolLog locally
pdenert Nov 5, 2024
dc0f226
Change comment describing log source
pdenert Nov 5, 2024
ed4ebca
Change flag to hideTestSteps
pdenert Nov 5, 2024
5e1ec6c
Fix android report path
pdenert Nov 5, 2024
d5cf9a1
Change emojis in step_entry to one from Emojis class
pdenert Nov 5, 2024
2f60a16
Rename printNumber to printIndex and add comment
pdenert Nov 5, 2024
829948a
Use sealed class and json serializable
pdenert Nov 5, 2024
b69c156
Add class for ascii codes
pdenert Nov 6, 2024
af20ae3
Change report path on windows
pdenert Nov 6, 2024
bae1e70
Add logcat to adb wrapper
pdenert Nov 6, 2024
787d242
Fix - add entry type to generated json
pdenert Nov 6, 2024
2869e10
Change way of generating type in entries toJson
pdenert Nov 6, 2024
d1e9d8b
Refactor reading Entry
pdenert Nov 6, 2024
4654340
Convert to switch expressions
pdenert Nov 8, 2024
44e0951
Change print index body to switch expression
pdenert Nov 8, 2024
0ab2069
Bump adb version
pdenert Nov 8, 2024
6fa4e0a
Print test error when not null
pdenert Nov 8, 2024
4ab8e3b
Add ErrorEntry
pdenert Nov 8, 2024
cc04824
Remove show-flutter-logs from develop
pdenert Nov 8, 2024
5b644d1
Log patrol test start in patrolTest
pdenert Nov 8, 2024
c4308d3
Switch to versions from pub
pdenert Nov 8, 2024
60139d2
Remove unneeded conditions
pdenert Nov 8, 2024
9444598
Update changelogs and versions
pdenert Nov 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dev/e2e_app/integration_test/example_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void main() {
await $(#textField).enterText('Hello, Flutter!');
expect($('Hello, Flutter!'), findsOneWidget);

$.log('Tapped the button');
await $.native.pressHome();
await $.native.openApp();

Expand All @@ -32,6 +33,7 @@ void main() {

patrol(
'short test with two tags',
skip: true,
tags: ['smoke', 'fume'],
($) async {
await createApp($);
Expand Down
2 changes: 2 additions & 0 deletions dev/e2e_app/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import flutter_local_notifications
import flutter_timezone
import geolocator_apple
import patrol
import webview_flutter_wkwebview

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
PatrolPlugin.register(with: registry.registrar(forPlugin: "PatrolPlugin"))
FLTWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "FLTWebViewFlutterPlugin"))
}
24 changes: 19 additions & 5 deletions dev/e2e_app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.10"
dispose_scope:
dependency: transitive
description:
name: dispose_scope
sha256: "48ec38ca2631c53c4f8fa96b294c801e55c335db5e3fb9f82cede150cfe5a2af"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
equatable:
dependency: transitive
description:
Expand Down Expand Up @@ -491,15 +499,21 @@ packages:
path: "../../packages/patrol"
relative: true
source: path
version: "3.11.1"
version: "3.11.2"
patrol_finders:
dependency: transitive
description:
name: patrol_finders
sha256: "6bf2c3093fbccd02f80f73fafc1bd021d76410cbab6e329be220b5e3bc58f072"
url: "https://pub.dev"
source: hosted
path: "../../packages/patrol_finders"
relative: true
source: path
version: "2.1.2"
patrol_log:
dependency: transitive
description:
path: "../../packages/patrol_log"
relative: true
source: path
version: "0.0.1"
permission_handler:
dependency: "direct main"
description:
Expand Down
3 changes: 2 additions & 1 deletion packages/patrol/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Unreleased
## 3.13.0-dev.1

- Add support for the patrol_log package. (#2387)
- Fix tapping on notification on iOS 18. (#2394)

## 3.12.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public RunDartTestResponse runDartTest(String name) {
if (response.getResult() == Contracts.RunDartTestResponseResult.failure) {
throw new AssertionError("Dart test failed: " + name + "\n" + response.getDetails());
}
Logger.INSTANCE.i(TAG + "Test execution succeeded");
return response;
} catch (PatrolAppServiceClientException e) {
Logger.INSTANCE.e(TAG + e.getMessage(), e.getCause());
Expand Down
8 changes: 8 additions & 0 deletions packages/patrol/lib/src/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:patrol/src/global_state.dart' as global_state;
import 'package:patrol/src/native/contracts/contracts.dart';
import 'package:patrol/src/native/native.dart';
import 'package:patrol_finders/patrol_finders.dart' as finders;
import 'package:patrol_log/patrol_log.dart';

/// We need [Group] to recreate test hierarchy.
// ignore: implementation_imports
Expand Down Expand Up @@ -94,11 +95,15 @@ void patrolTest(
LiveTestWidgetsFlutterBindingFramePolicy framePolicy =
LiveTestWidgetsFlutterBindingFramePolicy.fadePointers,
}) {
final patrolLog = PatrolLogWriter();
final automator = NativeAutomator(config: nativeAutomatorConfig);
final automator2 = NativeAutomator2(config: nativeAutomatorConfig);
final patrolBinding = PatrolBinding.ensureInitialized(nativeAutomatorConfig)
..framePolicy = framePolicy;

if (skip ?? false) {
patrolLog.log(TestEntry(name: description, status: TestEntryStatus.skip));
}
testWidgets(
description,
skip: skip,
Expand Down Expand Up @@ -131,6 +136,9 @@ void patrolTest(
// We don't have to call this line because automator.configure() does the same.
// await automator2.configure();

patrolLog.log(
TestEntry(name: description, status: TestEntryStatus.start),
);
final patrolTester = PatrolIntegrationTester(
tester: widgetTester,
nativeAutomator: automator,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import 'package:patrol/src/native/native_automator.dart';
import 'package:patrol/src/native/native_automator2.dart';
import 'package:patrol_finders/patrol_finders.dart' as finders;
import 'package:patrol_log/patrol_log.dart';

/// PatrolIntegrationTester extends the capabilities of [finders.PatrolTester]
/// with the ability to interact with native platform features via [native].
class PatrolIntegrationTester extends finders.PatrolTester {
/// Creates a new [PatrolIntegrationTester] which wraps [tester].
const PatrolIntegrationTester({
PatrolIntegrationTester({
required super.tester,
required super.config,
required this.nativeAutomator,
required this.nativeAutomator2,
});
}) : _patrolLog = PatrolLogWriter();

/// The log for the patrol.
final PatrolLogWriter _patrolLog;

/// Native automator that allows for interaction with OS the app is running
/// on.
Expand All @@ -28,4 +32,9 @@ class PatrolIntegrationTester extends finders.PatrolTester {

/// Shorthand for [nativeAutomator2].
NativeAutomator2 get native2 => nativeAutomator2;

/// Logs a message to the patrol log.
void log(String message) {
_patrolLog.log(LogEntry(message: message));
}
}
46 changes: 44 additions & 2 deletions packages/patrol/lib/src/native/native_automator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:meta/meta.dart';
import 'package:patrol/src/native/contracts/contracts.dart' as contracts;
import 'package:patrol/src/native/contracts/contracts.dart';
import 'package:patrol/src/native/contracts/native_automator_client.dart';
import 'package:patrol_log/patrol_log.dart';

/// Thrown when a native action fails.
class PatrolActionException implements Exception {
Expand Down Expand Up @@ -199,6 +200,7 @@ class NativeAutomator {
_config.logger('NativeAutomatorClient created, port: ${_config.port}');
}

final PatrolLogWriter _patrolLog = PatrolLogWriter();
final NativeAutomatorConfig _config;

late final NativeAutomatorClient _client;
Expand All @@ -214,19 +216,53 @@ class NativeAutomator {
throw StateError('unsupported platform');
}

Future<T> _wrapRequest<T>(String name, Future<T> Function() request) async {
Future<T> _wrapRequest<T>(
String name,
Future<T> Function() request, {
bool enablePatrolLog = true,
}) async {
_config.logger('$name() started');
final text =
'${AnsiCodes.lightBlue}$name${AnsiCodes.reset} ${AnsiCodes.gray}(native)${AnsiCodes.reset}';

if (enablePatrolLog) {
_patrolLog.log(StepEntry(action: text, status: StepEntryStatus.start));
}
try {
final result = await request();
_config.logger('$name() succeeded');
if (enablePatrolLog) {
_patrolLog
.log(StepEntry(action: text, status: StepEntryStatus.success));
}
return result;
} on NativeAutomatorClientException catch (err) {
_config.logger('$name() failed');
final log = 'NativeAutomatorClientException: '
'$name() failed with $err';

if (enablePatrolLog) {
_patrolLog.log(
StepEntry(
action: text,
status: StepEntryStatus.failure,
exception: log,
),
);
}
throw PatrolActionException(log);
} catch (err) {
_config.logger('$name() failed');

if (enablePatrolLog) {
_patrolLog.log(
StepEntry(
action: text,
status: StepEntryStatus.failure,
exception: err.toString(),
),
);
}
rethrow;
}
}
Expand All @@ -241,7 +277,11 @@ class NativeAutomator {
/// See also:
/// * https://github.com/flutter/flutter/issues/129231
Future<void> initialize() async {
await _wrapRequest('initialize', _client.initialize);
await _wrapRequest(
'initialize',
_client.initialize,
enablePatrolLog: false,
);
}

/// Configures the native automator.
Expand All @@ -260,6 +300,7 @@ class NativeAutomator {
findTimeoutMillis: _config.findTimeout.inMilliseconds,
),
),
enablePatrolLog: false,
);
exception = null;
break;
Expand Down Expand Up @@ -940,6 +981,7 @@ class NativeAutomator {
await _wrapRequest(
'markPatrolAppServiceReady',
_client.markPatrolAppServiceReady,
enablePatrolLog: false,
);
}
}
46 changes: 44 additions & 2 deletions packages/patrol/lib/src/native/native_automator2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:patrol/src/native/contracts/contracts.dart' as contracts;
import 'package:patrol/src/native/contracts/native_automator_client.dart';
import 'package:patrol/src/native/native_automator.dart';
import 'package:patrol/src/native/native_automator.dart' as native_automator;
import 'package:patrol_log/patrol_log.dart';

/// This class represents the result of [NativeAutomator.getNativeViews].
class GetNativeViewsResult {
Expand Down Expand Up @@ -81,6 +82,7 @@ class NativeAutomator2 {
_config.logger('NativeAutomatorClient created, port: ${_config.port}');
}

final PatrolLogWriter _patrolLog = PatrolLogWriter();
final NativeAutomatorConfig _config;

late final NativeAutomatorClient _client;
Expand All @@ -96,19 +98,53 @@ class NativeAutomator2 {
throw StateError('unsupported platform');
}

Future<T> _wrapRequest<T>(String name, Future<T> Function() request) async {
Future<T> _wrapRequest<T>(
String name,
Future<T> Function() request, {
bool enablePatrolLog = true,
}) async {
_config.logger('$name() started');
final text =
'${AnsiCodes.lightBlue}$name${AnsiCodes.reset} ${AnsiCodes.gray}(native)${AnsiCodes.reset}';

if (enablePatrolLog) {
_patrolLog.log(StepEntry(action: text, status: StepEntryStatus.start));
}
try {
final result = await request();
_config.logger('$name() succeeded');
if (enablePatrolLog) {
_patrolLog
.log(StepEntry(action: text, status: StepEntryStatus.success));
}
return result;
} on NativeAutomatorClientException catch (err) {
_config.logger('$name() failed');
final log = 'NativeAutomatorClientException: '
'$name() failed with $err';

if (enablePatrolLog) {
_patrolLog.log(
StepEntry(
action: text,
status: StepEntryStatus.failure,
exception: log,
),
);
}
throw PatrolActionException(log);
} catch (err) {
_config.logger('$name() failed');

if (enablePatrolLog) {
_patrolLog.log(
StepEntry(
action: text,
status: StepEntryStatus.failure,
exception: err.toString(),
),
);
}
rethrow;
}
}
Expand All @@ -123,7 +159,11 @@ class NativeAutomator2 {
/// See also:
/// * https://github.com/flutter/flutter/issues/129231
Future<void> initialize() async {
await _wrapRequest('initialize', _client.initialize);
await _wrapRequest(
'initialize',
_client.initialize,
enablePatrolLog: false,
);
}

/// Configures the native automator.
Expand All @@ -142,6 +182,7 @@ class NativeAutomator2 {
findTimeoutMillis: _config.findTimeout.inMilliseconds,
),
),
enablePatrolLog: false,
);
exception = null;
break;
Expand Down Expand Up @@ -819,6 +860,7 @@ class NativeAutomator2 {
await _wrapRequest(
'markPatrolAppServiceReady',
_client.markPatrolAppServiceReady,
enablePatrolLog: false,
);
}
}
22 changes: 22 additions & 0 deletions packages/patrol/lib/src/native/patrol_app_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'dart:io';
import 'package:patrol/src/common.dart';
import 'package:patrol/src/native/contracts/contracts.dart';
import 'package:patrol/src/native/contracts/patrol_app_service_server.dart';
import 'package:patrol_log/patrol_log.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;

Expand Down Expand Up @@ -78,6 +79,8 @@ class PatrolAppService extends PatrolAppServiceServer {
return _testExecutionCompleted.future;
}

final PatrolLogWriter _patrolLog = PatrolLogWriter();

/// Marks [dartFileName] as completed with the given [passed] status.
///
/// If an exception was thrown during the test, [details] should contain the
Expand Down Expand Up @@ -150,6 +153,25 @@ class PatrolAppService extends PatrolAppServiceServer {
_testExecutionRequested.complete(request.name);

final testExecutionResult = await testExecutionCompleted;
if (!testExecutionResult.passed) {
_patrolLog.log(
TestEntry(
name: request.name,
status: TestEntryStatus.failure,
),
);
testExecutionResult.details?.split('\n').forEach(
(e) => _patrolLog.log(ErrorEntry(message: e)),
);
} else {
_patrolLog.log(
TestEntry(
name: request.name,
status: TestEntryStatus.success,
),
);
}

return RunDartTestResponse(
result: testExecutionResult.passed
? RunDartTestResponseResult.success
Expand Down
Loading
Loading