Understand how Patrol enables interaction with native Android, iOS, and web platform features from your Flutter tests
Patrol’s native automation capabilities allow you to interact with platform-specific UI elements and features that are outside the Flutter framework. This is what sets Patrol apart from standard Flutter integration tests.
At the heart of Patrol’s native automation is the $.platform object, which provides access to platform-specific automators:
$.platform.mobile - Cross-platform mobile automator (Android & iOS)
$.platform.android - Android-specific automator
$.platform.ios - iOS-specific automator
$.platform.web - Web browser automator
Use $.platform.mobile whenever possible to keep your tests cross-platform. Only use platform-specific automators when you need different behavior per platform.
Patrol’s architecture bridges the gap between Flutter and native platforms:
1
Test Code Execution
Your Dart test code runs in the Flutter test environment, just like standard integration tests.
2
Native Communication
When you call a native method (e.g., $.platform.mobile.pressHome()), Patrol sends a command over a local network connection to the native test instrumentation.
3
Native Execution
The native instrumentation receives the command and executes it using platform-specific automation frameworks:
Android: UI Automator 2
iOS: XCTest
Web: Playwright
4
Result Return
The result is sent back to your Dart test code, allowing you to continue with assertions or further actions.
Native automation requires additional setup beyond standard Flutter integration tests. Make sure you’ve completed the installation steps for your target platforms.
// Go to home screenawait $.platform.mobile.pressHome();// Open recent apps / app switcherawait $.platform.mobile.openQuickSettings();// Press back button (Android) or swipe back (iOS)await $.platform.mobile.pressBack();// Switch to the previous appawait $.platform.mobile.pressDoubleRecentApps();
One of the most common use cases for native automation is handling system permission dialogs:
// Grant permission when system dialog appearsawait $.platform.mobile.grantPermissionWhenInUse();await $.platform.mobile.grantPermissionOnlyThisTime();await $.platform.mobile.denyPermission();
iOS Language Requirement: Patrol can only handle iOS permission dialogs when the device language is set to English (preferably US). This is because iOS doesn’t provide a language-independent way to identify permission dialog buttons.For non-English devices, handle permissions manually:
await $.platform.ios.tap( IOSSelector(text: 'Zezwól'), // "Allow" in Polish appId: 'com.apple.springboard',);
Patrol provides powerful capabilities for testing notification interactions:
Notification Actions
// Open notification shade/centerawait $.platform.mobile.openNotifications();// Tap notification by index (0-based)await $.platform.mobile.tapOnNotificationByIndex(0);// Tap notification by contentawait $.platform.mobile.tapOnNotificationBySelector( Selector(textContains: 'New message from'),);// Close notification (iOS)await $.platform.ios.closeHeadsUpNotification();
The $.platform.android automator provides Android-only features:
Android Actions
// Press hardware back buttonawait $.platform.android.pressBack();// Press hardware home button await $.platform.android.pressHome();// Open quick settingsawait $.platform.android.openQuickSettings();// Open a specific Android appawait $.platform.android.openPlatformApp( androidAppId: 'com.android.settings',);// Tap with Android-specific selectorawait $.platform.android.tap( AndroidSelector( resourceName: 'com.example:id/button', text: 'Submit', className: 'android.widget.Button', ),);
The $.platform.ios automator provides iOS-only features:
iOS Actions
// Swipe back gesture (edge swipe)await $.platform.ios.swipeBack();// Close heads-up notificationawait $.platform.ios.closeHeadsUpNotification();// Open a specific iOS appawait $.platform.ios.openPlatformApp( iosAppId: 'com.apple.Preferences',);// Tap with iOS-specific selectorawait $.platform.ios.tap( IOSSelector( identifier: 'submitButton', label: 'Submit', ),);
App ID Requirement: When interacting with iOS apps other than your Flutter app under test, you must specify the app’s bundle identifier:
Web tests often need to interact with content inside iframes:
// Tap element inside an iframeawait $.platform.web.tap( WebSelector(text: 'Submit Payment'), iframeSelector: WebSelector(cssOrXpath: 'css=#payment-iframe'),);