diff --git a/packages/patrol/example/pubspec.yaml b/packages/patrol/example/pubspec.yaml index 9bddd7701..792b109b3 100644 --- a/packages/patrol/example/pubspec.yaml +++ b/packages/patrol/example/pubspec.yaml @@ -21,8 +21,6 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - integration_test: - sdk: flutter leancode_lint: ^3.0.0 patrol: path: ../ diff --git a/packages/patrol/lib/src/binding.dart b/packages/patrol/lib/src/binding.dart index 5fcbe7d60..8ac5bd9d2 100644 --- a/packages/patrol/lib/src/binding.dart +++ b/packages/patrol/lib/src/binding.dart @@ -1,8 +1,9 @@ +import 'dart:convert'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/common.dart'; -import 'package:integration_test/integration_test.dart'; import 'package:patrol/patrol.dart'; import 'package:patrol/src/devtools_service_extensions/devtools_service_extensions.dart'; // ignore: implementation_imports, depend_on_referenced_packages @@ -33,12 +34,14 @@ void _defaultPrintLogger(String message) { /// [PatrolBinding] submits the Dart test file name that is being currently /// executed to [PatrolAppService]. Once the name is submitted to it, that /// pending `runDartTest()` method returns. -class PatrolBinding extends IntegrationTestWidgetsFlutterBinding { +class PatrolBinding extends LiveTestWidgetsFlutterBinding { /// Creates a new [PatrolBinding]. /// /// You most likely don't want to call it yourself. PatrolBinding(NativeAutomatorConfig config) : _serviceExtensions = DevtoolsServiceExtensions(config) { + shouldPropagateDevicePointerEvents = true; + final oldTestExceptionReporter = reportTestException; reportTestException = (details, testDescription) { final currentDartTest = _currentDartTest; @@ -111,6 +114,12 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding { return _instance!; } + @override + bool get overrideHttpClient => false; + + @override + bool get registerTestTextInput => false; + /// Logger used by this binding. void Function(String message) logger = _defaultPrintLogger; @@ -131,16 +140,12 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding { String? _currentDartTest; - /// Keys are the test descriptions, and values are either [_success] or - /// a [Failure]. + /// Keys are the test descriptions, and values are either [_success] or a + /// [Failure]. final Map _testResults = {}; final DevtoolsServiceExtensions _serviceExtensions; - // TODO: Remove once https://github.com/flutter/flutter/pull/108430 is available on the stable channel - @override - TestBindingEventSource get pointerEventSource => TestBindingEventSource.test; - @override void initInstances() { super.initInstances(); @@ -177,6 +182,15 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding { _testResults[description] ??= _success; } + @override + ViewConfiguration createViewConfigurationFor(RenderView renderView) { + final view = renderView.flutterView; + return TestViewConfiguration.fromView( + size: view.physicalSize / view.devicePixelRatio, + view: view, + ); + } + @override Widget wrapWithDefaultView(Widget rootWidget) { assert( @@ -193,7 +207,8 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding { textDirection: TextDirection.ltr, children: [ RepaintBoundary(child: rootWidget), - // Prevents crashes when Android activity is resumed (see https://github.com/leancodepl/patrol/issues/901) + // Prevents crashes when Android activity is resumed (see + // https://github.com/leancodepl/patrol/issues/901) ExcludeSemantics( child: Padding( padding: EdgeInsets.only( @@ -214,4 +229,45 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding { ); } } + + @override + void reportExceptionNoticed(FlutterErrorDetails exception) { + // This override is copied from IntegrationTestWidgetsFlutterBinding. It may + // be not needed. + // + // See: https://github.com/flutter/flutter/issues/81534 + } +} + +/// Representing a failure includes the method name and the failure details. +class Failure { + /// Constructor requiring all fields during initialization. + Failure(this.methodName, this.details); + + /// The name of the test method which failed. + final String methodName; + + /// The details of the failure such as stack trace. + final String? details; + + /// Serializes the object to JSON. + String toJson() { + return json.encode({ + 'methodName': methodName, + 'details': details, + }); + } + + @override + String toString() => toJson(); + + /// Decode a JSON string to create a Failure object. + // ignore: prefer_constructors_over_static_methods + static Failure fromJsonString(String jsonString) { + final failure = json.decode(jsonString) as Map; + return Failure( + failure['methodName'] as String, + failure['details'] as String?, + ); + } } diff --git a/packages/patrol/lib/src/common.dart b/packages/patrol/lib/src/common.dart index 92a8756e9..96e87232e 100644 --- a/packages/patrol/lib/src/common.dart +++ b/packages/patrol/lib/src/common.dart @@ -2,7 +2,6 @@ import 'dart:io' as io; import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; import 'package:meta/meta.dart'; import 'package:patrol/src/binding.dart'; import 'package:patrol/src/global_state.dart' as global_state; @@ -37,9 +36,6 @@ typedef PatrolTesterCallback = Future Function(PatrolIntegrationTester $); /// }, /// ); /// ``` -/// -/// [bindingType] specifies the binding to use. [bindingType] is ignored if -/// [nativeAutomation] is false. @isTest void patrolTest( String description, @@ -52,7 +48,6 @@ void patrolTest( finders.PatrolTesterConfig config = const finders.PatrolTesterConfig(), NativeAutomatorConfig nativeAutomatorConfig = const NativeAutomatorConfig(), bool nativeAutomation = false, - BindingType bindingType = BindingType.patrol, LiveTestWidgetsFlutterBindingFramePolicy framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fadePointers, }) { @@ -72,21 +67,9 @@ void patrolTest( } if (nativeAutomation) { - switch (bindingType) { - case BindingType.patrol: - automator = NativeAutomator(config: nativeAutomatorConfig); - - patrolBinding = PatrolBinding.ensureInitialized(nativeAutomatorConfig); - patrolBinding.framePolicy = framePolicy; - break; - case BindingType.integrationTest: - IntegrationTestWidgetsFlutterBinding.ensureInitialized().framePolicy = - framePolicy; - - break; - case BindingType.none: - break; - } + automator = NativeAutomator(config: nativeAutomatorConfig); + patrolBinding = PatrolBinding.ensureInitialized(nativeAutomatorConfig) + ..framePolicy = framePolicy; } testWidgets( diff --git a/packages/patrol/lib/src/native/native_automator.dart b/packages/patrol/lib/src/native/native_automator.dart index af0efa4cc..8322d4e7e 100644 --- a/packages/patrol/lib/src/native/native_automator.dart +++ b/packages/patrol/lib/src/native/native_automator.dart @@ -2,11 +2,9 @@ import 'dart:io' as io; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; -import 'package:integration_test/integration_test.dart'; import 'package:meta/meta.dart'; -import 'package:patrol/src/binding.dart'; -import 'package:patrol/src/native/contracts/contracts.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'; /// Thrown when a native action fails. @@ -21,18 +19,6 @@ class PatrolActionException implements Exception { String toString() => 'Patrol action failed: $message'; } -/// Bindings available to use with [NativeAutomator]. -enum BindingType { - /// Initialize [PatrolBinding]. - patrol, - - /// Initializes [IntegrationTestWidgetsFlutterBinding] - integrationTest, - - /// Doesn't initialize any binding. - none, -} - /// Specifies how the OS keyboard should behave when using /// [NativeAutomator.enterText] and [NativeAutomator.enterTextByIndex]. enum KeyboardBehavior { @@ -92,6 +78,10 @@ class NativeAutomatorConfig { this.logger = _defaultPrintLogger, }); + /// Apps installed on the iOS simulator. + /// + /// This is needed for purpose of native view inspection in the Patrol + /// DevTools extension. final String iosInstalledApps; /// Host on which Patrol server instrumentation is running. diff --git a/packages/patrol/pubspec.yaml b/packages/patrol/pubspec.yaml index e7b44d77e..706c131b1 100644 --- a/packages/patrol/pubspec.yaml +++ b/packages/patrol/pubspec.yaml @@ -19,8 +19,6 @@ dependencies: flutter_test: sdk: flutter http: '>=0.13.5 <2.0.0' - integration_test: - sdk: flutter json_annotation: ^4.6.0 meta: ^1.7.0 path: ^1.8.2