patrol_plus 5.6.4
patrol_plus: ^5.6.4 copied to clipboard
A powerful, multiplatform E2E UI testing framework for Flutter apps that overcomes the limitations of integration_test by handling native interactions.
⚠️ Independent fork —
patrol_plusis an independent fork of Patrol, originally created by LeanCode. It is maintained by Bdaya-Dev and is not maintained, supported, or endorsed by LeanCode. Please report issues at https://github.com/Bdaya-Dev/patrol/issues, not to LeanCode. Both the original and this fork are licensed under the Apache License 2.0 (see LICENSE and NOTICE.md).
patrol_plus #
A powerful, multiplatform E2E UI testing framework for Flutter apps that overcomes the limitations of integration_test by handling native interactions, battle-tested and shaped by production-grade experience.
Patrol #
patrol_plus package builds on top of flutter_test and integration_test
to make it easy to control the native UI from Dart test code. It must be used
together with patrol_cli_plus.
It also provides a new custom finder system to make Flutter widget tests more
concise and understandable, and writing them – faster and more fun. If you
want to only use custom finders, check out
patrol_finders_plus.
Installation #
$ dart pub add patrol_plus --dev
⚠️ Additional setup is required to run tests – install
patrol_cli_plus. This package's API matches upstream Patrol; fork-specific changes are listed in this package's CHANGELOG.
Usage #
Patrol has 2 main features – native automation and custom finders. This package's API matches upstream Patrol; see this package's CHANGELOG for fork-specific changes.
Accessing native platform features #
// example/patrol_test/example_test.dart
import 'package:example/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol_plus/patrol.dart';
void main() {
patrolTest(
'counter state is the same after going to home and going back',
($) async {
await $.pumpWidgetAndSettle(const MyApp());
await $(FloatingActionButton).tap();
expect($(#counterText).text, '1');
await $.platform.mobile.pressHome();
await $.platform.mobile.pressDoubleRecentApps();
expect($(#counterText).text, '1');
await $(FloatingActionButton).tap();
expect($(#counterText).text, '2');
await $.platform.mobile.openNotifications();
await $.platform.mobile.pressBack();
},
);
}
Custom finders #
import 'package:example/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol_plus/patrol.dart';
void main() {
patrolTest(
'logs in successfully',
($) async {
await $.pumpWidgetAndSettle(const MyApp());
await $(#emailInput).enterText('user@example.com');
await $(#passwordInput).enterText('ny4ncat');
// Finds all widgets with text 'Log in' which are descendants of widgets with key
// box1, which are descendants of a Scaffold widget and tap on the first one.
await $(Scaffold).$(#box1).$('Log in').tap();
// Finds all Scrollables which have Text descendant
$(Scrollable).containing(Text);
// Finds all Scrollables which have a Button descendant which has a Text descendant
$(Scrollable).containing($(Button).containing(Text));
// Finds all Scrollables which have a Button descendant and a Text descendant
$(Scrollable).containing(Button).containing(Text);
},
);
}