From c9ca3bf7e6236adc18060f8a03c01f42e839e969 Mon Sep 17 00:00:00 2001 From: Bartek Pacia Date: Wed, 29 Nov 2023 21:47:18 +0100 Subject: [PATCH 1/3] implement patrolSetUp and patrolTearDown --- packages/patrol/lib/src/binding.dart | 8 ++-- packages/patrol/lib/src/common.dart | 57 ++++++++++++++++------------ 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/packages/patrol/lib/src/binding.dart b/packages/patrol/lib/src/binding.dart index 0511a6ad0..990c554af 100644 --- a/packages/patrol/lib/src/binding.dart +++ b/packages/patrol/lib/src/binding.dart @@ -54,7 +54,10 @@ class PatrolBinding extends LiveTestWidgetsFlutterBinding { setUp(() { if (constants.hotRestartEnabled) { - // Sending results ends the test, which we don't want for Hot Restart + return; + } + + if (global_state.currentTestIndividualName == 'patrol_test_explorer') { return; } @@ -68,8 +71,7 @@ class PatrolBinding extends LiveTestWidgetsFlutterBinding { } final testName = global_state.currentTestIndividualName; - final isTestExplorer = testName == 'patrol_test_explorer'; - if (isTestExplorer) { + if (testName == 'patrol_test_explorer') { return; } else { logger( diff --git a/packages/patrol/lib/src/common.dart b/packages/patrol/lib/src/common.dart index 16a8c9a97..5a82edd15 100644 --- a/packages/patrol/lib/src/common.dart +++ b/packages/patrol/lib/src/common.dart @@ -19,6 +19,34 @@ import 'custom_finders/patrol_integration_tester.dart'; /// Signature for callback to [patrolTest]. typedef PatrolTesterCallback = Future Function(PatrolIntegrationTester $); +/// A modification of [setUp] that works with Patrol's native automation. +void patrolSetUp(dynamic Function() body) { + setUp(() async { + final currentTest = global_state.currentTestFullName; + + final requestedToExecute = await PatrolBinding.instance.patrolAppService + .waitForExecutionRequest(currentTest); + + if (requestedToExecute) { + await body(); + } + }); +} + +/// A modification of [tearDown] that works with Patrol's native automation. +void patrolTearDown(dynamic Function() body) { + tearDown(() async { + final currentTest = global_state.currentTestFullName; + + final requestedToExecute = await PatrolBinding.instance.patrolAppService + .waitForExecutionRequest(currentTest); + + if (requestedToExecute) { + await body(); + } + }); +} + /// Like [testWidgets], but with support for Patrol custom finders. /// /// To customize the Patrol-specific configuration, set [config]. @@ -50,14 +78,9 @@ void patrolTest( LiveTestWidgetsFlutterBindingFramePolicy framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fadePointers, }) { - NativeAutomator automator; - - PatrolBinding? patrolBinding; - - automator = NativeAutomator(config: nativeAutomatorConfig); - final binding = - patrolBinding = PatrolBinding.ensureInitialized(nativeAutomatorConfig) - ..framePolicy = framePolicy; + final automator = NativeAutomator(config: nativeAutomatorConfig); + final patrolBinding = PatrolBinding.ensureInitialized(nativeAutomatorConfig) + ..framePolicy = framePolicy; testWidgets( description, @@ -67,23 +90,10 @@ void patrolTest( variant: variant, tags: tags, (widgetTester) async { - if (patrolBinding != null && !constants.hotRestartEnabled) { + if (!constants.hotRestartEnabled) { // If Patrol's native automation feature is enabled, then this test will // be executed only if the native side requested it to be executed. // Otherwise, it returns early. - // - // The assumption here is that this test doesn't have any extra parent - // groups. Every Dart test suite has an implict, unnamed, top-level - // group. An additional group is present in the bundled_test.dart, and - // its name is equal to the path to the Dart test file in the - // integration_test directory. - // - // In other words, the developer cannot use `group()` in the tests. - // - // Example: if this function is called from the Dart test file named - // "example_test.dart", and that file is located in the - // "integration_test/examples" directory, we assume that the name of the - // immediate parent group is "examples.example_test". final requestedToExecute = await patrolBinding.patrolAppService .waitForExecutionRequest(global_state.currentTestFullName); @@ -114,7 +124,7 @@ void patrolTest( final waitDuration = Duration(seconds: waitSeconds); debugDefaultTargetPlatformOverride = - binding.workaroundDebugDefaultTargetPlatformOverride; + patrolBinding.workaroundDebugDefaultTargetPlatformOverride; if (waitDuration > Duration.zero) { final stopwatch = Stopwatch()..start(); @@ -175,7 +185,6 @@ DartGroupEntry createDartTestGroup( ); } else if (entry is Test) { if (entry.name == 'patrol_test_explorer') { - // throw StateError('Expected group, got test: ${entry.name}'); // Ignore the bogus test that is used to discover the test structure. continue; } From 09f86eaf101ed03b6c8440041947ef4e59ec2e4c Mon Sep 17 00:00:00 2001 From: Bartek Pacia Date: Wed, 29 Nov 2023 22:39:12 +0100 Subject: [PATCH 2/3] add internal/callbacks_test.dart --- .../internal/callbacks_test.dart | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 dev/e2e_app/integration_test/internal/callbacks_test.dart diff --git a/dev/e2e_app/integration_test/internal/callbacks_test.dart b/dev/e2e_app/integration_test/internal/callbacks_test.dart new file mode 100644 index 000000000..fff11dfe5 --- /dev/null +++ b/dev/e2e_app/integration_test/internal/callbacks_test.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:patrol/src/global_state.dart' as global_state; + +import '../common.dart'; + +String get currentTest => global_state.currentTestFullName; + +void _print(String text) => print('PATROL_DEBUG: $text'); + +void main() { + patrolSetUp(() async { + await Future.delayed(Duration(seconds: 1)); + _print('setUp 1 (level 1) before $currentTest'); + }); + + patrolTearDown(() async { + await Future.delayed(Duration(seconds: 1)); + _print('tearDown 1 (level 1) after $currentTest'); + }); + + patrolTest('testFirst', _body); + + group('groupA', () { + patrolSetUp(() async { + if (currentTest == 'internal.callbacks_test groupA testB') { + throw Exception('PATROL_DEBUG: Crashing testB on purpose!'); + } + _print('setUp 1 (level 2) before $currentTest'); + }); + + patrolTearDown(() async { + _print('tearDown 1 (level 2) after $currentTest'); + }); + + patrolTest('testA', _body); + patrolTest('testB', _body); + patrolTest('testC', _body); + }); + + patrolTest('testLast', _body); +} + +Future _body(PatrolIntegrationTester $) async { + _print('test body: name=${global_state.currentTestFullName}'); + + await createApp($); + + await $(FloatingActionButton).tap(); + expect($(#counterText).text, '1'); + + await $(#textField).enterText(global_state.currentTestFullName); + + await $.pumpAndSettle(duration: Duration(seconds: 2)); +} From e524db0f5816f7d9d2d4c7f3130372f4e39ca4e0 Mon Sep 17 00:00:00 2001 From: Bartek Pacia Date: Wed, 29 Nov 2023 22:39:30 +0100 Subject: [PATCH 3/3] Revert "add internal/callbacks_test.dart" This reverts commit 09f86eaf101ed03b6c8440041947ef4e59ec2e4c. --- .../internal/callbacks_test.dart | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 dev/e2e_app/integration_test/internal/callbacks_test.dart diff --git a/dev/e2e_app/integration_test/internal/callbacks_test.dart b/dev/e2e_app/integration_test/internal/callbacks_test.dart deleted file mode 100644 index fff11dfe5..000000000 --- a/dev/e2e_app/integration_test/internal/callbacks_test.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:patrol/src/global_state.dart' as global_state; - -import '../common.dart'; - -String get currentTest => global_state.currentTestFullName; - -void _print(String text) => print('PATROL_DEBUG: $text'); - -void main() { - patrolSetUp(() async { - await Future.delayed(Duration(seconds: 1)); - _print('setUp 1 (level 1) before $currentTest'); - }); - - patrolTearDown(() async { - await Future.delayed(Duration(seconds: 1)); - _print('tearDown 1 (level 1) after $currentTest'); - }); - - patrolTest('testFirst', _body); - - group('groupA', () { - patrolSetUp(() async { - if (currentTest == 'internal.callbacks_test groupA testB') { - throw Exception('PATROL_DEBUG: Crashing testB on purpose!'); - } - _print('setUp 1 (level 2) before $currentTest'); - }); - - patrolTearDown(() async { - _print('tearDown 1 (level 2) after $currentTest'); - }); - - patrolTest('testA', _body); - patrolTest('testB', _body); - patrolTest('testC', _body); - }); - - patrolTest('testLast', _body); -} - -Future _body(PatrolIntegrationTester $) async { - _print('test body: name=${global_state.currentTestFullName}'); - - await createApp($); - - await $(FloatingActionButton).tap(); - expect($(#counterText).text, '1'); - - await $(#textField).enterText(global_state.currentTestFullName); - - await $.pumpAndSettle(duration: Duration(seconds: 2)); -}