Flutter-first UI testing framework. Ready for action!
1,425
stars
4,133
commits
Dart
primary language
Sep 11, 2026
updated
A powerful, multiplatform E2E UI testing framework for Flutter apps that overcomes the limitations of integration_test by handling native interactions. Developed by LeanCode since 2022, battle-tested and shaped by production-grade experience.
Patrol is an open-source framework created and maintained by LeanCode. However, if your company wants to scale fast and accelerate Patrol’s adoption, we offer a set of value-added services on top of the core framework.
You can find out more below:
[!NOTE] Patrol 4.7.0 adds Swift Package Manager support for iOS and macOS! If you migrate your project to SPM, a few small setup changes are needed — see the iOS setup guide for details.
Flutter's finders are powerful, but not very intuitive to use.
We took them and made something awesome.
Thanks to Patrol's custom finders, you'll take your tests from this:
testWidgets('signs up', (WidgetTester tester) async {
await tester.pumpWidget(AwesomeApp());
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(Key('emailTextField')),
'charlie@root.me',
);
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(Key('nameTextField')),
'Charlie',
);
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(Key('passwordTextField')),
'ny4ncat',
);
await tester.pumpAndSettle();
await tester.tap(find.byKey(Key('termsCheckbox')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(Key('signUpButton')));
await tester.pumpAndSettle();
expect(find.text('Welcome, Charlie!'), findsOneWidget);
});
to this:
patrolTest('signs up', (PatrolIntegrationTester $) async {
await $.pumpWidgetAndSettle(AwesomeApp());
await $(#emailTextField).enterText('charlie@root.me');
await $(#nameTextField).enterText('Charlie');
await $(#passwordTextField).enterText('ny4ncat');
await $(#termsCheckbox).tap();
await $(#signUpButton).tap();
await $('Welcome, Charlie!').waitUntilVisible();
});
Learn more about custom finders in the docs!
Patrol's custom finders are also available standalone in the patrol_finders package.
Flutter's default integration_test package can't interact with the OS your Flutter app is running on. This makes it impossible to test many critical business features, such as:
Patrol's native automation feature solves these problems:
void main() {
patrolTest('showtime', (PatrolIntegrationTester $) async {
await $.pumpWidgetAndSettle(AwesomeApp());
// prepare network conditions
await $.platform.mobile.enableCellular();
await $.platform.mobile.disableWifi();
// toggle system theme
await $.platform.mobile.enableDarkMode();
// handle native location permission request dialog
await $.platform.mobile.selectFineLocation();
await $.platform.mobile.grantPermissionWhenInUse();
// tap on the first notification
await $.platform.mobile.openNotifications();
await $.platform.mobile.tapOnNotificationByIndex(0);
});
}
See packages/patrol_cli.
The CLI is needed to enable Patrol's native automation feature in integration tests. It also makes development of integration tests much faster thanks to [Hot Restart].
To run widget tests, you can continue to use flutter test.
See packages/patrol.
See .github/WORKFLOWS.md for detailed documentation about all GitHub Actions workflows, including test schedules, Flutter versions, and deployment pipelines.
class OpenAppRequest {
late String appId;
}
NativeAutomator:abstract class NativeAutomator<IOSServer, AndroidServer, DartClient> {
...
void openApp(OpenAppRequest request);
...
}
gen_from_schema script, few files will be updatedIf you have previously activated patrol_cli run:
dart pub global deactivate patrol_cli
then
cd packages/patrol_cli
flutter pub global activate -s path .
This package is built with 💙 by LeanCode. We are top-tier experts focused on Flutter Enterprise solutions.
Creators of Patrol – the next-gen testing framework for Flutter.
Production-Ready – We use this package in apps with millions of users.
Full-Cycle Product Development – We take your product from scratch to long-term maintenance.
(top 30 of 86)
Dart
67.8%
Swift
13.0%
TypeScript
5.7%
C
3.9%
Objective-C
3.8%
Kotlin
3.4%
Flutter-first UI testing framework. Ready for action!
1,425
stars
4,133
commits
Dart
primary language
Sep 11, 2026
updated
A powerful, multiplatform E2E UI testing framework for Flutter apps that overcomes the limitations of integration_test by handling native interactions. Developed by LeanCode since 2022, battle-tested and shaped by production-grade experience.
Patrol is an open-source framework created and maintained by LeanCode. However, if your company wants to scale fast and accelerate Patrol’s adoption, we offer a set of value-added services on top of the core framework.
You can find out more below:
[!NOTE] Patrol 4.7.0 adds Swift Package Manager support for iOS and macOS! If you migrate your project to SPM, a few small setup changes are needed — see the iOS setup guide for details.
Flutter's finders are powerful, but not very intuitive to use.
We took them and made something awesome.
Thanks to Patrol's custom finders, you'll take your tests from this:
testWidgets('signs up', (WidgetTester tester) async {
await tester.pumpWidget(AwesomeApp());
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(Key('emailTextField')),
'charlie@root.me',
);
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(Key('nameTextField')),
'Charlie',
);
await tester.pumpAndSettle();
await tester.enterText(
find.byKey(Key('passwordTextField')),
'ny4ncat',
);
await tester.pumpAndSettle();
await tester.tap(find.byKey(Key('termsCheckbox')));
await tester.pumpAndSettle();
await tester.tap(find.byKey(Key('signUpButton')));
await tester.pumpAndSettle();
expect(find.text('Welcome, Charlie!'), findsOneWidget);
});
to this:
patrolTest('signs up', (PatrolIntegrationTester $) async {
await $.pumpWidgetAndSettle(AwesomeApp());
await $(#emailTextField).enterText('charlie@root.me');
await $(#nameTextField).enterText('Charlie');
await $(#passwordTextField).enterText('ny4ncat');
await $(#termsCheckbox).tap();
await $(#signUpButton).tap();
await $('Welcome, Charlie!').waitUntilVisible();
});
Learn more about custom finders in the docs!
Patrol's custom finders are also available standalone in the patrol_finders package.
Flutter's default integration_test package can't interact with the OS your Flutter app is running on. This makes it impossible to test many critical business features, such as:
Patrol's native automation feature solves these problems:
void main() {
patrolTest('showtime', (PatrolIntegrationTester $) async {
await $.pumpWidgetAndSettle(AwesomeApp());
// prepare network conditions
await $.platform.mobile.enableCellular();
await $.platform.mobile.disableWifi();
// toggle system theme
await $.platform.mobile.enableDarkMode();
// handle native location permission request dialog
await $.platform.mobile.selectFineLocation();
await $.platform.mobile.grantPermissionWhenInUse();
// tap on the first notification
await $.platform.mobile.openNotifications();
await $.platform.mobile.tapOnNotificationByIndex(0);
});
}
See packages/patrol_cli.
The CLI is needed to enable Patrol's native automation feature in integration tests. It also makes development of integration tests much faster thanks to [Hot Restart].
To run widget tests, you can continue to use flutter test.
See packages/patrol.
See .github/WORKFLOWS.md for detailed documentation about all GitHub Actions workflows, including test schedules, Flutter versions, and deployment pipelines.
class OpenAppRequest {
late String appId;
}
NativeAutomator:abstract class NativeAutomator<IOSServer, AndroidServer, DartClient> {
...
void openApp(OpenAppRequest request);
...
}
gen_from_schema script, few files will be updatedIf you have previously activated patrol_cli run:
dart pub global deactivate patrol_cli
then
cd packages/patrol_cli
flutter pub global activate -s path .
This package is built with 💙 by LeanCode. We are top-tier experts focused on Flutter Enterprise solutions.
Creators of Patrol – the next-gen testing framework for Flutter.
Production-Ready – We use this package in apps with millions of users.
Full-Cycle Product Development – We take your product from scratch to long-term maintenance.
(top 30 of 86)
Dart
67.8%
Swift
13.0%
TypeScript
5.7%
C
3.9%
Objective-C
3.8%
Kotlin
3.4%