Skip to main content
Patrol 4.0 introduces significant improvements including web support, the new Platform Automation API, and enhanced testing capabilities. This guide will help you migrate your existing Patrol 3.x tests to 4.x.
Check out the Patrol 4.0 release announcement for a complete overview of new features.

What’s New in Patrol 4.0

Patrol 4.0 brings several major improvements:
  • Web Testing Support: Test your Flutter web applications with Patrol
  • Platform Automation API: Unified API replacing the legacy native and native2 APIs
  • VS Code Extension: Enhanced development experience with debugging and test running capabilities
  • New Default Test Directory: Changed from integration_test/ to patrol_test/
  • Improved Device Selection: Interactive device prompts and better CI support

Breaking Changes

The legacy Native Automation APIs ($.native and $.native2) are deprecated and will be removed in a future release. Migrate to $.platform as soon as possible.

1. Platform Automation API

The biggest change in Patrol 4.0 is the introduction of the Platform Automation API, which replaces the legacy $.native and $.native2 entry points.
1

Update Native Automation Calls

Before (Patrol 3.x):
// Using $.native
await $.native.tap(Selector(text: 'Allow'));
await $.native.pressBack();

// Using $.native2
await $.native2.pressHome();
await $.native2.tap(
  NativeSelector(
    android: AndroidSelector(resourceName: 'com.example:id/button'),
    ios: IOSSelector(identifier: 'submitButton'),
  ),
);
After (Patrol 4.x):
// Cross-platform mobile actions
await $.platform.mobile.tap(Selector(text: 'Allow'));
await $.platform.mobile.pressHome();

// Platform-specific actions
await $.platform.android.pressBack();

// Using MobileSelector
await $.platform.mobile.tap(
  MobileSelector(
    android: AndroidSelector(resourceName: 'com.example:id/button'),
    ios: IOSSelector(identifier: 'submitButton'),
  ),
);
2

Update Selector Types

Replace NativeSelector with the appropriate new selector type:
  • MobileSelector(...) - For different Android/iOS selectors
  • Selector(...) - For same selector across platforms
  • PlatformSelector(...) - For Android/iOS/Web selectors
Before:
await $.native2.tap(
  NativeSelector(
    android: AndroidSelector(text: 'Submit'),
    ios: IOSSelector(text: 'Submit'),
  ),
);
After:
await $.platform.mobile.tap(
  MobileSelector(
    android: AndroidSelector(text: 'Submit'),
    ios: IOSSelector(text: 'Submit'),
  ),
);

// Or simply use Selector for text-based selectors
await $.platform.mobile.tap(Selector(text: 'Submit'));
3

Update Configuration Classes

Before:
final nativeConfig = NativeAutomatorConfig(
  keyboardBehavior: KeyboardBehavior.alternative,
);

final automator = NativeAutomator(config: nativeConfig);
await automator.enableWifi();
After:
final platformConfig = PlatformAutomatorConfig.fromOptions(
  keyboardBehavior: KeyboardBehavior.alternative,
);

final automator = PlatformAutomator(config: platformConfig);
await automator.mobile.enableWifi();

2. Test Directory Change

The default test directory has changed from integration_test/ to patrol_test/ to avoid conflicts with Flutter’s official integration test package.
1

Choose Your Migration Path

You have two options:Option 1: Rename your test directory (Recommended)
mv integration_test patrol_test
Update your .gitignore:
.gitignore
# Replace
integration_test/test_bundle.dart

# With
patrol_test/test_bundle.dart
Option 2: Configure Patrol to use the old directoryAdd configuration to your pubspec.yaml:
pubspec.yaml
patrol:
  app_name: My App
  test_directory: integration_test  # Keep using old directory
  android:
    package_name: com.example.myapp
  ios:
    bundle_id: com.example.MyApp

3. Device Selection Changes

Patrol 4.x now prompts for device selection interactively. This improves the development experience but requires changes in CI environments.
# Pass the device explicitly
patrol test --device <device-id>

# Or set CI environment variable
export CI=true
patrol test
When CI=true is set, Patrol will automatically select an available device without prompting.

Migration Checklist

Use this checklist to ensure a smooth migration:
1

Update Dependencies

# Update Patrol CLI
patrol update

# Update patrol package in pubspec.yaml
flutter pub upgrade patrol
2

Rename Test Directory

mv integration_test patrol_test
Or configure test_directory in pubspec.yaml to keep using integration_test/.
3

Update Native Automation Calls

Search and replace across your test files:
  • $.native.$.platform.mobile. or $.platform.android. / $.platform.ios.
  • $.native2.$.platform.mobile.
  • NativeSelectorMobileSelector, Selector, or PlatformSelector
  • NativeAutomatorPlatformAutomator
  • NativeAutomatorConfigPlatformAutomatorConfig
4

Update Platform-Specific Actions

Move platform-specific actions to appropriate namespaces:
// Android-specific
await $.platform.android.pressBack();

// iOS-specific
await $.platform.ios.closeHeadsUpNotification();
5

Update CI Configuration

Add --device flag or set CI=true in your CI pipeline:
.github/workflows/test.yml
- name: Run Patrol tests
  run: patrol test --device <device-id>
  env:
    CI: true
6

Test Your Migration

# Run tests to verify everything works
patrol test

# Or use develop mode for faster iteration
patrol develop

Common Migration Patterns

Permission Handling

await $.native2.grantPermissionWhenInUse();
await $.native2.grantPermissionOnlyThisTime();

Notification Handling

await $.native2.openNotifications();
await $.native2.tapOnNotificationByIndex(0);
await $.native.closeHeadsUpNotification();

Device Settings

await $.native2.enableWifi();
await $.native2.disableWifi();
await $.native2.enableDarkMode();
await $.native2.pressHome();
await $.native.pressBack();

New Features in Patrol 4.0

Web Support

Patrol 4.0 introduces comprehensive web testing capabilities:
patrolTest('web test', ($) async {
  await $.pumpWidgetAndSettle(MyWebApp());
  
  // Grant browser permissions
  await $.platform.web.grantPermissions(permissions: ['clipboard-read']);
  
  // Manage cookies
  await $.platform.web.addCookie(name: 'session', value: 'abc123');
  
  // Handle browser dialogs
  await $.platform.web.acceptNextDialog();
});
Learn more about web testing with Patrol.

PlatformSelector for Multi-Platform Tests

Write tests that work across mobile and web:
await $.platform.tap(
  PlatformSelector(
    android: AndroidSelector(resourceName: 'submit_button'),
    ios: IOSSelector(identifier: 'submitButton'),
    web: WebSelector(cssSelector: '#submit-button'),
  ),
);

VS Code Extension

The new Patrol VS Code extension provides:
  • Run and debug tests directly from VS Code
  • Test exploration and navigation
  • Real-time test results
  • Integration with Flutter DevTools
Learn more about the Patrol VS Code Extension.

Troubleshooting

Tests Fail After Migration

If your tests fail after migration, check:
  1. Correct namespace: Ensure platform-specific actions use the right namespace ($.platform.android.* vs $.platform.ios.*)
  2. Selector types: Verify you’re using the correct selector type for your use case
  3. Configuration: Check that PlatformAutomatorConfig is properly initialized

Deprecation Warnings

If you see deprecation warnings:
// Deprecated
await $.native.tap(...);

// Use instead
await $.platform.mobile.tap(...);

Device Selection Issues in CI

If CI fails with device selection prompts:
# Add device flag
patrol test --device <device-id>

# Or set environment variable
export CI=true

Need Help?

If you encounter issues during migration:

Next Steps

After completing the migration:

Build docs developers (and LLMs) love