patrol-e2e-testing
Generates and maintains end-to-end tests for Flutter apps using Patrol. Use when adding E2E coverage for new features, regression tests for UI bugs, or testing native interactions (permissions, system dialogs, deep links)
Best use case
patrol-e2e-testing is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Generates and maintains end-to-end tests for Flutter apps using Patrol. Use when adding E2E coverage for new features, regression tests for UI bugs, or testing native interactions (permissions, system dialogs, deep links)
Generates and maintains end-to-end tests for Flutter apps using Patrol. Use when adding E2E coverage for new features, regression tests for UI bugs, or testing native interactions (permissions, system dialogs, deep links)
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "patrol-e2e-testing" skill to help with this workflow task. Context: Generates and maintains end-to-end tests for Flutter apps using Patrol. Use when adding E2E coverage for new features, regression tests for UI bugs, or testing native interactions (permissions, system dialogs, deep links)
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/patrol-e2e-testing/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How patrol-e2e-testing Compares
| Feature / Agent | patrol-e2e-testing | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Generates and maintains end-to-end tests for Flutter apps using Patrol. Use when adding E2E coverage for new features, regression tests for UI bugs, or testing native interactions (permissions, system dialogs, deep links)
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Patrol E2E Testing Skill
This skill defines how to design, implement, and run end-to-end (E2E) tests using Patrol 4.x in Flutter projects.
It focuses on:
* Covering new feature flows with deterministic UI tests
* Converting reproducible UI bugs into regression tests
* Handling native OS interactions
* Running tests locally and in CI using correct Patrol CLI commands
## When to Use
Use this skill when:
* A new screen or user flow must be covered with E2E tests.
* A feature interacts with native components (permissions, notifications, system dialogs).
* A UI bug should be captured as a regression test.
* Cross-platform behavior (Android / iOS / Web) must be validated.
## Setup
For installation and project initialization, follow the official documentation:
[https://patrol.leancode.co/documentation#setup](https://patrol.leancode.co/documentation#setup)
Key Patrol conventions:
* `patrol` is added as a dev dependency.
* Tests live in `patrol_test/`.
* Test files must end with `_test.dart`.
* Tests are executed with `patrol test`.
## How to use this skill
Follow the steps below when implementing or updating Patrol tests.
### 1. Identify the user journey
Break the feature into:
* **Actions**: taps, scrolls, input, navigation, deep links.
* **Observable outcomes**: visible text, screen changes, enabled buttons, dialogs.
Rules:
* One test per primary (happy-path) journey.
* Separate tests for critical edge cases.
* Avoid combining unrelated flows in a single test.
### 2. Structure the Patrol test
Basic Patrol structure:
```dart
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
void main() {
patrolTest(
'user can log in successfully',
($) async {
await $.pumpWidgetAndSettle(const MyApp());
const email = String.fromEnvironment('E2E_EMAIL');
const password = String.fromEnvironment('E2E_PASSWORD');
await $(#emailField).enterText(email);
await $(#passwordField).enterText(password);
await $(#loginButton).tap();
await $.waitUntilVisible($(#homeScreenTitle));
expect($(#homeScreenTitle).text, equals('Welcome'));
},
);
}
```
Key concepts:
* Use `patrolTest()` instead of `testWidgets()`.
* `$` is the Patrol tester.
* Use `$(#keyName)` to find widgets by `Key`.
* Use explicit wait conditions (e.g., `waitUntilVisible`).
### 3. Handle native dialogs
For OS-level permission dialogs:
```dart
patrolTest('grants camera permission', ($) async {
await $.pumpWidgetAndSettle(const MyApp());
await $(#openCameraButton).tap();
if (await $.native.isPermissionDialogVisible()) {
await $.native.grantPermission();
}
await $.waitUntilVisible($(#cameraPreview));
});
```
Use native automation only when required by the feature.
### 4. Selector & interaction quick reference
**Finding widgets:**
```dart
$('some text') // by text
$(TextField) // by type
$(Icons.arrow_back) // by icon
```
**Tapping:**
```dart
// Tap a widget containing a specific text label
await $(Container).$('click').tap();
// Tap a container that contains an ElevatedButton
await $(Container).containing(ElevatedButton).tap();
// Tap only the enabled ElevatedButton
await $(ElevatedButton)
.which<ElevatedButton>(
(b) => b.enabled,
)
.tap();
```
**Entering text:**
```dart
// Enter text into the second TextField on screen
await $(TextField).at(1).enterText('your input');
```
**Scrolling:**
```dart
await $(widget_you_want_to_scroll_to).scrollTo();
```
**Native interactions:**
```dart
// Grant permission while app is in use
await $.native.grantPermissionWhenInUse();
// Open notification shade and tap a notification by text
await $.native.openNotifications();
await $.native.tapOnNotificationBySelector(
Selector(textContains: 'text'),
);
```
### 5. Running Patrol tests
Run all tests:
```bash
patrol test
```
Run a specific file with live reload (development mode):
```bash
patrol develop -t integration_test/my_test.dart
```
Run a specific file:
```bash
patrol test --target patrol_test/login_test.dart
```
Run on web:
```bash
patrol test --device chrome
```
Headless web (CI):
```bash
patrol test --device chrome --web-headless true
```
Filter by tags:
```bash
patrol test --tags android
```
### Output requirements when this skill is used
When applied, this skill must produce:
1. Patrol test(s) covering the specified feature.
2. Any required widget key additions.
3. Exact `patrol test` command(s) to execute locally.
4. Notes explaining stabilization decisions.
### Quality bar
A valid Patrol test must be:
* Deterministic (no arbitrary delays)
* Readable
* Minimal but complete
* Secret-safe (no hardcoded credentials)
* CI-readyRelated Skills
testing
Writes and reviews Flutter/Dart tests. Use when writing unit tests, widget tests, or reviewing existing tests for correctness, structure, and naming conventions.
riverpod
Uses Riverpod for state management in Flutter/Dart. Use when setting up providers, combining requests, managing state disposal, passing arguments, performing side effects, testing providers, or applying Riverpod best practices.
provider
Uses the Provider package for dependency injection and state management in Flutter. Use when setting up providers, consuming state, optimizing rebuilds, using ProxyProvider, or migrating from deprecated providers.
mocktail
Uses the Mocktail package for mocking in Flutter/Dart tests. Use when creating mocks, stubbing methods, verifying interactions, registering fallback values, or deciding between mocks, fakes, and real objects.
mockito
Uses the Mockito package for mocking in Flutter/Dart tests. Use when generating mocks, stubbing methods, verifying interactions, capturing arguments, or deciding between mocks, fakes, and real objects.
flutterfire-configure
Sets up Firebase for Flutter apps using FlutterFire CLI. Use when initializing a Firebase project, running flutterfire configure, initializing Firebase in main.dart, or configuring multiple app flavors.
flutter-errors
Diagnoses and fixes common Flutter errors. Use when encountering layout errors (RenderFlex overflow, unbounded constraints, RenderBox not laid out), scroll errors, or setState-during-build errors.
flutter-app-architecture
Provides best practices for Flutter app architecture, including layered architecture, data flow, state management patterns, and extensibility guidelines.
firebase-storage
Integrates Firebase Cloud Storage into Flutter apps. Use when setting up Storage, uploading or downloading files, managing metadata, handling errors, or applying security rules.
firebase-remote-config
Integrates Firebase Remote Config into Flutter apps. Use when setting up Remote Config, managing parameter defaults, fetching and activating values, implementing real-time updates, or handling throttling and testing.
firebase-messaging
Integrates Firebase Cloud Messaging (FCM) into Flutter apps. Use when setting up push notifications, handling foreground/background messages, managing permissions, working with FCM tokens, or configuring platform-specific notification behavior.
firebase-in-app-messaging
Integrates Firebase In-App Messaging into Flutter apps. Use when setting up in-app messaging, triggering or suppressing messages, managing user privacy and opt-in data collection, or testing campaigns.