Appium Flutter Integration Driver Testing on Sauce Labs
Sauce Labs supports testing Flutter apps on Android and iOS real devices with Appium by utilizing the appium-flutter-integration-driver. The process to test Flutter apps with Appium involves an additional and crucial step: Prepare the app with Flutter Integration Server. This step includes instructions on how to prepare and build your app for both Android and iOS platforms. After preparing your app, you can upload it to Sauce Labs, Configure your Appium capabilities, and run your tests.
Native Flutter Integration Driver vs Appium Flutter Integration Driver
Use Cases | Native Flutter Driver | Appium Flutter Integration Driver |
---|---|---|
Writing tests in languages other than Dart | ❌ | ✔️ |
Running integration tests for Flutter apps with embedded webview or native view, or existing native apps with embedded Flutter view | ❌ | ✔️ |
Running tests on multiple devices simultaneously | ❌ | ✔️ |
Running integration tests on device farms that offer Appium support | ❌ | ✔️ |
App interactions beyond Flutter’s contextuality (e.g., sending an OTP from a message application) | ❌ | ✔️ |
Differences from Appium Flutter Driver
The current Appium Flutter Driver is built on top of the flutter_test
SDK, which is deprecated.
The potential deprecation (Expand deprecation policy to package:flutter_driver)
means this driver may not work with future Flutter updates. It also does not handle all cases, such as permission dialog handling.
Why Use Appium Flutter Integration Driver?
This driver is built using Flutter Integration Test.
Strong Typing & Fluent APIs: Ensures robust and easy-to-use interfaces.
Element Handling: Automatically waits for elements to attach to the DOM before interacting.
Seamless Context Switching: No need to switch between contexts, such as Flutter and native; the driver handles it effortlessly.
Auto Wait for Render Cycles: Automatically waits for frame render cycles, including animations and screen transitions.
Simplified Powerful Gestures: Supports powerful yet simplified gestures like LongPress, ScrollToElement, DragAndDrop, and DoubleClick.
Element Chaining: Allows chaining of elements, enabling you to find child elements under a specific parent easily.
What You'll Need
- Familiarity with creating, signing and building Flutter apps.
- Familiarity writing and running Appium tests.
Use Sauce Labs My Demo App Flutter
My Demo App Flutter is a mobile application developed using Flutter based on Flutter Counter example application. Modified by the Sauce Labs team, this app is designed to demonstrate the robust capabilities of Sauce Labs mobile devices cloud, with a particular focus on our integration with the Appium Flutter Integration Driver.
The apps can be found here.
- To download the demo app for Android please click here.
- To download the demo app for iOs please click here.
Prepare the app with Flutter Integration Server
-
Open your Flutter project in your favorite IDE.
-
In your Flutter app's
pubspec.yaml
, add the following dependencies:Get the latest version from
https://pub.dev/packages/appium_flutter_server/install
dev_dependencies:
appium_flutter_server: 0.0.14 -
Create a directory called
integration_test
in the root of your Flutter project. -
Create a file called
appium_test.dart
in theintegration_test
directory. -
Add the following code to the
appium_test.dart
file:import 'package:appium_flutter_server/appium_flutter_server.dart';
import 'package:appium_testing_app/main.dart';
void main() {
initializeTest(app: const MyApp());
}If you are in need to configure certain prerequists before the testing app is loaded, you can try the following code:
import 'package:appium_testing_app/main.dart'; as app;
void main() {
initializeTest(
callback: (WidgetTester tester) async {
// Perform any prerequisite steps or intialise any dependencies required by the app
// and make sure to pump the app widget using below statement.
await tester.pumpWidget(const app.MyApp());
},
);
} -
Build the Android app:
./gradlew app:assembleDebug -Ptarget=`pwd`/../integration_test/appium_test.dart
The APK file will be located in
{project-root}/build/app/outputs/flutter-apk/
-
Build the iOS app: For Simulator - Debug mode
flutter build ios integration_test/appium_test.dart --simulator
The app will be located in
{project-root}/build/ios/iphonesimulator/
For Real Device - Release mode
flutter build ipa --release integration_test/appium_test.dart
The IPA file will be located in
{project-root}/build/ios/ipa/
Bingo! You are ready to run your tests using Appium Flutter Integration Driver.
Uploading your Flutter App to Sauce Labs
You can now upload the built apps with our REST API, or manually upload them to the preferred Data Center. See Manually Uploading an App for more information.
Configuring your Appium Capabilities
More information on how to write Appium tests for Flutter apps can be found in the appium-flutter-integration-driver repository. You can also find a sample Flutter app and tests in the Demo JS - Appium Flutter Integration-repository.
appium-flutter-integration-driver. This driver will now be included by default with Appium version latest and all subsequent versions released after July 1st.
More information regarding the available appium versions we support at Sauce Sabs.
Real Devices
- Java
- WDIO
- Android
- iOS
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformName", "android");
// W3C Protocol is mandatory for Appium 2
capabilities.setCapability("appium:platformVersion", "12");
capabilities.setCapability("appium:deviceName", "Google Pixel 6");
// Mandatory for Appium 2
capabilities.setCapability("appium:automationName", "FlutterIntegration");
capabilities.setCapability("appium:app", "storage:filename=sl_my_demo_flutter_app.apk");
HashMap<String, Object> sauceOptions = new HashMap<String, Object>();
// appiumVersion is mandatory to use Appium 2 on Sauce Labs
sauceOptions.put("appiumVersion", "appium-20240701");
sauceOptions.put("username", System.getenv("SAUCE_USERNAME"));
sauceOptions.put("accessKey", System.getenv("SAUCE_ACCESS_KEY"));
capabilities.setCapability("sauce:options", sauceOptions);
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformName", "ios");
// W3C Protocol is mandatory for Appium 2
capabilities.setCapability("appium:platformVersion", "16");
capabilities.setCapability("appium:deviceName", "iPhone 14");
// Mandatory for Appium 2
capabilities.setCapability("appium:automationName", "FlutterIntegration");
capabilities.setCapability("appium:app", "storage:filename=sl_my_demo_flutter_app.ipa");
HashMap<String, Object> sauceOptions = new HashMap<String, Object>();
// appiumVersion is mandatory to use Appium 2 on Sauce Labs
sauceOptions.put("appiumVersion", "appium-20240701");
sauceOptions.put("username", System.getenv("SAUCE_USERNAME"));
sauceOptions.put("accessKey", System.getenv("SAUCE_ACCESS_KEY"));
capabilities.setCapability("sauce:options", sauceOptions);
- Android
- iOS
const capabilities = {
platformName: 'android',
// W3C Protocol is mandatory for Appium 2
'appium:platformVersion': '12',
'appium:deviceName': 'Google Pixel 6',
// Mandatory for Appium 2
'appium:automationName': 'FlutterIntegration',
'appium:app': 'storage:filename=sl_my_demo_flutter_app.apk',
'sauce:options': {
// appiumVersion is mandatory to use Appium 2 on Sauce Labs
appiumVersion: 'appium-20240701'
}
}
const capabilities = {
platformName: 'ios',
// W3C Protocol is mandatory for Appium 2
'appium:platformVersion': '16',
'appium:deviceName': 'iPhone 14',
// Mandatory for Appium 2
'appium:automationName': 'FlutterIntegration',
'appium:app': 'storage:filename=sl_my_demo_flutter_app.ipa',
'sauce:options': {
// appiumVersion is mandatory to use Appium 2 on Sauce Labs
appiumVersion: 'appium-20240701'
}
}