|
| 1 | +--- |
| 2 | +id: appium-flutter-integration-driver |
| 3 | +title: Appium Flutter Integration Driver Testing on Sauce Labs |
| 4 | +sidebar_label: Appium Flutter Integration Testing |
| 5 | +description: Learn how to test Flutter apps with the Appium Flutter Integration Driver. |
| 6 | +--- |
| 7 | + |
| 8 | +import useBaseUrl from '@docusaurus/useBaseUrl'; |
| 9 | +import Tabs from '@theme/Tabs'; |
| 10 | +import TabItem from '@theme/TabItem'; |
| 11 | + |
| 12 | +Sauce Labs supports testing Flutter apps on Android and iOS real devices with Appium by utilizing the [appium-flutter-integration-driver](https://github.com/AppiumTestDistribution/appium-flutter-integration-driver). |
| 13 | +The process to test Flutter apps with Appium involves an additional and crucial step: [Prepare the app with Flutter Integration Server](#prepare-the-app-with-flutter-integration-server). |
| 14 | +This step includes instructions on how to prepare and build your app for both Android and iOS platforms. After preparing your app, |
| 15 | +you can [upload](#uploading-your-flutter-app-to-sauce-labs) it to Sauce Labs, [Configure your Appium capabilities](#configuring-your-appium-capabilities), and run your tests. |
| 16 | + |
| 17 | + |
| 18 | +## Native Flutter Integration Driver vs Appium Flutter Integration Driver |
| 19 | + |
| 20 | +| Use Cases | Native Flutter Driver | Appium Flutter Integration Driver | |
| 21 | +| ----------------------------------------------------------------------------------------------------------------------------------- | --------------------- | --------------------------------- | |
| 22 | +| Writing tests in languages other than Dart | ❌ | ✔️ | |
| 23 | +| Running integration tests for Flutter apps with embedded webview or native view, or existing native apps with embedded Flutter view | ❌ | ✔️ | |
| 24 | +| Running tests on multiple devices simultaneously | ❌ | ✔️ | |
| 25 | +| Running integration tests on device farms that offer Appium support | ❌ | ✔️ | |
| 26 | +| App interactions beyond Flutter’s contextuality (e.g., sending an OTP from a message application) | ❌ | ✔️ | |
| 27 | + |
| 28 | +## Differences from Appium Flutter Driver |
| 29 | + |
| 30 | +The current Appium Flutter Driver is built on top of the `flutter_test` SDK, which is deprecated. |
| 31 | +The potential deprecation ([Expand deprecation policy to package:flutter_driver](https://github.com/flutter/flutter/issues/139249)) |
| 32 | +means this driver may not work with future Flutter updates. It also does not handle all cases, such as permission dialog handling. |
| 33 | + |
| 34 | +## Why Use Appium Flutter Integration Driver? |
| 35 | + |
| 36 | +This driver is built using [Flutter Integration Test](https://docs.flutter.dev/cookbook/testing/integration/introduction). |
| 37 | + |
| 38 | + ***Strong Typing & Fluent APIs:*** Ensures robust and easy-to-use interfaces. |
| 39 | + |
| 40 | + ***Element Handling***: Automatically waits for elements to attach to the DOM before interacting. |
| 41 | + |
| 42 | + ***Seamless Context Switching***: No need to switch between contexts, such as Flutter and native; the driver handles it effortlessly. |
| 43 | + |
| 44 | + ***Auto Wait for Render Cycles***: Automatically waits for frame render cycles, including animations and screen transitions. |
| 45 | + |
| 46 | + ***Simplified Powerful Gestures***: Supports powerful yet simplified gestures like LongPress, ScrollToElement, DragAndDrop, and DoubleClick. |
| 47 | + |
| 48 | + ***Element Chaining***: Allows chaining of elements, enabling you to find child elements under a specific parent easily. |
| 49 | + |
| 50 | + |
| 51 | +## What You'll Need |
| 52 | + |
| 53 | +- Familiarity with creating, signing and building [Flutter apps](https://docs.flutter.dev/). |
| 54 | +- Familiarity writing and running [Appium tests](/mobile-apps/automated-testing/appium/). |
| 55 | + |
| 56 | +## Use Sauce Labs `My Demo App Flutter` |
| 57 | + |
| 58 | +[*My Demo App Flutter*](https://github.com/saucelabs/my-demo-app-flutter) is a mobile application developed using Flutter based |
| 59 | +on [Flutter Counter example application](https://github.com/felangel/bloc/tree/master/examples/flutter_counter). |
| 60 | +Modified by the Sauce Labs team, this app is designed to demonstrate the robust capabilities of Sauce Labs |
| 61 | +mobile devices cloud, with a particular focus on our integration with the [Appium Flutter Integration Driver](https://github.com/AppiumTestDistribution/appium-flutter-integration-driver). |
| 62 | + |
| 63 | +The apps can be found [here](https://github.com/saucelabs/my-demo-app-flutter/releases/tag/v1.0.0). |
| 64 | +- To download the demo app for Android please click [here](https://github.com/saucelabs/my-demo-app-flutter/releases/download/v1.0.0/sl_my_demo_flutter_app.apk). |
| 65 | +- To download the demo app for iOs please click [here](https://github.com/saucelabs/my-demo-app-flutter/releases/download/v1.0.0/sl_my_demo_flutter_app.ipa). |
| 66 | + |
| 67 | + |
| 68 | +## Prepare the app with Flutter Integration Server |
| 69 | + |
| 70 | +1. Open your Flutter project in your favorite IDE. |
| 71 | +2. In your Flutter app's `pubspec.yaml`, add the following dependencies: |
| 72 | + |
| 73 | + Get the latest version from `https://pub.dev/packages/appium_flutter_server/install` |
| 74 | + |
| 75 | + ```yaml |
| 76 | + dev_dependencies: |
| 77 | + appium_flutter_server: 0.0.14 |
| 78 | + ``` |
| 79 | +
|
| 80 | +3. Create a directory called `integration_test` in the root of your Flutter project. |
| 81 | +4. Create a file called `appium_test.dart` in the `integration_test` directory. |
| 82 | +5. Add the following code to the `appium_test.dart` file: |
| 83 | + |
| 84 | + ```dart |
| 85 | + import 'package:appium_flutter_server/appium_flutter_server.dart'; |
| 86 | + import 'package:appium_testing_app/main.dart'; |
| 87 | +
|
| 88 | + void main() { |
| 89 | + initializeTest(app: const MyApp()); |
| 90 | + } |
| 91 | + ``` |
| 92 | + If you are in need to configure certain prerequists before the testing app is loaded, you can try the following code: |
| 93 | + ```dart |
| 94 | + import 'package:appium_testing_app/main.dart'; as app; |
| 95 | + void main() { |
| 96 | + initializeTest( |
| 97 | + callback: (WidgetTester tester) async { |
| 98 | + // Perform any prerequisite steps or intialise any dependencies required by the app |
| 99 | + // and make sure to pump the app widget using below statement. |
| 100 | + await tester.pumpWidget(const app.MyApp()); |
| 101 | + }, |
| 102 | + ); |
| 103 | + } |
| 104 | + ``` |
| 105 | + |
| 106 | +6. Build the Android app: |
| 107 | + |
| 108 | + ```bash |
| 109 | + ./gradlew app:assembleDebug -Ptarget=`pwd`/../integration_test/appium_test.dart |
| 110 | + ``` |
| 111 | + |
| 112 | + The APK file will be located in `{project-root}/build/app/outputs/flutter-apk/` |
| 113 | + |
| 114 | +7. Build the iOS app: |
| 115 | + For Simulator - Debug mode |
| 116 | + ```bash |
| 117 | + flutter build ios integration_test/appium_test.dart --simulator |
| 118 | + ``` |
| 119 | + |
| 120 | + The app will be located in `{project-root}/build/ios/iphonesimulator/` |
| 121 | + |
| 122 | + For Real Device - Release mode |
| 123 | + ```bash |
| 124 | + flutter build ipa --release integration_test/appium_test.dart |
| 125 | + ``` |
| 126 | + |
| 127 | + The IPA file will be located in `{project-root}/build/ios/ipa/` |
| 128 | + |
| 129 | +Bingo! You are ready to run your tests using Appium Flutter Integration Driver. |
| 130 | + |
| 131 | +## Uploading your Flutter App to Sauce Labs |
| 132 | + |
| 133 | +You can now upload the built apps with our [REST API](/dev/api/storage/#upload-file-to-app-storage), or manually upload them to the preferred Data Center. See [Manually Uploading an App](/mobile-apps/live-testing/live-mobile-app-testing/#uploading-an-app) for more information. |
| 134 | + |
| 135 | +## Configuring your Appium Capabilities |
| 136 | + |
| 137 | +More information on how to write Appium tests for Flutter apps can be found in the [appium-flutter-integration-driver](https://github.com/AppiumTestDistribution/appium-flutter-integration-driver) repository. You can also find a sample Flutter app and tests in the [Demo JS - Appium Flutter Integration](https://github.com/saucelabs-training/demo-js/tree/docs-1.3/webdriverio/appium-app/examples/appium-flutter-integration)-repository. |
| 138 | + |
| 139 | +:::info APPIUM FLUTTER INTEGRATION DRIVER SUPPORT : |
| 140 | +[appium-flutter-integration-driver](https://github.com/AppiumTestDistribution/appium-flutter-integration-driver). This driver will now be included by default with Appium version latest and all subsequent versions released after July 1st. |
| 141 | + |
| 142 | +More information regarding the available [appium versions](/mobile-apps/automated-testing/appium/appium-versions/#Real-Devices) we support at Sauce Sabs. |
| 143 | +::: |
| 144 | + |
| 145 | +### Real Devices |
| 146 | + |
| 147 | +<Tabs |
| 148 | +groupId="capability-ex" |
| 149 | +defaultValue="java" |
| 150 | +values={[ |
| 151 | +{label: 'Java', value: 'java'}, |
| 152 | +{label: 'WDIO', value: 'ts'}, |
| 153 | +]}> |
| 154 | + |
| 155 | +<TabItem value="java"> |
| 156 | +<Tabs groupId="capability-java" |
| 157 | +defaultValue="android" |
| 158 | +values={[ |
| 159 | +{label: 'Android', value: 'android'}, |
| 160 | +{label: 'iOS', value: 'ios'}, |
| 161 | +]}> |
| 162 | +<TabItem value="android"> |
| 163 | + |
| 164 | +<!-- prettier-ignore --> |
| 165 | +```java |
| 166 | +MutableCapabilities capabilities = new MutableCapabilities(); |
| 167 | +
|
| 168 | +capabilities.setCapability("platformName", "android"); |
| 169 | +// W3C Protocol is mandatory for Appium 2 |
| 170 | +capabilities.setCapability("appium:platformVersion", "12"); |
| 171 | +capabilities.setCapability("appium:deviceName", "Google Pixel 6"); |
| 172 | +// Mandatory for Appium 2 |
| 173 | +capabilities.setCapability("appium:automationName", "FlutterIntegration"); |
| 174 | +capabilities.setCapability("appium:app", "storage:filename=sl_my_demo_flutter_app.apk"); |
| 175 | +
|
| 176 | +HashMap<String, Object> sauceOptions = new HashMap<String, Object>(); |
| 177 | +// appiumVersion is mandatory to use Appium 2 on Sauce Labs |
| 178 | +sauceOptions.put("appiumVersion", "appium-20240701"); |
| 179 | +sauceOptions.put("username", System.getenv("SAUCE_USERNAME")); |
| 180 | +sauceOptions.put("accessKey", System.getenv("SAUCE_ACCESS_KEY")); |
| 181 | +capabilities.setCapability("sauce:options", sauceOptions); |
| 182 | +``` |
| 183 | + |
| 184 | +</TabItem> |
| 185 | +<TabItem value="ios"> |
| 186 | + |
| 187 | +<!-- prettier-ignore --> |
| 188 | +```java |
| 189 | +MutableCapabilities capabilities = new MutableCapabilities(); |
| 190 | +
|
| 191 | +capabilities.setCapability("platformName", "ios"); |
| 192 | +// W3C Protocol is mandatory for Appium 2 |
| 193 | +capabilities.setCapability("appium:platformVersion", "16"); |
| 194 | +capabilities.setCapability("appium:deviceName", "iPhone 14"); |
| 195 | +// Mandatory for Appium 2 |
| 196 | +capabilities.setCapability("appium:automationName", "FlutterIntegration"); |
| 197 | +capabilities.setCapability("appium:app", "storage:filename=sl_my_demo_flutter_app.ipa"); |
| 198 | +
|
| 199 | +HashMap<String, Object> sauceOptions = new HashMap<String, Object>(); |
| 200 | +// appiumVersion is mandatory to use Appium 2 on Sauce Labs |
| 201 | +sauceOptions.put("appiumVersion", "appium-20240701"); |
| 202 | +sauceOptions.put("username", System.getenv("SAUCE_USERNAME")); |
| 203 | +sauceOptions.put("accessKey", System.getenv("SAUCE_ACCESS_KEY")); |
| 204 | +capabilities.setCapability("sauce:options", sauceOptions); |
| 205 | +``` |
| 206 | + |
| 207 | +</TabItem> |
| 208 | +</Tabs> |
| 209 | +</TabItem> |
| 210 | +<TabItem value="ts"> |
| 211 | + |
| 212 | +<Tabs |
| 213 | +groupId="capability-js" |
| 214 | +defaultValue="android" |
| 215 | +values={[ |
| 216 | +{label: 'Android', value: 'android'}, |
| 217 | +{label: 'iOS', value: 'ios'}, |
| 218 | +]}> |
| 219 | +<TabItem value="android"> |
| 220 | + |
| 221 | +<!-- prettier-ignore --> |
| 222 | +```ts |
| 223 | +const capabilities = { |
| 224 | + platformName: 'android', |
| 225 | + // W3C Protocol is mandatory for Appium 2 |
| 226 | + 'appium:platformVersion': '12', |
| 227 | + 'appium:deviceName': 'Google Pixel 6', |
| 228 | + // Mandatory for Appium 2 |
| 229 | + 'appium:automationName': 'FlutterIntegration', |
| 230 | + 'appium:app': 'storage:filename=sl_my_demo_flutter_app.apk', |
| 231 | + 'sauce:options': { |
| 232 | + // appiumVersion is mandatory to use Appium 2 on Sauce Labs |
| 233 | + appiumVersion: 'appium-20240701' |
| 234 | + } |
| 235 | +} |
| 236 | +``` |
| 237 | + |
| 238 | +</TabItem> |
| 239 | +<TabItem value="ios"> |
| 240 | + |
| 241 | +<!-- prettier-ignore --> |
| 242 | +```ts |
| 243 | +const capabilities = { |
| 244 | + platformName: 'ios', |
| 245 | + // W3C Protocol is mandatory for Appium 2 |
| 246 | + 'appium:platformVersion': '16', |
| 247 | + 'appium:deviceName': 'iPhone 14', |
| 248 | + // Mandatory for Appium 2 |
| 249 | + 'appium:automationName': 'FlutterIntegration', |
| 250 | + 'appium:app': 'storage:filename=sl_my_demo_flutter_app.ipa', |
| 251 | + 'sauce:options': { |
| 252 | + // appiumVersion is mandatory to use Appium 2 on Sauce Labs |
| 253 | + appiumVersion: 'appium-20240701' |
| 254 | + } |
| 255 | +} |
| 256 | +``` |
| 257 | + |
| 258 | +</TabItem> |
| 259 | +</Tabs> |
| 260 | +</TabItem> |
| 261 | +</Tabs> |
0 commit comments