What is Appium Flutter Finder?
mainCommonFinders class, allowing you to locate Flutter widgets during automation sessions.repository·main·Indexed 19 days ago
https://github.com/appium/appium-flutter-driverA driver for Appium that enables automation of Flutter applications by communicating with the Dart VM via the Flutter Driver protocol. It supports switching between FLUTTER, NATIVE_APP, and WEBVIEW contexts, allowing developers to interact with Flutter widgets and native platform elements. The driver requires apps to be compiled in debug or profile mode with the flutter_driver extension enabled. It is accompanied by the Appium Flutter Finder library, providing finding utilities for Node.js, Python, Ruby, and Kotlin.
CommonFinders class, allowing you to locate Flutter widgets during automation sessions.To automate different parts of a Flutter application, you must switch between three primary contexts:
FLUTTER: Used to send flutter_driver commands to the Dart VM. This is where you interact with Flutter widgets.NATIVE_APP: Used to interact with native Android (via UiAutomator2) or iOS (via XCUITest) elements. Use this for system dialogs or native components surrounding the Flutter app.WEBVIEW_XXXX: Used for testing WebViews that are not accessible via flutter_driver.You must explicitly call driver.switchContext() to move between these targets.
// Example context switching in WebdriverIO
if (process.env.APPIUM_OS === 'android') {
await driver.switchContext('NATIVE_APP');
await (await driver.$('~fab')).click(); // Interact with native element
await driver.switchContext('FLUTTER'); // Switch back to Flutter widgets
}The Appium Flutter Driver exposes the underlying Flutter Driver API through the execute command. In most WebDriver clients, you use a command prefix (like flutter: for Android/iOS or mobile: in standard Appium) to invoke these specific Flutter capabilities.
Commands are categorized by their Scope:
Note: The examples below use webdriverio syntax. Replace driver.execute('flutter:...') with the appropriate method for your specific client (e.g., driver.execute_script in Python or driver.execute_script in Ruby).
Choosing between the Appium Flutter Driver and standard native drivers depends on your app's build and testing strategy:
debug or profile builds).semanticLabel or identifier (for Flutter 3.19+) in your Flutter code. These map to resource-id (Android) and accessibilityIdentifier (iOS).Note for Flutter 3.19+: If using native drivers, you may need to set "appium:settings[disableIdLocatorAutocompletion]": true to work with resource-id without package name prefixes on Android.
The Appium Flutter Driver manages three distinct contexts to allow interaction with different layers of the application:
FLUTTER: Sends commands directly to the Dart VM over the observatory URL. This allows for direct interaction with Flutter elements using the flutter_driver API. Note that page source is not supported in this context; use the getRenderTree command instead.NATIVE_APP: Uses the standard Appium UIAutomator2 (Android) or XCUITest (iOS) driver. This is useful for interacting with native OS elements or system dialogs.WEBVIEW: Manages WebView contents using the underlying native driver (UIAutomator2 or XCUITest).As of version 0.3.0, appium-flutter-finder is an ESM-only package. You must use import statements instead of require(). Deep imports from appium-flutter-finder/build/... are no longer supported; always import from the package root.
// Standard ESM import
import * as finder from 'appium-flutter-finder';
// Named imports
import {byText, byValueKey} from 'appium-flutter-finder';To use Appium Flutter Driver version 3.0.0 or later, you must have Appium 3 installed. You can install the driver via npm or from a local path.
Install via npm:
appium driver install --source=npm appium-flutter-driverInstall from a local path:
appium driver install --source local /path/to/appium-flutter-driver/driverTo use the Kotlin finder elements for the Appium Flutter Driver in your Android project, you can include them via JitPack. You must first configure your settings.gradle to include the JitPack repository, and then add the dependency to your build.gradle file.
Note that the package name for this project is pro.truongsinh.appium_flutter.
// settings.gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
// build.gradle
dependencies {
// Use the specific version or main-SNAPSHOT
testImplementation 'com.github.appium:appium-flutter-driver:kotlin-finder-0.0.7'
}There are four ways to launch your application and establish a Dart VM connection:
app capability)Include the app capability in your session configuration. The driver will start the app and immediately attempt to connect to the Dart VM.
activate_app)Useful if you want to start a session first and then launch the app later:
app capability.driver.install_app or mobile:installApp.driver.activate_app or mobile:activateApp.flutter:connectObservatoryWsUrl)Use this if you manage the application lifecycle yourself (e.g., via ios-go, iproxy, or tidevice):
app capability.flutter:connectObservatoryWsUrl command to continuously search for the observatory URL.flutter:launchApp)Specifically for iOS apps that do not print the observatory URL via standard methods:
app capability.flutter:launchApp to start the iOS app via the instrument service.Note: Ensure the target app process is stopped before attempting these methods.
// Example of using flutter:launchApp for iOS
driver.execute_script('flutter:launchApp', 'com.example.bundleId', {arguments: ['arg1'], environment: {ENV1: 'env'}});To run the Appium Flutter Driver automation locally for development or testing, follow these steps to set up the driver, Appium server, and example applications:
node and npm are installed.cd ./driver.npm install -g typescript.npm install.npm link.npm i -g appium.appium.apps.apps directory:android-real-debug.apkios-sim-debug.zip.apk or .ipa in the example script located at example/nodejs/src/index.js (specifically around line 13) to match your local paths.Execute the automation script using the npm start command, specifying the target operating system via the APPIUM_OS environment variable:
APPIUM_OS=android npm startAPPIUM_OS=ios npm start# Setup steps summary
cd ./driver
npm install -g typescript
npm install
npm link
npm i -g appium
# Run Appium in a separate terminal
appium
# Run the automation example
APPIUM_OS=android npm start
# OR
APPIUM_OS=ios npm startTo use the Appium Flutter Driver, your Flutter application must meet the following requirements:
debug or profile mode.flutter_driver package in its pubspec.yaml.enableFlutterDriverExtension in your main.dart file.Example pubspec.yaml configuration:
# pubspec.yaml
dev_dependencies:
flutter_driver:
sdk: flutterYou can add custom functionality to the Flutter Driver using the CommandExtension class. This requires adding specific Dart files to your project's lib folder and registering them in your app's entry point (main.dart or test_main.dart).
Available Extensions:
dragAndDropWithCommandExtension: Performs drag-and-drop via coordinates and duration.getTextWithCommandExtension: Retrieves text from widgets containing TextSpan.Implementation Steps:
.dart files (e.g., drag_commands.dart) to your lib folder.main() function to include the extensions in enableFlutterDriverExtension().Example Registration:
import 'drag_commands.dart';
import 'get_text_command.dart';
void main() {
enableFlutterDriverExtension(
commands: [DragCommandExtension(), GetTextCommandExtension()]);
runApp(const MyApp());
}