Skip to content

Commit

Permalink
Remove patrol's dependency on integration test plugin (#1882)
Browse files Browse the repository at this point in the history
* Fix naming of NativeView properties in the extension UI

* make PatrolBinding no longer extend IntegrationTestWidgetsFlutterBinding

* remove `integration_test` from dependencies

* remove all usages of `integration_test`'s members

* add doc comment to PatrolBinding.iosInstalledApps

---------

Co-authored-by: Mateusz Wojtczak <[email protected]>
  • Loading branch information
bartekpacia and mateuszwojtczak authored Nov 13, 2023
1 parent f35adfe commit 5614356
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 49 deletions.
2 changes: 0 additions & 2 deletions packages/patrol/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
leancode_lint: ^3.0.0
patrol:
path: ../
Expand Down
76 changes: 66 additions & 10 deletions packages/patrol/lib/src/binding.dart
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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<String, Object> _testResults = <String, Object>{};

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();
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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(<String, String?>{
'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<String, dynamic>;
return Failure(
failure['methodName'] as String,
failure['details'] as String?,
);
}
}
23 changes: 3 additions & 20 deletions packages/patrol/lib/src/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -37,9 +36,6 @@ typedef PatrolTesterCallback = Future<void> Function(PatrolIntegrationTester $);
/// },
/// );
/// ```
///
/// [bindingType] specifies the binding to use. [bindingType] is ignored if
/// [nativeAutomation] is false.
@isTest
void patrolTest(
String description,
Expand All @@ -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,
}) {
Expand All @@ -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(
Expand Down
20 changes: 5 additions & 15 deletions packages/patrol/lib/src/native/native_automator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions packages/patrol/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5614356

Please sign in to comment.