From 346fd8144e223944e2cb3d06aa752bce8037c478 Mon Sep 17 00:00:00 2001 From: piotruela Date: Thu, 28 Nov 2024 20:39:58 +0100 Subject: [PATCH 1/4] Remove whitespace replacement from Android runner --- .../pl/leancode/patrol/PatrolJUnitRunner.java | 24 +++---------------- .../patrol/example/android/app/build.gradle | 2 +- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolJUnitRunner.java b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolJUnitRunner.java index 47e79b3f8..2568cd211 100644 --- a/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolJUnitRunner.java +++ b/packages/patrol/android/src/main/kotlin/pl/leancode/patrol/PatrolJUnitRunner.java @@ -35,8 +35,6 @@ public class PatrolJUnitRunner extends AndroidJUnitRunner { public PatrolAppServiceClient patrolAppServiceClient; private Map dartTestCaseSkipMap = new HashMap<>(); - private String spaceReplacement = "__"; - @Override protected boolean shouldWaitForActivitiesToComplete() { return false; @@ -117,9 +115,8 @@ public Object[] listDartTests() { List dartTestCases = ContractsExtensionsKt.listTestsFlat(dartTestGroup, ""); List dartTestCaseNamesList = new ArrayList<>(); for (DartGroupEntry dartTestCase : dartTestCases) { - final String testName = sanitizeTestCaseName(dartTestCase.getName()); - dartTestCaseSkipMap.put(testName, dartTestCase.getSkip()); - dartTestCaseNamesList.add(testName); + dartTestCaseSkipMap.put(dartTestCase.getName(), dartTestCase.getSkip()); + dartTestCaseNamesList.add(dartTestCase.getName()); } Object[] dartTestCaseNames = dartTestCaseNamesList.toArray(); Logger.INSTANCE.i(TAG + "Got Dart tests: " + Arrays.toString(dartTestCaseNames)); @@ -145,7 +142,7 @@ public RunDartTestResponse runDartTest(String name) { try { Logger.INSTANCE.i(TAG + "Requested execution"); - RunDartTestResponse response = patrolAppServiceClient.runDartTest(originalTestCaseName(name)); + RunDartTestResponse response = patrolAppServiceClient.runDartTest(name); if (response.getResult() == Contracts.RunDartTestResponseResult.failure) { throw new AssertionError("Dart test failed: " + name + "\n" + response.getDetails()); } @@ -156,19 +153,4 @@ public RunDartTestResponse runDartTest(String name) { throw new RuntimeException(e); } } - - /** - * We need to remove whitespaces from test case name in order to make in compatible with Orchestrator 1.5.0. - * New requirement can be observed (here). - * */ - private String sanitizeTestCaseName(String name) { - return name.replace(" ", spaceReplacement); - } - - /** - * When calling test on dart side, we need to bring back original test case name. - * */ - private String originalTestCaseName(String name) { - return name.replace(spaceReplacement, " "); - } } diff --git a/packages/patrol/example/android/app/build.gradle b/packages/patrol/example/android/app/build.gradle index f5de74ea7..05f6330e5 100644 --- a/packages/patrol/example/android/app/build.gradle +++ b/packages/patrol/example/android/app/build.gradle @@ -82,5 +82,5 @@ flutter { } dependencies { - androidTestUtil 'androidx.test:orchestrator:1.4.2' + androidTestUtil 'androidx.test:orchestrator:1.5.1' } From 85f7f5c2a93e83eadb049fa023733f59e95c5b65 Mon Sep 17 00:00:00 2001 From: piotruela Date: Thu, 28 Nov 2024 20:50:48 +0100 Subject: [PATCH 2/4] Update getting started docs to use orchestrator 1.5.1 --- docs/getting-started.mdx | 585 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 585 insertions(+) diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx index b4c5570b0..390a477e9 100644 --- a/docs/getting-started.mdx +++ b/docs/getting-started.mdx @@ -1,3 +1,588 @@ --- redirect: /documentation --- + +# Getting started + +Check out our video version of this tutorial on YouTube! + + + + + If you want to use Patrol finders in your existing widget or golden + tests, go to [Using Patrol finders in widget tests]. + + + + In this tutorial, we are using example app, which has package name + `com.example.myapp` on Android, bundle id `com.example.MyApp` on iOS, + `com.example.macos.MyApp` on macOS and `My App` name on all platforms. + Replace any occurences of those names with proper values. + + + + Support for macOS is in alpha stage. Please be aware that some features + may not work as expected. There is also no native automation support + for macOS yet. If you encounter any issues, please report them on + GitHub. + + +### Add dependency on `patrol` + +If you haven't already, add a dependency on the `patrol` package in the +`dev_dependencies` section of `pubspec.yaml`. `patrol` package requires +Android SDK version 21 or higher. + +``` +flutter pub add patrol --dev +``` + +### Configure Patrol in `pubspec.yaml` + +Create `patrol` section in your `pubspec.yaml`: + +```yaml title="pubspec.yaml" +dependencies: + # ... + +dev_dependencies: + # ... + +patrol: + app_name: My App + android: + package_name: com.example.myapp + ios: + bundle_id: com.example.MyApp + macos: + bundle_id: com.example.macos.MyApp +``` + +If you don't know where to get `package_name` and `bundle_id` from, see the [FAQ] section. + +### Install `patrol_cli` + +[Patrol CLI] (command-line interface) is a small program that enables running +Patrol UI tests. It is necessary to run UI tests (`flutter test` won't work! [Here's why]). + +1. Install `patrol_cli` executable: + + ``` + dart pub global activate patrol_cli + ``` + + + Make sure to add `patrol` to your `PATH` environment variable. + It's explained how to do it in the [README](https://pub.dev/packages/patrol_cli#installation). + + +2. Verify that installation was successful and your environment is set up properly: + + ``` + patrol doctor + ``` + Example output: + ``` + Patrol CLI version: 2.3.1+1 + Android: + • Program adb found in /Users/username/Library/Android/sdk/platform-tools/adb + • Env var $ANDROID_HOME set to /Users/username/Library/Android/sdk + iOS / macOS: + • Program xcodebuild found in /usr/bin/xcodebuild + • Program ideviceinstaller found in /opt/homebrew/bin/ideviceinstaller + ``` + Be sure that for the platform you want to run the test on, all the checks are green. + +Patrol CLI invokes the Flutter CLI for certain commands. To override the command used, +pass the `--flutter-command` argument or set the `PATROL_FLUTTER_COMMAND` environment +variable. This supports FVM (by setting the value to `fvm flutter`), puro (`puro flutter`) +and potentially other version managers. + +### Integrate with native side + +The 3 first steps were common across platforms. The rest is platform-specific. + +Psst... Android is a bit easier to set up, so we recommend starting with it! + + + + 1. Go to **android/app/src/androidTest/java/com/example/myapp/** in your project + directory. If there are no such folders, create them. **Remember to replace + `/com/example/myapp/` with the path created by your app's package name.** + + 2. Create a file named `MainActivityTest.java` and copy there the code below. + + ```java title="MainActivityTest.java" + package com.example.myapp; // replace "com.example.myapp" with your app's package + + import androidx.test.platform.app.InstrumentationRegistry; + import org.junit.Test; + import org.junit.runner.RunWith; + import org.junit.runners.Parameterized; + import org.junit.runners.Parameterized.Parameters; + import pl.leancode.patrol.PatrolJUnitRunner; + + @RunWith(Parameterized.class) + public class MainActivityTest { + @Parameters(name = "{0}") + public static Object[] testCases() { + PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation(); + // replace "MainActivity.class" with "io.flutter.embedding.android.FlutterActivity.class" + // if in AndroidManifest.xml in manifest/application/activity you have + // android:name="io.flutter.embedding.android.FlutterActivity" + instrumentation.setUp(MainActivity.class); + instrumentation.waitForPatrolAppService(); + return instrumentation.listDartTests(); + } + + public MainActivityTest(String dartTestName) { + this.dartTestName = dartTestName; + } + + private final String dartTestName; + + @Test + public void runDartTest() { + PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation(); + instrumentation.runDartTest(dartTestName); + } + } + ``` + + 3. Go to the **build.gradle** file, located in **android/app** folder in your + project directory. + + 4. Add these 2 lines to the `defaultConfig` section: + + ```groovy + testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner" + testInstrumentationRunnerArguments clearPackageData: "true" + ``` + + 5. Add this section to the `android` section: + + ```groovy + testOptions { + execution "ANDROIDX_TEST_ORCHESTRATOR" + } + ``` + + 6. Add this line to `dependencies` section: + + ```groovy + androidTestUtil "androidx.test:orchestrator:1.5.1" + ``` + + + Bear in mind that ProGuard can lead to some problems if not well configured, potentially causing issues such as `ClassNotFoundException`s. + Keep all the Patrol packages or disable ProGuard in `android/app/build.gradle`: + ```groovy + ... + buildTypes { + release { + ... + } + debug { + minifyEnabled false + shrinkResources false + } + } + ``` + + + + + + + 1. Open `ios/Runner.xcworkspace` in Xcode. + + 2. Create a test target if you do not already have one (see the screenshot below + for the reference). Select `File > New > Target...` and select `UI Testing Bundle`. + Change the `Product Name` to `RunnerUITests`. Set the `Organization Identifier` + to be the same as for the `Runner` (no matter if you app has flavors or not). + For our example app, it's `com.example.MyApp` just as in the `pubspec.yaml` file. + Make sure `Target to be Tested` is set to `Runner` and language is set to `Objective-C`. + Select `Finish`. + + ![Xcode iOS test target](/assets/ios_test_target.png) + + 3. 2 files are created: `RunnerUITests.m` and `RunnerUITestsLaunchTests.m`. + Delete `RunnerUITestsLaunchTests.m` **through Xcode** by clicking on it and + selecting `Move to Trash`. + + 4. Make sure that the **iOS Deployment Target** of `RunnerUITests` within the + **Build Settings** section is the same as `Runner`. + The minimum supported **iOS Deployment Target** is `11.0`. For the + [example app](https://github.com/leancodepl/patrol/tree/master/packages/patrol/example), + we set it to `13.0` because it's required by the app dependencies. + + ![Xcode iOS deployment target](/assets/ios_deployment_target.png) + + ![Xcode iOS deployment target 2](/assets/ios_deployment_target_2.png) + + 5. Replace contents of `RunnerUITests.m` file with the following: + + ```objective-c title="ios/RunnerUITests/RunnerUITests.m" + @import XCTest; + @import patrol; + @import ObjectiveC.runtime; + + PATROL_INTEGRATION_TEST_IOS_RUNNER(RunnerUITests) + ``` + + Add the newly created target to `ios/Podfile` by embedding in the existing + `Runner` target. + + ```ruby title="ios/Podfile" + target 'Runner' do + # Do not change existing lines. + ... + + target 'RunnerUITests' do + inherit! :complete + end + end + ``` + + 6. Create an empty file `integration_test/example_test.dart` in the root of your Flutter project. From the command line, run + the following command and make sure it completes with no errors: + + ``` + $ flutter build ios --config-only integration_test/example_test.dart + ``` + + 7. Go to your `ios` directory and run: + + ``` + $ pod install --repo-update + ``` + + 8. Open your Xcode project and Make sure that for each build configuration, + the `RunnerUITests` have the same Configuration Set selected as the `Runner`: + + ![Xcode config setup](/assets/ios_runner_configs.png) + + 9. Go to **RunnerUITests** -> **Build Phases** and add 2 new "Run Script Phase" Build Phases. + Name them `xcode_backend build` and `xcode_backend embed_and_thin`. + + ![Xcode config setup](/assets/ios_runner_build_phases_create.png) + + 10. Arrange the newly created Build Phases in the order shown in the screenshot below. + + ![Xcode config setup](/assets/ios_runner_build_phases.png) + + 11. Paste this code into the `xcode_backend build` Build Phase: + + ``` + /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build + ``` + + 12. Paste this code into the `xcode_backend embed_and_thin` Build Phase: + + ``` + /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed_and_thin + ``` + + 13. Xcode by default also enables a "parallel execution" setting, which + breaks Patrol. Disable it **for all schemes** (if you have more than one): + + + + 14. Go to **RunnerUITests** -> **Build Settings**, search for **User Script Sandboxing** + and make sure it's set to **No**. + + + + + + 1. Open `macos/Runner.xcworkspace` in Xcode. + + 2. Create a test target if you do not already have one via `File > New > Target...` + and select `UI Testing Bundle`. Change the `Product Name` to `RunnerUITests`. Make + sure `Target to be Tested` is set to `Runner` and language is set to `Objective-C`. + Select `Finish`. + + 3. 2 files are created: `RunnerUITests.m` and `RunnerUITestsLaunchTests.m`. + Delete `RunnerUITestsLaunchTests.m` **through Xcode**. + + 4. Make sure that the **macOS Deployment Target** of `RunnerUITests` within the + **Build Settings** section is the same as `Runner`. + The minimum supported **macOS Deployment Target** is `10.14`. + + ![Xcode macOS deployment target](/assets/macos_deployment_target.png) + + ![Xcode macOS deployment target 2](/assets/macos_deployment_target_2.png) + + 5. Replace contents of `RunnerUITests.m` file with the following: + + ```objective-c title="macos/RunnerUITests/RunnerUITests.m" + @import XCTest; + @import patrol; + @import ObjectiveC.runtime; + + PATROL_INTEGRATION_TEST_MACOS_RUNNER(RunnerUITests) + ``` + + Add the newly created target to `macos/Podfile` by embedding in the existing + `Runner` target. + + ```ruby title="macos/Podfile" + target 'Runner' do + # Do not change existing lines. + ... + + target 'RunnerUITests' do + inherit! :complete + end + end + ``` + + 6. Create an empty file `integration_test/example_test.dart` in the root of your Flutter project. From the command line, run: + + ``` + $ flutter build macos --config-only integration_test/example_test.dart + ``` + + 7. Go to your `macos` directory and run: + + ``` + $ pod install --repo-update + ``` + + 8. Go to **RunnerUITests** -> **Build Phases** and add 2 new "Run Script Phase" Build Phases. + Rename them to `xcode_backend build` and `xcode_backend embed_and_thin` by double clicking + on their names. + + ![Xcode config setup](/assets/macos_runner_build_phases_create.png) + + 9. Arrange the newly created Build Phases in the order shown in the screenshot below. + + ![Xcode config setup](/assets/macos_runner_build_phases.png) + + 10. Paste this code into the first `macos_assemble build` Build Phase: + + ``` + /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/macos_assemble.sh" build + ``` + + 11. Paste this code into the second `macos_assemble embed` Build Phase: + + ``` + /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/macos_assemble.sh" embed + ``` + + 12. Xcode by default also enables a "parallel execution" setting, which + breaks Patrol. Disable it **for all schemes** (if you have more than one): + + + + 13. Go to **RunnerUITests** -> **Build Settings**, search for **User Script Sandboxing** + and make sure it's set to **No**. + + 14. Go to **Runner** -> **Signing & Capabilities**. Make sure that in all **App Sandbox** + sections, **Incoming Connections (Server)** and **Outgoing Connections (Client)** checkboxes + are checked. + + ![Xcode entitlements setup](/assets/macos_entitlements.png) + + 15. **Copy** `DebugProfile.entitlements` and `Release.entitlements` files from `macos/Runner` + to `macos/RunnerUITests` directory. + + 16. Go to **RunnerUITests** -> **Build Settings** and set **Code Signing Entitlements** to + `RunnerUITests/DebugProfile.entitlements` for **Debug** and **Profile** configuration and to + `RunnerUITests/Release.entitlements` for **Release** configuration. + + ![Xcode RunnerUITests entitlements setup](/assets/macos_ui_entitlements.png) + + + +### Create a simple integration test + +Let's create a dummy Flutter integration test that you'll use to verify +that Patrol is correctly set up. + +Paste the following code into `integration_test/example_test.dart`: + +```dart title="integration_test/example_test.dart" +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:patrol/patrol.dart'; + +void main() { + patrolTest( + 'counter state is the same after going to home and switching apps', + ($) async { + // Replace later with your app's main widget + await $.pumpWidgetAndSettle( + MaterialApp( + home: Scaffold( + appBar: AppBar(title: const Text('app')), + backgroundColor: Colors.blue, + ), + ), + ); + + expect($('app'), findsOneWidget); + if (!Platform.isMacOS) { + await $.native.pressHome(); + } + }, + ); +} +``` + +It does only 2 things: + +- first, it finds a text `app` +- then (on mobile platforms), it exits to home screen + +It's a very simple test, but it's enough to verify that Patrol is correctly set +up. To run `integration_test/example_test.dart` on a connected Android, iOS or macOS device: + + ``` + patrol test -t integration_test/example_test.dart + ``` + + If the setup is successful, you should see a **TEST PASSED** message. + If something went wrong, please proceed to the [FAQ] section which might + contain an answer to your issue. + + + If your app is using flavors, then you can pass them like so: + + ``` + patrol test --target integration_test/example_test.dart --flavor development + ``` + + or you can specify them in `pubspec.yaml` (recommended): + + ```yaml title="pubspec.yaml" + patrol: + app_name: My App + flavor: development + android: + package_name: com.example.myapp + ios: + bundle_id: com.example.MyApp + app_name: The Awesome App + macos: + bundle_id: com.example.macos.MyApp + ``` + + + + To prevent issues during Patrol tests, please follow these guidelines: + + 1. Do not call `IntegrationTestWidgetsFlutterBinding.ensureInitialized`. + Patrol automatically initializes its own test binding. + 2. Do not modify the global `FlutterError.onError` callback. Patrol's + internals depend on it. Keep in mind that this callback can also + be modified by popular packages such as Sentry or Crashlytics. + In such cases, you can disable them for Patrol tests. + + + + If you are looking for a working example of a Flutter app with Patrol tests, + check out the [example app](https://github.com/leancodepl/patrol/tree/master/packages/patrol/example) + in the patrol repository. + + +### FAQ + + + The reason is probably a mismatch of `patrol` and `patrol_cli` versions. Go to [Compatibility table] + and make sure that the versions of `patrol` and `patrol_cli` you are using are compatible. + + + + To run your application within the patrol test, you need to call `$.pumpWidgetAndSettle()`, + and pass your application's main widget to it. Be sure that you registered all the + necessary services before calling `$.pumpWidgetAndSettle()`. + Here's the example of running an app within the patrol test: + ```dart + + void main() { + patrolTest('real app test', ($) async { + + // Do all the necessary setup here (DI, services, etc.) + + await $.pumpWidgetAndSettle(const MyApp()); // Your's app main widget + + // Start testing your app here + + }); + } + + ``` + It's a good practice to create a setup wrapper function for your tests, so you don't have to + repeat the same code in every test. Look at the [example](https://github.com/leancodepl/patrol/blob/d2c7493f9399a028e39cb94fd204affdb932c5fc/dev/e2e_app/integration_test/common.dart#L17-L33) + of a wrapper function. + + + +#### Android + + + Go to `android/app/build.gradle` and look for `applicationId` in `defaultConfig` section. + + + + It's most likely caused by using incompatible JDK version. + Run `javac -version` to check your JDK version. Patrol officially works on JDK 17, + so unexpected errors may occur on other versions. + If you have AndroidStudio or Intellij IDEA installed, you can find the path to JDK by + opening your project's android directory in AS/Intellij and going to + **Settings** -> **Build, Execution, Deployment** -> **Build Tools** -> **Gradle** -> **Gradle JDK**. + [Learn more](https://developer.android.com/build/jdks) + + + +#### iOS + + + For iOS go to `ios/Runner.xcodeproj/project.pbxproj` and look for `PRODUCT_BUNDLE_IDENTIFIER`. + For macOS go to `macos/Runner.xcodeproj/project.pbxproj` and look for `PRODUCT_BUNDLE_IDENTIFIER`. + + + + Make sure that you disabled "Paralell execution" for **all schemes** in Xcode. + See [this video](https://www.youtube.com/watch?v=9LdEJR59fW4) for details. + + + + Search for a `FLUTTER_TARGET` in your project files and remove it (both value and key) + from *.xcconfig and *.pbxproj files. + + + + Search for a `FLUTTER_TARGET` in your project files and remove it (both value and key) + from *.xcconfig and *.pbxproj files. + + + + Check if this line in `Podfile` is present and uncommented. + ``` + platform :ios, '11.0' + ``` + If yes, then check if **iOS deployment version** in Xcode project's **Build Settings** + section for all targets (Runner and RunnerUITests) are set to the same value as in Podfile + (in case presented in snippet above, all should be set to 11.0). + + +If you couldn't find an answer to your question/problem, feel free to ask on +[Patrol Discord Server](https://discord.gg/ukBK5t4EZg). + +### Going from here + +To learn how to write Patrol tests, see [finders] and [native automation] sections. + +[native automation]: /native/usage +[finders]: /patrol/finders/usage +[Using Patrol finders in widget tests]: /patrol/finders/finders-setup +[Here's why]: /native/advanced#embrace-the-native-tests +[Patrol CLI]: https://pub.dev/packages/patrol_cli +[FAQ]: /getting-started#faq +[Compatibility table]: /compatibility-table From e11854689d57305d74d1786e633ae549e1b4a687 Mon Sep 17 00:00:00 2001 From: piotruela Date: Fri, 29 Nov 2024 15:59:00 +0100 Subject: [PATCH 3/4] Detect Orchestrator version and warn about 1.5.0 --- docs/compatibility-table.mdx | 25 ++++++++++++++ packages/patrol/CHANGELOG.md | 4 +++ packages/patrol/example/pubspec.yaml | 2 ++ packages/patrol/pubspec.yaml | 2 +- packages/patrol_cli/CHANGELOG.md | 3 +- .../lib/src/android/android_test_backend.dart | 33 +++++++++++++++++++ .../patrol_cli/lib/src/base/constants.dart | 2 +- .../compatibility_checker.dart | 10 +++++- .../lib/src/crossplatform/app_options.dart | 14 ++++++++ packages/patrol_cli/pubspec.yaml | 2 +- 10 files changed, 92 insertions(+), 5 deletions(-) diff --git a/docs/compatibility-table.mdx b/docs/compatibility-table.mdx index b48121033..8d27da378 100644 --- a/docs/compatibility-table.mdx +++ b/docs/compatibility-table.mdx @@ -1,3 +1,28 @@ --- redirect: /documentation/compatibility-table --- + +# Compatibility table + +The following table describes which versions of `patrol` +and `patrol_cli` are compatible with each other. +The simplest way to ensure that both packages are compatible +is by always using the latest version. However, +if for some reason that isn't possible, you can refer to +the table below to assess which version you should use. + +| patrol_cli | patrol | Min Flutter Version | +| -------------- | -------------- | ------------------- | +| 3.4.1+ | 3.13.1+ | 3.24.0 | +| 3.4.0 | 3.13.0 | 3.24.0 | +| 3.3.0 | 3.12.0 | 3.24.0 | +| 3.2.1 | 3.11.2 | 3.24.0 | +| 3.2.0 | 3.11.0 - 3.11.1| 3.22.0 | +| 3.1.0 - 3.1.1 | 3.10.0 | 3.22.0 | +| 2.6.5 - 3.0.1 | 3.6.0 - 3.10.0 | 3.16.0 | +| 2.6.0 - 2.6.4 | 3.4.0 - 3.5.2 | 3.16.0 | +| 2.3.0 - 2.5.0 | 3.0.0 - 3.3.0 | 3.16.0 | +| 2.2.0 - 2.2.2 | 2.3.0 - 2.3.2 | 3.3.0 | +| 2.0.1 - 2.1.5 | 2.0.1 - 2.2.5 | 3.3.0 | +| 2.0.0 | 2.0.0 | 3.3.0 | +| 1.1.4 - 1.1.11 | 1.0.9 - 1.1.11 | 3.3.0 | diff --git a/packages/patrol/CHANGELOG.md b/packages/patrol/CHANGELOG.md index f69a43b08..c1da30793 100644 --- a/packages/patrol/CHANGELOG.md +++ b/packages/patrol/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.13.1 + +- Remove whitespace replacement on Android test name. (#2437) + ## 3.13.0 - Add support for the `patrol_log` package. (#2387) diff --git a/packages/patrol/example/pubspec.yaml b/packages/patrol/example/pubspec.yaml index 45da527da..63a20bb94 100644 --- a/packages/patrol/example/pubspec.yaml +++ b/packages/patrol/example/pubspec.yaml @@ -34,6 +34,8 @@ dev_dependencies: leancode_lint: ^14.2.0 patrol: path: .. + patrol_cli: + path: ../../patrol_cli flutter_launcher_icons: android: 'launcher_icon' diff --git a/packages/patrol/pubspec.yaml b/packages/patrol/pubspec.yaml index 54d482893..ed584f3a0 100644 --- a/packages/patrol/pubspec.yaml +++ b/packages/patrol/pubspec.yaml @@ -2,7 +2,7 @@ name: patrol description: > Powerful Flutter-native UI testing framework overcoming limitations of existing Flutter testing tools. Ready for action! -version: 3.13.0 +version: 3.13.1 homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol/tree/master/packages/patrol issue_tracker: https://github.com/leancodepl/patrol/issues diff --git a/packages/patrol_cli/CHANGELOG.md b/packages/patrol_cli/CHANGELOG.md index 8072712a5..3fa63465d 100644 --- a/packages/patrol_cli/CHANGELOG.md +++ b/packages/patrol_cli/CHANGELOG.md @@ -1,6 +1,7 @@ -## Unreleased +## 3.4.1 - Add android product flavor to dart-define. (#2425) +- Detect and warn about Orchestrator 1.5.0. (#2437) ## 3.4.0 diff --git a/packages/patrol_cli/lib/src/android/android_test_backend.dart b/packages/patrol_cli/lib/src/android/android_test_backend.dart index 99b0992f7..008732cdc 100644 --- a/packages/patrol_cli/lib/src/android/android_test_backend.dart +++ b/packages/patrol_cli/lib/src/android/android_test_backend.dart @@ -46,6 +46,7 @@ class AndroidTestBackend { Future build(AndroidAppOptions options) async { await buildApkConfigOnly(options.flutter.command); await loadJavaPathFromFlutterDoctor(options.flutter.command); + await detectOrchestratorVersion(options); await _disposeScope.run((scope) async { final subject = options.description; @@ -179,6 +180,38 @@ class AndroidTestBackend { ); } + /// Detects the orchestrator version and warns the user if it's 1.5.0. + /// Related to this regression: https://github.com/android/android-test/issues/2255 + Future detectOrchestratorVersion( + AndroidAppOptions options, + ) async { + await _disposeScope.run((scope) async { + Process process; + + process = await _processManager.start( + options.toGradleAppDependencies(isWindows: _platform.isWindows), + runInShell: true, + workingDirectory: _rootDirectory.childDirectory('android').path, + environment: switch (javaPath) { + final javaPath? => {'JAVA_HOME': javaPath}, + _ => {}, + }, + ) + ..disposedBy(scope); + process.listenStdOut((l) { + if (l.contains('androidx.test:orchestrator:1.5.0')) { + _logger.warn( + 'Orchestrator version 1.5.0 detected\n' + 'Orchestrator 1.5.0 does not support whitespace in the test name.\n' + 'Please update the orchestrator version to 1.5.1 or higher.\n', + ); + } + }).disposedBy(scope); + + await process.exitCode; + }); + } + /// Executes the tests of the given [options] on the given [device]. /// /// [build] must be called before this method. diff --git a/packages/patrol_cli/lib/src/base/constants.dart b/packages/patrol_cli/lib/src/base/constants.dart index d7fcb8c78..173085a39 100644 --- a/packages/patrol_cli/lib/src/base/constants.dart +++ b/packages/patrol_cli/lib/src/base/constants.dart @@ -1,3 +1,3 @@ /// Version of Patrol CLI. Must be kept in sync with pubspec.yaml. /// If you update this, make sure that compatibility-table.mdx is updated (if needed) -const version = '3.4.0'; +const version = '3.4.1'; diff --git a/packages/patrol_cli/lib/src/compatibility_checker/compatibility_checker.dart b/packages/patrol_cli/lib/src/compatibility_checker/compatibility_checker.dart index 2f5e47ab4..83c80f152 100644 --- a/packages/patrol_cli/lib/src/compatibility_checker/compatibility_checker.dart +++ b/packages/patrol_cli/lib/src/compatibility_checker/compatibility_checker.dart @@ -64,7 +64,7 @@ class CompatibilityChecker { process.listenStdOut( (line) async { if (line.startsWith('- patrol ')) { - packageCompleter.complete(line.split(' ').last); + packageCompleter.maybeComplete(line.split(' ').last); } }, onDone: () { @@ -215,6 +215,10 @@ final _patrolVersionRange = [ ), VersionRange( min: Version.parse('3.13.0'), + max: Version.parse('3.13.0'), + ), + VersionRange( + min: Version.parse('3.13.1'), ), ]; @@ -265,5 +269,9 @@ final _patrolCliVersionRange = [ ), VersionRange( min: Version.parse('3.4.0'), + max: Version.parse('3.4.0'), + ), + VersionRange( + min: Version.parse('3.4.1'), ), ]; diff --git a/packages/patrol_cli/lib/src/crossplatform/app_options.dart b/packages/patrol_cli/lib/src/crossplatform/app_options.dart index 342ecaac7..d822532c8 100644 --- a/packages/patrol_cli/lib/src/crossplatform/app_options.dart +++ b/packages/patrol_cli/lib/src/crossplatform/app_options.dart @@ -86,6 +86,20 @@ class AndroidAppOptions { ); } + List toGradleAppDependencies({required bool isWindows}) { + final List cmd; + if (isWindows) { + cmd = [r'.\gradlew.bat']; + } else { + cmd = ['./gradlew']; + } + + // Add Gradle task + cmd.add(':app:dependencies'); + + return cmd; + } + String get _buildMode => flutter.buildMode.androidName; String get _effectiveFlavor { diff --git a/packages/patrol_cli/pubspec.yaml b/packages/patrol_cli/pubspec.yaml index 8cfc211e5..4d88bd5b4 100644 --- a/packages/patrol_cli/pubspec.yaml +++ b/packages/patrol_cli/pubspec.yaml @@ -1,7 +1,7 @@ name: patrol_cli description: > Command-line tool for Patrol, a powerful Flutter-native UI testing framework. -version: 3.4.0 # Must be kept in sync with constants.dart +version: 3.4.1 # Must be kept in sync with constants.dart homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol/tree/master/packages/patrol_cli issue_tracker: https://github.com/leancodepl/patrol/issues?q=is%3Aopen+is%3Aissue+label%3A%22package%3A+patrol_cli%22 From 0696e82f4408f6f6a0b09f15133f5eba1ea83ed9 Mon Sep 17 00:00:00 2001 From: piotruela Date: Fri, 6 Dec 2024 14:35:34 +0100 Subject: [PATCH 4/4] Adjust to docs changes --- docs/compatibility-table.mdx | 28 - docs/documentation/compatibility-table.mdx | 3 +- docs/documentation/index.mdx | 2 +- docs/getting-started.mdx | 588 --------------------- 4 files changed, 3 insertions(+), 618 deletions(-) delete mode 100644 docs/compatibility-table.mdx delete mode 100644 docs/getting-started.mdx diff --git a/docs/compatibility-table.mdx b/docs/compatibility-table.mdx deleted file mode 100644 index 8d27da378..000000000 --- a/docs/compatibility-table.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -redirect: /documentation/compatibility-table ---- - -# Compatibility table - -The following table describes which versions of `patrol` -and `patrol_cli` are compatible with each other. -The simplest way to ensure that both packages are compatible -is by always using the latest version. However, -if for some reason that isn't possible, you can refer to -the table below to assess which version you should use. - -| patrol_cli | patrol | Min Flutter Version | -| -------------- | -------------- | ------------------- | -| 3.4.1+ | 3.13.1+ | 3.24.0 | -| 3.4.0 | 3.13.0 | 3.24.0 | -| 3.3.0 | 3.12.0 | 3.24.0 | -| 3.2.1 | 3.11.2 | 3.24.0 | -| 3.2.0 | 3.11.0 - 3.11.1| 3.22.0 | -| 3.1.0 - 3.1.1 | 3.10.0 | 3.22.0 | -| 2.6.5 - 3.0.1 | 3.6.0 - 3.10.0 | 3.16.0 | -| 2.6.0 - 2.6.4 | 3.4.0 - 3.5.2 | 3.16.0 | -| 2.3.0 - 2.5.0 | 3.0.0 - 3.3.0 | 3.16.0 | -| 2.2.0 - 2.2.2 | 2.3.0 - 2.3.2 | 3.3.0 | -| 2.0.1 - 2.1.5 | 2.0.1 - 2.2.5 | 3.3.0 | -| 2.0.0 | 2.0.0 | 3.3.0 | -| 1.1.4 - 1.1.11 | 1.0.9 - 1.1.11 | 3.3.0 | diff --git a/docs/documentation/compatibility-table.mdx b/docs/documentation/compatibility-table.mdx index 8786655a4..47595f1d7 100644 --- a/docs/documentation/compatibility-table.mdx +++ b/docs/documentation/compatibility-table.mdx @@ -11,7 +11,8 @@ the table below to assess which version you should use. | patrol_cli | patrol | Min Flutter Version | | -------------- | -------------- | ------------------- | -| 3.4.0+ | 3.13.0+ | 3.24.0 | +| 3.4.1+ | 3.13.1+ | 3.24.0 | +| 3.4.0 | 3.13.0 | 3.24.0 | | 3.3.0 | 3.12.0 | 3.24.0 | | 3.2.1 | 3.11.2 | 3.24.0 | | 3.2.0 | 3.11.0 - 3.11.1| 3.22.0 | diff --git a/docs/documentation/index.mdx b/docs/documentation/index.mdx index 895f163ca..1bc11253c 100644 --- a/docs/documentation/index.mdx +++ b/docs/documentation/index.mdx @@ -182,7 +182,7 @@ Check out our video version of this tutorial on YouTube! Add this line to `dependencies` section: ```groovy title="android/app/build.gradle" - androidTestUtil "androidx.test:orchestrator:1.4.2" + androidTestUtil "androidx.test:orchestrator:1.5.1" ``` diff --git a/docs/getting-started.mdx b/docs/getting-started.mdx deleted file mode 100644 index 390a477e9..000000000 --- a/docs/getting-started.mdx +++ /dev/null @@ -1,588 +0,0 @@ ---- -redirect: /documentation ---- - -# Getting started - -Check out our video version of this tutorial on YouTube! - - - - - If you want to use Patrol finders in your existing widget or golden - tests, go to [Using Patrol finders in widget tests]. - - - - In this tutorial, we are using example app, which has package name - `com.example.myapp` on Android, bundle id `com.example.MyApp` on iOS, - `com.example.macos.MyApp` on macOS and `My App` name on all platforms. - Replace any occurences of those names with proper values. - - - - Support for macOS is in alpha stage. Please be aware that some features - may not work as expected. There is also no native automation support - for macOS yet. If you encounter any issues, please report them on - GitHub. - - -### Add dependency on `patrol` - -If you haven't already, add a dependency on the `patrol` package in the -`dev_dependencies` section of `pubspec.yaml`. `patrol` package requires -Android SDK version 21 or higher. - -``` -flutter pub add patrol --dev -``` - -### Configure Patrol in `pubspec.yaml` - -Create `patrol` section in your `pubspec.yaml`: - -```yaml title="pubspec.yaml" -dependencies: - # ... - -dev_dependencies: - # ... - -patrol: - app_name: My App - android: - package_name: com.example.myapp - ios: - bundle_id: com.example.MyApp - macos: - bundle_id: com.example.macos.MyApp -``` - -If you don't know where to get `package_name` and `bundle_id` from, see the [FAQ] section. - -### Install `patrol_cli` - -[Patrol CLI] (command-line interface) is a small program that enables running -Patrol UI tests. It is necessary to run UI tests (`flutter test` won't work! [Here's why]). - -1. Install `patrol_cli` executable: - - ``` - dart pub global activate patrol_cli - ``` - - - Make sure to add `patrol` to your `PATH` environment variable. - It's explained how to do it in the [README](https://pub.dev/packages/patrol_cli#installation). - - -2. Verify that installation was successful and your environment is set up properly: - - ``` - patrol doctor - ``` - Example output: - ``` - Patrol CLI version: 2.3.1+1 - Android: - • Program adb found in /Users/username/Library/Android/sdk/platform-tools/adb - • Env var $ANDROID_HOME set to /Users/username/Library/Android/sdk - iOS / macOS: - • Program xcodebuild found in /usr/bin/xcodebuild - • Program ideviceinstaller found in /opt/homebrew/bin/ideviceinstaller - ``` - Be sure that for the platform you want to run the test on, all the checks are green. - -Patrol CLI invokes the Flutter CLI for certain commands. To override the command used, -pass the `--flutter-command` argument or set the `PATROL_FLUTTER_COMMAND` environment -variable. This supports FVM (by setting the value to `fvm flutter`), puro (`puro flutter`) -and potentially other version managers. - -### Integrate with native side - -The 3 first steps were common across platforms. The rest is platform-specific. - -Psst... Android is a bit easier to set up, so we recommend starting with it! - - - - 1. Go to **android/app/src/androidTest/java/com/example/myapp/** in your project - directory. If there are no such folders, create them. **Remember to replace - `/com/example/myapp/` with the path created by your app's package name.** - - 2. Create a file named `MainActivityTest.java` and copy there the code below. - - ```java title="MainActivityTest.java" - package com.example.myapp; // replace "com.example.myapp" with your app's package - - import androidx.test.platform.app.InstrumentationRegistry; - import org.junit.Test; - import org.junit.runner.RunWith; - import org.junit.runners.Parameterized; - import org.junit.runners.Parameterized.Parameters; - import pl.leancode.patrol.PatrolJUnitRunner; - - @RunWith(Parameterized.class) - public class MainActivityTest { - @Parameters(name = "{0}") - public static Object[] testCases() { - PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation(); - // replace "MainActivity.class" with "io.flutter.embedding.android.FlutterActivity.class" - // if in AndroidManifest.xml in manifest/application/activity you have - // android:name="io.flutter.embedding.android.FlutterActivity" - instrumentation.setUp(MainActivity.class); - instrumentation.waitForPatrolAppService(); - return instrumentation.listDartTests(); - } - - public MainActivityTest(String dartTestName) { - this.dartTestName = dartTestName; - } - - private final String dartTestName; - - @Test - public void runDartTest() { - PatrolJUnitRunner instrumentation = (PatrolJUnitRunner) InstrumentationRegistry.getInstrumentation(); - instrumentation.runDartTest(dartTestName); - } - } - ``` - - 3. Go to the **build.gradle** file, located in **android/app** folder in your - project directory. - - 4. Add these 2 lines to the `defaultConfig` section: - - ```groovy - testInstrumentationRunner "pl.leancode.patrol.PatrolJUnitRunner" - testInstrumentationRunnerArguments clearPackageData: "true" - ``` - - 5. Add this section to the `android` section: - - ```groovy - testOptions { - execution "ANDROIDX_TEST_ORCHESTRATOR" - } - ``` - - 6. Add this line to `dependencies` section: - - ```groovy - androidTestUtil "androidx.test:orchestrator:1.5.1" - ``` - - - Bear in mind that ProGuard can lead to some problems if not well configured, potentially causing issues such as `ClassNotFoundException`s. - Keep all the Patrol packages or disable ProGuard in `android/app/build.gradle`: - ```groovy - ... - buildTypes { - release { - ... - } - debug { - minifyEnabled false - shrinkResources false - } - } - ``` - - - - - - - 1. Open `ios/Runner.xcworkspace` in Xcode. - - 2. Create a test target if you do not already have one (see the screenshot below - for the reference). Select `File > New > Target...` and select `UI Testing Bundle`. - Change the `Product Name` to `RunnerUITests`. Set the `Organization Identifier` - to be the same as for the `Runner` (no matter if you app has flavors or not). - For our example app, it's `com.example.MyApp` just as in the `pubspec.yaml` file. - Make sure `Target to be Tested` is set to `Runner` and language is set to `Objective-C`. - Select `Finish`. - - ![Xcode iOS test target](/assets/ios_test_target.png) - - 3. 2 files are created: `RunnerUITests.m` and `RunnerUITestsLaunchTests.m`. - Delete `RunnerUITestsLaunchTests.m` **through Xcode** by clicking on it and - selecting `Move to Trash`. - - 4. Make sure that the **iOS Deployment Target** of `RunnerUITests` within the - **Build Settings** section is the same as `Runner`. - The minimum supported **iOS Deployment Target** is `11.0`. For the - [example app](https://github.com/leancodepl/patrol/tree/master/packages/patrol/example), - we set it to `13.0` because it's required by the app dependencies. - - ![Xcode iOS deployment target](/assets/ios_deployment_target.png) - - ![Xcode iOS deployment target 2](/assets/ios_deployment_target_2.png) - - 5. Replace contents of `RunnerUITests.m` file with the following: - - ```objective-c title="ios/RunnerUITests/RunnerUITests.m" - @import XCTest; - @import patrol; - @import ObjectiveC.runtime; - - PATROL_INTEGRATION_TEST_IOS_RUNNER(RunnerUITests) - ``` - - Add the newly created target to `ios/Podfile` by embedding in the existing - `Runner` target. - - ```ruby title="ios/Podfile" - target 'Runner' do - # Do not change existing lines. - ... - - target 'RunnerUITests' do - inherit! :complete - end - end - ``` - - 6. Create an empty file `integration_test/example_test.dart` in the root of your Flutter project. From the command line, run - the following command and make sure it completes with no errors: - - ``` - $ flutter build ios --config-only integration_test/example_test.dart - ``` - - 7. Go to your `ios` directory and run: - - ``` - $ pod install --repo-update - ``` - - 8. Open your Xcode project and Make sure that for each build configuration, - the `RunnerUITests` have the same Configuration Set selected as the `Runner`: - - ![Xcode config setup](/assets/ios_runner_configs.png) - - 9. Go to **RunnerUITests** -> **Build Phases** and add 2 new "Run Script Phase" Build Phases. - Name them `xcode_backend build` and `xcode_backend embed_and_thin`. - - ![Xcode config setup](/assets/ios_runner_build_phases_create.png) - - 10. Arrange the newly created Build Phases in the order shown in the screenshot below. - - ![Xcode config setup](/assets/ios_runner_build_phases.png) - - 11. Paste this code into the `xcode_backend build` Build Phase: - - ``` - /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build - ``` - - 12. Paste this code into the `xcode_backend embed_and_thin` Build Phase: - - ``` - /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed_and_thin - ``` - - 13. Xcode by default also enables a "parallel execution" setting, which - breaks Patrol. Disable it **for all schemes** (if you have more than one): - - - - 14. Go to **RunnerUITests** -> **Build Settings**, search for **User Script Sandboxing** - and make sure it's set to **No**. - - - - - - 1. Open `macos/Runner.xcworkspace` in Xcode. - - 2. Create a test target if you do not already have one via `File > New > Target...` - and select `UI Testing Bundle`. Change the `Product Name` to `RunnerUITests`. Make - sure `Target to be Tested` is set to `Runner` and language is set to `Objective-C`. - Select `Finish`. - - 3. 2 files are created: `RunnerUITests.m` and `RunnerUITestsLaunchTests.m`. - Delete `RunnerUITestsLaunchTests.m` **through Xcode**. - - 4. Make sure that the **macOS Deployment Target** of `RunnerUITests` within the - **Build Settings** section is the same as `Runner`. - The minimum supported **macOS Deployment Target** is `10.14`. - - ![Xcode macOS deployment target](/assets/macos_deployment_target.png) - - ![Xcode macOS deployment target 2](/assets/macos_deployment_target_2.png) - - 5. Replace contents of `RunnerUITests.m` file with the following: - - ```objective-c title="macos/RunnerUITests/RunnerUITests.m" - @import XCTest; - @import patrol; - @import ObjectiveC.runtime; - - PATROL_INTEGRATION_TEST_MACOS_RUNNER(RunnerUITests) - ``` - - Add the newly created target to `macos/Podfile` by embedding in the existing - `Runner` target. - - ```ruby title="macos/Podfile" - target 'Runner' do - # Do not change existing lines. - ... - - target 'RunnerUITests' do - inherit! :complete - end - end - ``` - - 6. Create an empty file `integration_test/example_test.dart` in the root of your Flutter project. From the command line, run: - - ``` - $ flutter build macos --config-only integration_test/example_test.dart - ``` - - 7. Go to your `macos` directory and run: - - ``` - $ pod install --repo-update - ``` - - 8. Go to **RunnerUITests** -> **Build Phases** and add 2 new "Run Script Phase" Build Phases. - Rename them to `xcode_backend build` and `xcode_backend embed_and_thin` by double clicking - on their names. - - ![Xcode config setup](/assets/macos_runner_build_phases_create.png) - - 9. Arrange the newly created Build Phases in the order shown in the screenshot below. - - ![Xcode config setup](/assets/macos_runner_build_phases.png) - - 10. Paste this code into the first `macos_assemble build` Build Phase: - - ``` - /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/macos_assemble.sh" build - ``` - - 11. Paste this code into the second `macos_assemble embed` Build Phase: - - ``` - /bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/macos_assemble.sh" embed - ``` - - 12. Xcode by default also enables a "parallel execution" setting, which - breaks Patrol. Disable it **for all schemes** (if you have more than one): - - - - 13. Go to **RunnerUITests** -> **Build Settings**, search for **User Script Sandboxing** - and make sure it's set to **No**. - - 14. Go to **Runner** -> **Signing & Capabilities**. Make sure that in all **App Sandbox** - sections, **Incoming Connections (Server)** and **Outgoing Connections (Client)** checkboxes - are checked. - - ![Xcode entitlements setup](/assets/macos_entitlements.png) - - 15. **Copy** `DebugProfile.entitlements` and `Release.entitlements` files from `macos/Runner` - to `macos/RunnerUITests` directory. - - 16. Go to **RunnerUITests** -> **Build Settings** and set **Code Signing Entitlements** to - `RunnerUITests/DebugProfile.entitlements` for **Debug** and **Profile** configuration and to - `RunnerUITests/Release.entitlements` for **Release** configuration. - - ![Xcode RunnerUITests entitlements setup](/assets/macos_ui_entitlements.png) - - - -### Create a simple integration test - -Let's create a dummy Flutter integration test that you'll use to verify -that Patrol is correctly set up. - -Paste the following code into `integration_test/example_test.dart`: - -```dart title="integration_test/example_test.dart" -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:patrol/patrol.dart'; - -void main() { - patrolTest( - 'counter state is the same after going to home and switching apps', - ($) async { - // Replace later with your app's main widget - await $.pumpWidgetAndSettle( - MaterialApp( - home: Scaffold( - appBar: AppBar(title: const Text('app')), - backgroundColor: Colors.blue, - ), - ), - ); - - expect($('app'), findsOneWidget); - if (!Platform.isMacOS) { - await $.native.pressHome(); - } - }, - ); -} -``` - -It does only 2 things: - -- first, it finds a text `app` -- then (on mobile platforms), it exits to home screen - -It's a very simple test, but it's enough to verify that Patrol is correctly set -up. To run `integration_test/example_test.dart` on a connected Android, iOS or macOS device: - - ``` - patrol test -t integration_test/example_test.dart - ``` - - If the setup is successful, you should see a **TEST PASSED** message. - If something went wrong, please proceed to the [FAQ] section which might - contain an answer to your issue. - - - If your app is using flavors, then you can pass them like so: - - ``` - patrol test --target integration_test/example_test.dart --flavor development - ``` - - or you can specify them in `pubspec.yaml` (recommended): - - ```yaml title="pubspec.yaml" - patrol: - app_name: My App - flavor: development - android: - package_name: com.example.myapp - ios: - bundle_id: com.example.MyApp - app_name: The Awesome App - macos: - bundle_id: com.example.macos.MyApp - ``` - - - - To prevent issues during Patrol tests, please follow these guidelines: - - 1. Do not call `IntegrationTestWidgetsFlutterBinding.ensureInitialized`. - Patrol automatically initializes its own test binding. - 2. Do not modify the global `FlutterError.onError` callback. Patrol's - internals depend on it. Keep in mind that this callback can also - be modified by popular packages such as Sentry or Crashlytics. - In such cases, you can disable them for Patrol tests. - - - - If you are looking for a working example of a Flutter app with Patrol tests, - check out the [example app](https://github.com/leancodepl/patrol/tree/master/packages/patrol/example) - in the patrol repository. - - -### FAQ - - - The reason is probably a mismatch of `patrol` and `patrol_cli` versions. Go to [Compatibility table] - and make sure that the versions of `patrol` and `patrol_cli` you are using are compatible. - - - - To run your application within the patrol test, you need to call `$.pumpWidgetAndSettle()`, - and pass your application's main widget to it. Be sure that you registered all the - necessary services before calling `$.pumpWidgetAndSettle()`. - Here's the example of running an app within the patrol test: - ```dart - - void main() { - patrolTest('real app test', ($) async { - - // Do all the necessary setup here (DI, services, etc.) - - await $.pumpWidgetAndSettle(const MyApp()); // Your's app main widget - - // Start testing your app here - - }); - } - - ``` - It's a good practice to create a setup wrapper function for your tests, so you don't have to - repeat the same code in every test. Look at the [example](https://github.com/leancodepl/patrol/blob/d2c7493f9399a028e39cb94fd204affdb932c5fc/dev/e2e_app/integration_test/common.dart#L17-L33) - of a wrapper function. - - - -#### Android - - - Go to `android/app/build.gradle` and look for `applicationId` in `defaultConfig` section. - - - - It's most likely caused by using incompatible JDK version. - Run `javac -version` to check your JDK version. Patrol officially works on JDK 17, - so unexpected errors may occur on other versions. - If you have AndroidStudio or Intellij IDEA installed, you can find the path to JDK by - opening your project's android directory in AS/Intellij and going to - **Settings** -> **Build, Execution, Deployment** -> **Build Tools** -> **Gradle** -> **Gradle JDK**. - [Learn more](https://developer.android.com/build/jdks) - - - -#### iOS - - - For iOS go to `ios/Runner.xcodeproj/project.pbxproj` and look for `PRODUCT_BUNDLE_IDENTIFIER`. - For macOS go to `macos/Runner.xcodeproj/project.pbxproj` and look for `PRODUCT_BUNDLE_IDENTIFIER`. - - - - Make sure that you disabled "Paralell execution" for **all schemes** in Xcode. - See [this video](https://www.youtube.com/watch?v=9LdEJR59fW4) for details. - - - - Search for a `FLUTTER_TARGET` in your project files and remove it (both value and key) - from *.xcconfig and *.pbxproj files. - - - - Search for a `FLUTTER_TARGET` in your project files and remove it (both value and key) - from *.xcconfig and *.pbxproj files. - - - - Check if this line in `Podfile` is present and uncommented. - ``` - platform :ios, '11.0' - ``` - If yes, then check if **iOS deployment version** in Xcode project's **Build Settings** - section for all targets (Runner and RunnerUITests) are set to the same value as in Podfile - (in case presented in snippet above, all should be set to 11.0). - - -If you couldn't find an answer to your question/problem, feel free to ask on -[Patrol Discord Server](https://discord.gg/ukBK5t4EZg). - -### Going from here - -To learn how to write Patrol tests, see [finders] and [native automation] sections. - -[native automation]: /native/usage -[finders]: /patrol/finders/usage -[Using Patrol finders in widget tests]: /patrol/finders/finders-setup -[Here's why]: /native/advanced#embrace-the-native-tests -[Patrol CLI]: https://pub.dev/packages/patrol_cli -[FAQ]: /getting-started#faq -[Compatibility table]: /compatibility-table