Flutter KeyCheck
A powerful CLI tool for validating Flutter automation keys in your codebase. Perfect for QA automation teams, CI/CD pipelines, and Flutter package development.
โจ Features
๐ KeyConstants Support (NEW in v2.1.9)
- Modern key patterns - Detects
Key(KeyConstants.*)
andValueKey(KeyConstants.*)
usage - Dynamic key methods - Supports
KeyConstants.*Key()
method patterns - KeyConstants validation - Validates KeyConstants class structure and usage
- Usage analysis - Comprehensive reports on traditional vs modern key patterns
- Migration recommendations - Suggests improvements for key management
๐ฏ Tracked Keys Validation (NEW in v2.1.0)
- Focus on critical UI elements - Define a subset of keys to validate for QA automation
- Flexible validation scope - Choose which keys matter most for your testing workflow
- Smart filtering - Combine tracked keys with include/exclude patterns
๐ Advanced Key Filtering & Tagging
- AQA/E2E tagging support - Organize keys by testing purpose (
aqa_*
for general automation,e2e_*
for critical flows) - Include-only patterns - Focus on specific key types like
qa_*
,e2e_*
,*_button
- Exclude patterns - Filter out noise like dynamic IDs, tokens, and business logic keys
- Regex support - Use complex patterns for precise filtering
- Substring matching - Simple pattern matching for common use cases
๐๏ธ Flutter Package Support
- Automatic example/ folder detection - Seamlessly handles pub.dev package structure
- Intelligent path resolution - Works from root, example/, or nested directories
- Comprehensive scanning - Validates both main project and example code
- Dual dependency checking - Verifies test dependencies in all relevant pubspec.yaml files
โ๏ธ Flexible Configuration
- YAML configuration files - Store settings in
.flutter_keycheck.yaml
- CLI argument override - Command-line arguments take priority over config files
- Multiple output formats - Human-readable or JSON output for automation
๐งช Integration Test Validation
- Dependency verification - Ensures
integration_test
andappium_flutter_server
are present - Test setup validation - Checks for proper Appium Flutter Driver initialization
- Strict mode - Enforce complete test setup for CI/CD environments
๐ฆ Installation
Global Installation
dart pub global activate flutter_keycheck
Project Dependency
dev_dependencies:
flutter_keycheck: ^2.1.0
๐ Quick Start
1. Generate Keys from Your Project
# Generate all keys found in your project
flutter_keycheck --generate-keys > keys/expected_keys.yaml
# Generate only AQA automation keys
flutter_keycheck --generate-keys --include-only="aqa_,e2e_" > keys/automation_keys.yaml
2. Validate Keys
# Basic validation
flutter_keycheck --keys keys/expected_keys.yaml
# Strict validation for CI/CD
flutter_keycheck --keys keys/expected_keys.yaml --strict --fail-on-extra
3. Use Configuration File
Create .flutter_keycheck.yaml
in your project root:
keys: keys/expected_keys.yaml
strict: false
verbose: false
fail_on_extra: false
# Focus on critical automation keys
tracked_keys:
- e2e_login_submit_button
- aqa_signup_email_field
- e2e_checkout_process
# Filter patterns for key generation and validation
include_only:
- aqa_
- e2e_
- _button
- _field
exclude:
- user.id
- token
- temp_
Then run:
flutter_keycheck
4. KeyConstants Analysis
# Validate KeyConstants class structure
flutter_keycheck --validate-key-constants
# Generate KeyConstants usage report
flutter_keycheck --key-constants-report
๐ท๏ธ AQA/E2E Tagging Strategy
Flutter KeyCheck supports organized tagging for different testing purposes, making it easier to manage keys across QA automation workflows.
Tagging Conventions
AQA Tags (aqa_*
)
- Purpose: General UI testing, validation, regression testing
- Scope: All testable UI elements
- Examples:
aqa_email_field
,aqa_submit_button
,aqa_error_message
E2E Tags (e2e_*
)
- Purpose: Critical user journeys, smoke testing
- Scope: Key business process elements only
- Examples:
e2e_login_flow
,e2e_checkout_process
,e2e_payment_button
Implementation Example
class LoginScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
// AQA: General UI testing
TextField(
key: const ValueKey('aqa_email_field'),
decoration: const InputDecoration(labelText: 'Email'),
),
TextField(
key: const ValueKey('aqa_password_field'),
decoration: const InputDecoration(labelText: 'Password'),
),
// E2E: Critical business flow
ElevatedButton(
key: const ValueKey('e2e_login_submit_button'),
onPressed: _handleLogin,
child: const Text('Login'),
),
// AQA: Error state testing
if (_hasError)
Container(
key: const ValueKey('aqa_error_message_container'),
child: const Text('Login failed'),
),
],
);
}
}
Configuration by Tags
Create separate configurations for different testing scenarios:
# .flutter_keycheck_aqa.yaml - For comprehensive UI testing
keys: keys/aqa_keys.yaml
include_only: [aqa_]
strict: false
fail_on_extra: false
# .flutter_keycheck_e2e.yaml - For critical flow testing
keys: keys/e2e_keys.yaml
include_only: [e2e_]
strict: true
fail_on_extra: true
Usage Commands
# Generate keys by testing purpose
flutter_keycheck --generate-keys --include-only="aqa_" > keys/aqa_keys.yaml
flutter_keycheck --generate-keys --include-only="e2e_" > keys/e2e_keys.yaml
# Validate by configuration
flutter_keycheck --config .flutter_keycheck_aqa.yaml
flutter_keycheck --config .flutter_keycheck_e2e.yaml --strict
# JSON reports for CI/CD
flutter_keycheck --config .flutter_keycheck_e2e.yaml --report json
For detailed examples and best practices, see AQA/E2E Usage Guide.
๐ Comprehensive Guide
KeyConstants Support
Flutter KeyCheck now supports modern KeyConstants patterns for better key management and organization.
Supported Patterns
// KeyConstants class definition
class KeyConstants {
// Static constants
static const String loginButton = 'login_button';
static const String emailField = 'email_field';
// Dynamic key methods
static Key gameCardKey(String gameId) => Key('game_card_$gameId');
static Key userProfileKey(int userId) => Key('user_profile_$userId');
}
// Usage in widgets
Widget build(BuildContext context) {
return Column(
children: [
// Modern KeyConstants usage (detected)
TextField(key: const Key(KeyConstants.emailField)),
ElevatedButton(
key: const ValueKey(KeyConstants.loginButton),
onPressed: () {},
child: Text('Login'),
),
// Traditional usage (still supported)
TextField(key: const ValueKey('old_style_key')),
],
);
}
// Usage in tests
testWidgets('login test', (tester) async {
// Modern finder usage (detected)
await tester.tap(find.byValueKey(KeyConstants.loginButton));
// Traditional finder usage (still supported)
await tester.tap(find.byValueKey('old_style_key'));
});
KeyConstants Validation
# Validate KeyConstants class structure
flutter_keycheck --validate-key-constants
Output:
๐ KeyConstants Validation
โ
KeyConstants class found
๐ Location: lib/constants/key_constants.dart
๐ Static constants (8):
โข loginButton
โข emailField
โข passwordField
โข signupButton
โข logoutButton
โข homeTab
โข profileTab
โข settingsTab
โ๏ธ Dynamic methods (4):
โข gameCardKey
โข userProfileKey
โข categoryButtonKey
โข notificationKey
Usage Analysis Report
# Generate comprehensive usage report
flutter_keycheck --key-constants-report
Output:
๐ KeyConstants Analysis Report
๐ Total keys found: 25
๐ Traditional string-based keys (15):
โข old_login_button
โข legacy_email_field
โข temp_password_input
...
๐๏ธ KeyConstants static keys (8):
โข loginButton
โข emailField
โข passwordField
...
โก KeyConstants dynamic methods (2):
โข gameCardKey
โข userProfileKey
๐ก Recommendations:
โข Found 15 traditional string-based keys that could be migrated to KeyConstants
โข Consider standardizing dynamic key method naming patterns
Tracked Keys Feature
The tracked keys feature allows you to focus validation on a critical subset of your UI automation keys. This is perfect for QA teams who want to ensure specific elements are always present without being overwhelmed by every key in the codebase.
Example Workflow
- Generate all keys from your project:
flutter_keycheck --generate-keys > keys/all_keys.yaml
- Create a tracked keys configuration focusing on critical elements:
# .flutter_keycheck.yaml
keys: keys/all_keys.yaml
tracked_keys:
- login_submit_button
- signup_email_field
- payment_confirm_button
- logout_button
- Validate only tracked keys:
flutter_keycheck
Output:
๐ Flutter KeyCheck Results
๐ Tracking 4 specific keys
โ
Matched tracked keys (3):
- login_submit_button
- signup_email_field
- logout_button
โ Missing tracked keys (1):
- payment_confirm_button
๐ All checks passed!
Advanced Filtering
Include-Only Patterns
Focus on specific key types:
# Only QA automation keys
flutter_keycheck --include-only="qa_,e2e_"
# Only buttons and fields
flutter_keycheck --include-only="_button,_field"
# Regex patterns
flutter_keycheck --include-only="^qa_.*_button$"
Exclude Patterns
Filter out noise and dynamic content:
# Exclude dynamic user data
flutter_keycheck --exclude="user.id,token,session"
# Exclude temporary and debug keys
flutter_keycheck --exclude="temp_,debug_,dev_"
# Exclude template variables (regex)
flutter_keycheck --exclude="\$\{.*\}"
Combined Filtering
# .flutter_keycheck.yaml
include_only:
- qa_
- e2e_
- automation_
exclude:
- temp_
- debug_
- user\..*
tracked_keys:
- qa_login_button
- qa_signup_field
- e2e_checkout_flow
Flutter Package Development
Flutter KeyCheck automatically detects and handles packages with example/ folders, which is the standard structure for packages published to pub.dev.
Supported Structures
my_package/
โโโ lib/ # Main package code
โโโ example/
โ โโโ lib/ # Example app code
โ โโโ integration_test/ # Example integration tests
โ โโโ pubspec.yaml # Example dependencies
โโโ integration_test/ # Package integration tests
โโโ pubspec.yaml # Package dependencies
โโโ .flutter_keycheck.yaml # Configuration
Automatic Detection
- Run from anywhere: Works from root directory or example/ subdirectory
- Comprehensive scanning: Validates keys in both main package and example app
- Dependency validation: Checks test dependencies in both pubspec.yaml files
- Integration test detection: Finds tests in both locations
Example Commands
# From package root - scans both main and example
flutter_keycheck --generate-keys
# From example directory - automatically detects package structure
cd example && flutter_keycheck --config=../.flutter_keycheck.yaml
# Validate package for publishing
flutter_keycheck --strict --fail-on-extra
Integration Test Validation
Flutter KeyCheck validates your Appium Flutter Driver setup:
Requirements
integration_test
dependency indev_dependencies
appium_flutter_server
dependency indev_dependencies
- Integration test files in
integration_test/
directory - Proper Appium Flutter Driver initialization
Example Integration Test Setup
// integration_test/appium_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:appium_flutter_server/appium_flutter_server.dart';
import 'package:my_app/main.dart' as app;
void main() {
group('App Integration Tests', () {
setUpAll(() async {
await initializeTest();
});
testWidgets('login flow', (WidgetTester tester) async {
app.main();
await tester.pumpAndSettle();
// Your test code using ValueKey elements
await tester.tap(find.byValueKey('login_submit_button'));
await tester.pumpAndSettle();
});
});
}
CLI Reference
Command-Line Options
Option | Description | Example |
---|---|---|
--keys |
Path to expected keys YAML file | --keys keys/expected_keys.yaml |
--path |
Project path to scan | --path ./my_flutter_app |
--strict |
Fail if integration test setup incomplete | --strict |
--verbose |
Show detailed output | --verbose |
--fail-on-extra |
Fail if extra keys found | --fail-on-extra |
--generate-keys |
Generate keys file from project | --generate-keys |
--include-only |
Include only matching patterns | --include-only="qa_,e2e_" |
--exclude |
Exclude matching patterns | --exclude="temp_,debug_" |
--config |
Configuration file path | --config .flutter_keycheck.yaml |
--report |
Output format (human/json) | --report json |
Configuration File Reference
# Basic settings
keys: keys/expected_keys.yaml # Path to expected keys file
path: . # Project path to scan
strict: false # Strict validation mode
verbose: false # Verbose output
fail_on_extra: false # Fail on extra keys
report: human # Output format
# Advanced filtering
include_only: # Include only matching patterns
- qa_
- e2e_
- _button
- _field
exclude: # Exclude matching patterns
- user.id
- token
- temp_
- debug_
# Tracked keys (NEW in v2.1.0)
tracked_keys: # Focus on specific keys
- login_submit_button
- signup_email_field
- card_dropdown
Usage Examples
QA Automation Workflow
# 1. Generate QA-specific keys
flutter_keycheck --generate-keys --include-only="qa_,e2e_" > keys/qa_keys.yaml
# 2. Create tracked keys config for critical elements
cat > .flutter_keycheck.yaml << EOF
keys: keys/qa_keys.yaml
tracked_keys:
- qa_login_button
- qa_signup_field
- qa_payment_button
fail_on_extra: true
EOF
# 3. Validate in CI/CD pipeline
flutter_keycheck --strict
CI/CD Integration
GitHub Actions
name: Flutter KeyCheck
on: [push, pull_request]
jobs:
keycheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
with:
sdk: stable
- name: Install flutter_keycheck
run: dart pub global activate flutter_keycheck
- name: Validate automation keys
run: flutter_keycheck --strict --fail-on-extra
- name: Upload key validation report
if: failure()
uses: actions/upload-artifact@v4
with:
name: keycheck-report
path: keycheck-report.json
GitLab CI
stages:
- test
- validate
keycheck:
stage: validate
image: dart:stable
before_script:
- dart pub global activate flutter_keycheck
script:
- flutter_keycheck --strict --fail-on-extra --report json > keycheck-report.json
artifacts:
when: always
reports:
junit: keycheck-report.json
expire_in: 1 week
only:
- merge_requests
- main
Azure DevOps
- task: DartInstaller@0
displayName: 'Install Dart SDK'
inputs:
dartVersion: 'stable'
- script: |
dart pub global activate flutter_keycheck
flutter_keycheck --strict --fail-on-extra
displayName: 'Validate Flutter Keys'
continueOnError: false
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'keycheck-report.xml'
testRunTitle: 'Flutter KeyCheck Results'
CircleCI
version: 2.1
orbs:
dart: circleci/dart@1.0.0
jobs:
keycheck:
executor: dart/dart
steps:
- checkout
- dart/install-dart
- run:
name: Install flutter_keycheck
command: dart pub global activate flutter_keycheck
- run:
name: Validate automation keys
command: flutter_keycheck --strict --fail-on-extra
- store_artifacts:
path: keycheck-report.json
destination: keycheck-report
workflows:
test-and-validate:
jobs:
- keycheck
Package Development
# Generate keys for package and example
flutter_keycheck --generate-keys > keys/expected_keys.yaml
# Validate package structure
flutter_keycheck --strict --verbose
# Test from example directory
cd example && flutter_keycheck --config=../.flutter_keycheck.yaml
๐จ Output Examples
Human-Readable (Default)
๐ Flutter KeyCheck Results
๐ Tracking 3 specific keys
โ
Matched tracked keys (2):
- login_submit_button
๐ lib/screens/login_screen.dart
- signup_email_field
๐ lib/screens/signup_screen.dart
โ Missing tracked keys (1):
- card_dropdown
โ
Required dependencies found
โ
Integration test setup complete
๐ฅ Some checks failed
JSON Output
# Standard key validation in JSON format
flutter_keycheck --report json
# KeyConstants analysis in JSON format
flutter_keycheck --key-constants-report --json-key-constants
flutter_keycheck --validate-key-constants --json-key-constants
Standard Validation JSON Structure
{
"timestamp": "2025-12-23T10:05:59.811115",
"summary": {
"total_expected_keys": 18,
"found_keys": 10,
"missing_keys": 8,
"extra_keys": 2,
"validation_passed": false
},
"missing_keys": ["avatar_image", "edit_profile_button"],
"extra_keys": ["emailField", "passwordField"],
"found_keys": {
"login_button": {
"key": "login_button",
"locations": ["lib/main.dart", "lib/widgets.dart"],
"location_count": 2
}
},
"dependencies": {
"integration_test": false,
"appium_flutter_server": false,
"all_dependencies_present": false
},
"integration_test_setup": {
"has_integration_tests": false,
"setup_complete": false
},
"tracked_keys": null
}
KeyConstants Analysis JSON Structure
{
"timestamp": "2025-12-23T10:06:11.364861",
"analysis_type": "key_constants_report",
"summary": {
"total_keys_found": 10,
"traditional_keys_count": 7,
"constant_keys_count": 3,
"dynamic_keys_count": 0
},
"traditional_keys": ["email_field", "password_field", "login_button"],
"constant_keys": ["loginButton", "emailField", "passwordField"],
"dynamic_keys": [],
"key_constants_validation": {
"hasKeyConstants": true,
"constantsFound": ["loginButton", "emailField", "passwordField"],
"methodsFound": [],
"filePath": "lib/key_constants.dart"
},
"recommendations": [
"Found 7 traditional string-based keys that could be migrated to KeyConstants"
]
}
๐ ๏ธ Troubleshooting
Common Issues
"No keys found in project"
- Ensure your Flutter widgets use
ValueKey
orKey
with string values - Check that you're scanning the correct directory with
--path
- Use
--verbose
to see which files are being scanned
"Missing dependencies"
Add required dependencies to your pubspec.yaml
:
dev_dependencies:
integration_test:
sdk: flutter
appium_flutter_server: ^0.0.27
"Integration test setup incomplete"
Ensure your integration tests import and initialize Appium Flutter Server:
import 'package:appium_flutter_server/appium_flutter_server.dart';
void main() {
setUpAll(() async {
await initializeTest();
});
}
Best Practices
- Use descriptive key names:
login_submit_button
instead ofbutton1
- Consistent naming patterns: Use prefixes like
qa_
,e2e_
,test_
- Avoid dynamic keys: Don't use variables in key values
- Regular validation: Run in CI/CD to catch missing keys early
- Track critical paths: Use tracked_keys for essential user journeys
๐ฆ Package Information
Excluded from Package
The published package excludes development files to keep it lightweight:
example/ # Example code (repo only)
test/ # Test files
.github/ # CI workflows
.vscode/ # Editor settings
.dart_tool/ # Build artifacts
Requirements
- Dart SDK: >=3.0.0 <4.0.0
- Platforms: Linux, macOS, Windows
- Flutter: Any version (for projects being validated)
๐ค Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Links
Made with โค๏ธ for the Flutter community
Libraries
- flutter_keycheck
- Flutter Key Integration Validator