sdd-full 4.6.2 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.js +1 -1
- package/package.json +1 -1
- package/skills/.agents/skills/flutter-add-integration-test/SKILL.md +165 -0
- package/skills/.agents/skills/flutter-add-widget-preview/SKILL.md +147 -0
- package/skills/.agents/skills/flutter-add-widget-test/SKILL.md +156 -0
- package/skills/.agents/skills/flutter-apply-architecture-best-practices/SKILL.md +164 -0
- package/skills/.agents/skills/flutter-build-responsive-layout/SKILL.md +141 -0
- package/skills/.agents/skills/flutter-fix-layout-issues/SKILL.md +132 -0
- package/skills/.agents/skills/flutter-implement-json-serialization/SKILL.md +155 -0
- package/skills/.agents/skills/flutter-setup-declarative-routing/SKILL.md +257 -0
- package/skills/.agents/skills/flutter-setup-localization/SKILL.md +212 -0
- package/skills/.agents/skills/flutter-use-http-package/SKILL.md +177 -0
- package/skills/VERSION.md +176 -62
- package/skills/design-planning/ai-coding-rules/SKILL.md +5 -13
- package/skills/design-planning/design-to-code/SKILL.md +5 -14
- package/skills/design-planning/enterprise-spec/SKILL.md +5 -13
- package/skills/design-planning/flutter-av/SKILL.md +5 -16
- package/skills/design-planning/flutter-map/SKILL.md +5 -14
- package/skills/design-planning/function-sdd/SKILL.md +5 -13
- package/skills/design-planning/global-overlay-stack-standard/SKILL.md +73 -0
- package/skills/design-planning/ui-motion-interaction-standard/SKILL.md +69 -0
- package/skills/design-planning/ui-sdd-specialized/SKILL.md +5 -14
- package/skills/development-execution/flutter-errors/SKILL.md +5 -15
- package/skills/flutter-skills/.github/dependabot.yaml +15 -0
- package/skills/flutter-skills/.github/workflows/dart_skills_lint_workflow.yaml +68 -0
- package/skills/flutter-skills/.github/workflows/skills_tool.yaml +51 -0
- package/skills/flutter-skills/CODE_OF_CONDUCT.md +3 -0
- package/skills/flutter-skills/CONTRIBUTING.md +36 -0
- package/skills/flutter-skills/LICENSE +26 -0
- package/skills/flutter-skills/README.md +50 -0
- package/skills/flutter-skills/pubspec.yaml +9 -0
- package/skills/flutter-skills/resources/flutter_skills.yaml +434 -0
- package/skills/flutter-skills/skills/flutter-add-integration-test/SKILL.md +163 -0
- package/skills/flutter-skills/skills/flutter-add-widget-preview/SKILL.md +145 -0
- package/skills/flutter-skills/skills/flutter-add-widget-test/SKILL.md +154 -0
- package/skills/flutter-skills/skills/flutter-apply-architecture-best-practices/SKILL.md +162 -0
- package/skills/flutter-skills/skills/flutter-build-responsive-layout/SKILL.md +139 -0
- package/skills/flutter-skills/skills/flutter-fix-layout-issues/SKILL.md +130 -0
- package/skills/flutter-skills/skills/flutter-implement-json-serialization/SKILL.md +153 -0
- package/skills/flutter-skills/skills/flutter-setup-declarative-routing/SKILL.md +255 -0
- package/skills/flutter-skills/skills/flutter-setup-localization/SKILL.md +210 -0
- package/skills/flutter-skills/skills/flutter-use-http-package/SKILL.md +175 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/add-dart-lint-validation-rule/SKILL.md +196 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-best-practices/SKILL.md +65 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-checks-migration/SKILL.md +158 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-cli-app-best-practices/SKILL.md +168 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-doc-validation/SKILL.md +87 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-long-lines/SKILL.md +101 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-matcher-best-practices/SKILL.md +136 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-modern-features/SKILL.md +266 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-package-maintenance/SKILL.md +92 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/SKILL.md +92 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/lib/src/calculator.dart +7 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/pubspec.yaml +8 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/example/test/calculator_test.dart +11 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/interpret_coverage.dart +95 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/pubspec.yaml +6 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-coverage/scripts/test/interpret_coverage_test.dart +93 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/dart-test-fundamentals/SKILL.md +173 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/definition-of-done/SKILL.md +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/flutter_skills_ignore.json +3 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/grill-me/SKILL.md +10 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/ignore.json +3 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/SKILL.md +371 -0
- package/skills/flutter-skills/tool/dart_skills_lint/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/flutter-skills/tool/dart_skills_lint/AUTHORS +7 -0
- package/skills/flutter-skills/tool/dart_skills_lint/CHANGELOG.md +12 -0
- package/skills/flutter-skills/tool/dart_skills_lint/CONTRIBUTING.md +51 -0
- package/skills/flutter-skills/tool/dart_skills_lint/LICENSE +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/README.md +203 -0
- package/skills/flutter-skills/tool/dart_skills_lint/analysis_options.yaml +296 -0
- package/skills/flutter-skills/tool/dart_skills_lint/bench/README.md +23 -0
- package/skills/flutter-skills/tool/dart_skills_lint/bench/baseline_throughput.dart +230 -0
- package/skills/flutter-skills/tool/dart_skills_lint/bin/cli.dart +10 -0
- package/skills/flutter-skills/tool/dart_skills_lint/dart_skills_lint.yaml +14 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/PRODUCTION_READYNESS.md +48 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/completion_migration_plan.md +99 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/legacy_patterns_report.md +110 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/feature_design_docs/pub_vs_skill_report.md +56 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/SPECIFICATION.md +79 -0
- package/skills/flutter-skills/tool/dart_skills_lint/documentation/knowledge/architecture_overview.md +64 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/dart_skills_lint.dart +11 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/config_parser.dart +156 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/entry_point.dart +354 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/fixable_rule.dart +20 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/analysis_severity.dart +15 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/check_type.dart +17 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.dart +34 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/ignore_entry.g.dart +19 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_context.dart +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skill_rule.dart +27 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.dart +26 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/skills_ignores.g.dart +24 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/models/validation_error.dart +31 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rule_registry.dart +79 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/absolute_paths_rule.dart +74 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/description_length_rule.dart +49 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/disallowed_field_rule.dart +61 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/name_format_rule.dart +167 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/relative_paths_rule.dart +72 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/trailing_whitespace_rule.dart +93 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/rules/valid_yaml_metadata_rule.dart +74 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/skills_ignores_storage.dart +36 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validation_session.dart +559 -0
- package/skills/flutter-skills/tool/dart_skills_lint/lib/src/validator.dart +238 -0
- package/skills/flutter-skills/tool/dart_skills_lint/pubspec.yaml +28 -0
- package/skills/flutter-skills/tool/dart_skills_lint/skills/README.md +10 -0
- package/skills/flutter-skills/tool/dart_skills_lint/skills/dart-skills-lint-validation/SKILL.md +195 -0
- package/skills/flutter-skills/tool/dart_skills_lint/skills-lock.json +75 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/absolute_paths_test.dart +167 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/cli_integration_test.dart +683 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/config_file_test.dart +292 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/custom_rule_test.dart +122 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/directory_structure_test.dart +163 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/field_constraints_test.dart +178 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/fixer_test.dart +172 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/ignore_models_test.dart +63 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/metadata_validation_test.dart +116 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/relative_path_flag_test.dart +70 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/relative_paths_test.dart +172 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/resolve_rules_test.dart +82 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/rule_naming_test.dart +29 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/skills_ignores_storage_test.dart +89 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/test_utils.dart +19 -0
- package/skills/flutter-skills/tool/dart_skills_lint/test/trailing_whitespace_test.dart +152 -0
- package/skills/flutter-skills/tool/generator/README.md +150 -0
- package/skills/flutter-skills/tool/generator/analysis_options.yaml +143 -0
- package/skills/flutter-skills/tool/generator/bin/skills.dart +73 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/base_skill_command.dart +87 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/base_yaml_command.dart +83 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/generate_skill_command.dart +92 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/update_readme_command.dart +150 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/update_skill_command.dart +97 -0
- package/skills/flutter-skills/tool/generator/lib/src/commands/validate_skill_command.dart +284 -0
- package/skills/flutter-skills/tool/generator/lib/src/models/skill_params.dart +41 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/gemini_service.dart +310 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/markdown_converter.dart +226 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/prompts.dart +72 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/resource_fetcher_service.dart +84 -0
- package/skills/flutter-skills/tool/generator/lib/src/services/skill_instructions.dart +30 -0
- package/skills/flutter-skills/tool/generator/pubspec.yaml +32 -0
- package/skills/flutter-skills/tool/generator/test/commands/base_skill_command_test.dart +131 -0
- package/skills/flutter-skills/tool/generator/test/commands/validate_skills_input_test.dart +263 -0
- package/skills/flutter-skills/tool/generator/test/custom_skill_rules/last_modified_rule.dart +32 -0
- package/skills/flutter-skills/tool/generator/test/generate_skills_retry_test.dart +105 -0
- package/skills/flutter-skills/tool/generator/test/generate_skills_test.dart +519 -0
- package/skills/flutter-skills/tool/generator/test/lint_skills_test.dart +34 -0
- package/skills/flutter-skills/tool/generator/test/markdown_converter_test.dart +103 -0
- package/skills/flutter-skills/tool/generator/test/markdown_table_test.dart +131 -0
- package/skills/flutter-skills/tool/generator/test/models/skill_params_test.dart +37 -0
- package/skills/flutter-skills/tool/generator/test/services/gemini_service_test.dart +291 -0
- package/skills/flutter-skills/tool/generator/test/services/markdown_converter_test.dart +156 -0
- package/skills/flutter-skills/tool/generator/test/services/resource_fetcher_service_test.dart +188 -0
- package/skills/flutter-skills/tool/generator/test/update_skills_test.dart +241 -0
- package/skills/flutter-skills/tool/generator/test/validate_skills_test.dart +728 -0
- package/skills/quality-assurance/bdd-acceptance/SKILL.md +5 -14
- package/skills/quality-assurance/flutter-test/SKILL.md +5 -16
- package/skills/rules/project_rules.md +538 -127
- package/skills/special-tools/env-check/SKILL.md +5 -13
- package/skills/special-tools/ios-full-auto-debug/SKILL.md +5 -15
- package/skills/writing-skills/SKILL.md +654 -0
- package/skills/writing-skills/anthropic-best-practices.md +1149 -0
- package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/writing-skills/persuasion-principles.md +187 -0
- package/skills/writing-skills/render-graphs.js +168 -0
- package/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/skills/checklist.md +0 -154
- package/skills/rules/user_rules.md +0 -263
- package/skills//345/256/214/346/225/264/345/274/200/345/217/221/346/265/201/347/250/213/346/211/213/345/206/214.md +0 -454
- package/skills//346/212/200/350/203/275/344/275/223/347/263/273/345/256/214/345/226/204/345/273/272/350/256/256.md +0 -308
- package/skills//346/212/200/350/203/275/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -309
- package/skills//346/212/200/350/203/275/345/206/263/347/255/226/346/240/221.md +0 -338
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
# Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
|
|
2
|
+
# for details. All rights reserved. Use of this source code is governed by a
|
|
3
|
+
# BSD-style license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
# This is the configuration file for the skill generator.
|
|
6
|
+
# To generate skills, use the following command (from the `tool` directory):
|
|
7
|
+
# dart run skills generate-skill --config ../resources/flutter_skills.yaml --output ../skills
|
|
8
|
+
- name: flutter-add-integration-test
|
|
9
|
+
description: Configures Flutter Driver for app interaction and converts MCP
|
|
10
|
+
actions into permanent integration tests. Use when adding integration
|
|
11
|
+
testing to a project, exploring UI components via MCP, or automating user
|
|
12
|
+
flows with the integration_test package.
|
|
13
|
+
examplePrompt: "Add an integration test that validates the checkout experience"
|
|
14
|
+
instructions: |
|
|
15
|
+
1. **Project Setup and Dependency Management:**
|
|
16
|
+
* Add the `integration_test` package as a `dev_dependency` to your `pubspec.yaml` file. This can be done by running `flutter pub add 'dev:integration_test:{"sdk":"flutter"}'`.
|
|
17
|
+
* Ensure the `flutter_test` package is also included as a `dev_dependency`.
|
|
18
|
+
* Ensure `flutter_driver` is configured by importing `package:flutter_driver/driver_extension.dart' and calling `enableFlutterDriverExtension()`
|
|
19
|
+
|
|
20
|
+
2. **Interactive Exploration (Flutter Driver MCP)**
|
|
21
|
+
* Once configured, use the `flutter-driver` MCP tools to explore the app:
|
|
22
|
+
1. **Launch**: Use `launch_app` with `target: "lib/main_test.dart"`.
|
|
23
|
+
2. **Inspect**: Use `get_widget_tree` to find `Key`s, `Text`, or `Type`s.
|
|
24
|
+
3. **Interact**: Use `tap`, `enter_text`, and `scroll` to execute your flow.
|
|
25
|
+
4. **Wait**: Always call `waitFor` or check `get_health` if transitions are slow.
|
|
26
|
+
* If a widget isn't found, it might be unmounted in a `SliverList` or `ListView`. Use `scroll` or `scrollIntoView` first.
|
|
27
|
+
3. **Integration Test File Creation:**
|
|
28
|
+
* Create a new directory named `integration_test/` within your project.
|
|
29
|
+
* Inside this directory, create your test files with the format `<name>_test.dart`.
|
|
30
|
+
* For running tests with `flutter drive`, create a `test_driver` directory and an `integration_test.dart` file within it, containing `integrationDriver()`.
|
|
31
|
+
|
|
32
|
+
4. **Writing Integration Tests:**
|
|
33
|
+
* Integration tests verify the behavior of the complete app and can be used to validate how individual pieces work together or capture app performance on a real device. They are also known as end-to-end or GUI testing.
|
|
34
|
+
* Use `flutter_test` APIs to write tests in a style similar to widget tests.
|
|
35
|
+
* To verify a widget is displayed, load the main app widget using `tester.pumpWidget` and then use `expect` with `findsOneWidget`.
|
|
36
|
+
* For user interactions like tapping, use `tester.tap` and then `tester.pumpAndSettle` to wait for UI changes.
|
|
37
|
+
* To verify a widget is not displayed, use `expect` with `findsNothing`.
|
|
38
|
+
* For scrolling, `integration_test` allows using `tester.scrollUntilVisible` to scroll to a specific item.
|
|
39
|
+
* When working with `flutter_driver` (for migration or specific scenarios), `waitFor` is used to locate widgets, and `waitForAbsent` to ensure a widget is not present. `flutter_driver` also uses `driver.tap` for interactions and `driver.scroll` for scrolling.
|
|
40
|
+
* Add `Key` parameters to widgets, such as `ValueKey('increment')`, to allow finding specific widgets within the test suite.
|
|
41
|
+
|
|
42
|
+
5. **Running Integration Tests:**
|
|
43
|
+
* Integration tests can be run on a physical device or emulator using the `flutter drive` command.
|
|
44
|
+
* To run tests on Chrome, launch `chromedriver` and then use `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome`.
|
|
45
|
+
* To run as a headless test, use `flutter drive` with the `-d web-server` option.
|
|
46
|
+
* For Android, you can build a debug APK using `flutter build apk --debug` and then build an Android test APK using `./gradlew app:assembleAndroidTest`.
|
|
47
|
+
* Integration tests can also be run on Firebase Test Lab to automate testing on various devices. This involves creating an APK using Gradle and uploading it to the Firebase Test Lab Console.
|
|
48
|
+
resources:
|
|
49
|
+
- https://raw.githubusercontent.com/dart-lang/ai/refs/heads/main/pkgs/dart_mcp_server/README.md
|
|
50
|
+
- https://docs.flutter.dev/cookbook/testing/integration
|
|
51
|
+
- https://docs.flutter.dev/cookbook/testing/integration/introduction
|
|
52
|
+
- https://docs.flutter.dev/cookbook/testing/integration/profiling
|
|
53
|
+
- https://docs.flutter.dev/testing/integration-tests
|
|
54
|
+
- https://docs.flutter.dev/testing/plugins-in-tests
|
|
55
|
+
- https://docs.flutter.dev/testing/testing-plugins
|
|
56
|
+
- name: flutter-fix-layout-issues
|
|
57
|
+
description: Fixes Flutter layout errors (overflows, unbounded constraints)
|
|
58
|
+
using Dart and Flutter MCP tools. Use when addressing "RenderFlex overflowed",
|
|
59
|
+
"Vertical viewport was given unbounded height", or similar layout issues.
|
|
60
|
+
examplePrompt: "Fix the overflow error on the profile page when the keyboard is visible"
|
|
61
|
+
instructions: |
|
|
62
|
+
1. **Identify the Layout Error:**
|
|
63
|
+
* Recognize common Flutter framework errors, including layout errors.
|
|
64
|
+
* Look for specific error messages such as "RenderFlex overflowed", "Vertical viewport was given unbounded height", "An InputDecorator...cannot have an unbounded width", or "RenderBox was not laid out".
|
|
65
|
+
* A solid red or grey screen can also indicate an error.
|
|
66
|
+
|
|
67
|
+
2. **Understand the Cause of the Error:**
|
|
68
|
+
* **"Vertical viewport was given unbounded height"**: This error often occurs when a scrollable widget, like a `ListView` or `GridView`, is placed inside a `Column`. `ListView`s take all available vertical space unless constrained by a parent, and `Column`s don't impose height constraints on their children by default, leading to an inability to determine the `ListView`'s size.
|
|
69
|
+
* **Unbounded Width Errors (e.g., `InputDecorator` or `TextField`)**: This happens when a `Row` contains a `TextFormField` or `TextField` without a width constraint. Similarly, a `Column` might try to be wider than its parent `Row` can allocate, causing an overflow. This is due to Flutter's layout process where parents pass down constraints, and children respond by passing up a size within those constraints. If a child, like a `Text` widget, determines its own width based on its content, and its parent (`Column`) adopts that width, it can clash with the parent's (`Row`) maximum horizontal space.
|
|
70
|
+
* **"RenderBox was not laid out"**: This error is often a side effect of a primary error earlier in the rendering pipeline. It usually relates to violations of box constraints, meaning Flutter needs more information on how to constrain the widgets.
|
|
71
|
+
* **"Incorrect use of ParentData widget"**: This error indicates that a `ParentDataWidget` is not placed directly inside a compatible ancestor widget. Certain widgets, like `Flexible` and `Expanded`, expect specific parent widgets such as `Row`, `Column`, or `Flex`. `Positioned` expects a `Stack`, and `TableCell` expects a `Table`.
|
|
72
|
+
|
|
73
|
+
3. **Apply the Appropriate Fix:**
|
|
74
|
+
* **For "Vertical viewport was given unbounded height" (ListView in Column)**:
|
|
75
|
+
* Specify the height of the `ListView`.
|
|
76
|
+
* Wrap the `ListView` in an `Expanded` widget to make it take the remaining space in the `Column`.
|
|
77
|
+
* Alternatively, use a `SizedBox` for an absolute height or a `Flexible` widget for a relative height.
|
|
78
|
+
* **For unbounded width errors (e.g., `TextField` in `Row` or `Column` in `Row`)**:
|
|
79
|
+
* Constrain the width of the widget (e.g., `InputDecorator`, `TextField`, or `Column`).
|
|
80
|
+
* Wrap the widget in an `Expanded` widget.
|
|
81
|
+
* Wrap the widget in a `Flexible` widget and specify a flex factor. An `Expanded` widget is equivalent to a `Flexible` widget with a flex factor of 1.0.
|
|
82
|
+
* **For "RenderBox was not laid out"**: The solution involves providing more information to Flutter about how to constrain the widgets. Understanding how constraints work in Flutter is crucial.
|
|
83
|
+
* **For "Incorrect use of ParentData widget"**: The fix is to place the `ParentDataWidget` inside its expected parent widget.
|
|
84
|
+
|
|
85
|
+
4. **Review and Refine:**
|
|
86
|
+
* Compare your code to working examples if available.
|
|
87
|
+
* Use automatic reformatting support in your Flutter editor.
|
|
88
|
+
* Leverage Flutter's hot reload feature to accelerate development and see changes quickly.
|
|
89
|
+
resources:
|
|
90
|
+
- https://raw.githubusercontent.com/dart-lang/ai/refs/heads/main/pkgs/dart_mcp_server/README.md
|
|
91
|
+
- https://docs.flutter.dev/get-started/fundamentals/layout
|
|
92
|
+
- https://docs.flutter.dev/release/breaking-changes/layout-builder-optimization
|
|
93
|
+
- https://docs.flutter.dev/testing/common-errors
|
|
94
|
+
- https://docs.flutter.dev/testing/errors
|
|
95
|
+
- https://docs.flutter.dev/tools/devtools/inspector
|
|
96
|
+
- https://docs.flutter.dev/tools/devtools/legacy-inspector
|
|
97
|
+
- https://docs.flutter.dev/tools/flutter-fix
|
|
98
|
+
- https://docs.flutter.dev/ui/layout
|
|
99
|
+
- https://docs.flutter.dev/ui/layout/constraints
|
|
100
|
+
- https://docs.flutter.dev/ui/layout/tutorial
|
|
101
|
+
- name: flutter-add-widget-preview
|
|
102
|
+
description: Adds interactive widget previews to the project using the
|
|
103
|
+
previews.dart system. Use when creating new UI components or updating
|
|
104
|
+
existing screens to ensure consistent design and interactive testing.
|
|
105
|
+
examplePrompt: "Create a preview for the ProductCard widget with different price states"
|
|
106
|
+
instructions: |
|
|
107
|
+
1. Defining Widget Previews:
|
|
108
|
+
* To preview a widget, use the `@Preview` annotation defined in `package:flutter/widget_previews.dart`.
|
|
109
|
+
* This annotation can be applied to top-level functions that return a `Widget` or `WidgetBuilder`, static methods within a class that return a `Widget` or `WidgetBuilder`, or public `Widget` constructors and factories with no required arguments.
|
|
110
|
+
* A basic example involves importing `package:flutter/widget_previews.dart` and `package:flutter/material.dart`, then defining a function annotated with `@Preview` that returns a `Widget`, such as a `Text` widget. For instance:
|
|
111
|
+
```dart
|
|
112
|
+
import 'package:flutter/widget_previews.dart';
|
|
113
|
+
import 'package:flutter/material.dart';
|
|
114
|
+
|
|
115
|
+
@Preview(name: 'My Sample Text')
|
|
116
|
+
Widget mySampleText() {
|
|
117
|
+
return const Text('Hello, World!');
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
* Multiple preview configurations can be created by applying multiple `@Preview` annotations to a single function or constructor.
|
|
122
|
+
* For common configurations, extend `MultiPreview` to create a custom annotation. `MultiPreview` also provides a `transform()` method to perform transformations on each preview at runtime.
|
|
123
|
+
|
|
124
|
+
2. Interacting with Previews:
|
|
125
|
+
* As of Flutter 3.38, Android Studio, IntelliJ, and Visual Studio Code automatically start the Flutter Widget Previewer on launch.
|
|
126
|
+
* Alternatively, the previewer can be started from the command line by navigating to the Flutter project's root directory and running `flutter widget-preview start`. This command launches a local server and opens a Widget Preview environment in Chrome that updates automatically with project changes.
|
|
127
|
+
resources:
|
|
128
|
+
- https://docs.flutter.dev/tools/widget-previewer
|
|
129
|
+
- name: flutter-apply-architecture-best-practices
|
|
130
|
+
description: Architects a Flutter application using the recommended layered
|
|
131
|
+
approach (UI, Logic, Data). Use when structuring a new project or
|
|
132
|
+
refactoring for scalability.
|
|
133
|
+
examplePrompt: "Refactor the authentication flow to follow the recommended layered architecture"
|
|
134
|
+
instructions: |
|
|
135
|
+
**1. Understand the Core Principles and Layers:**
|
|
136
|
+
* **Separation of Concerns** is the most important principle to follow when designing your Flutter app. This principle makes your code less error-prone by keeping widgets "dumb".
|
|
137
|
+
* Flutter applications should be written in **layers**. Layered architecture organizes an application into distinct layers, each with specific roles and responsibilities.
|
|
138
|
+
* Typically, applications are separated into 2 to 3 layers, depending on complexity. The three common layers are the UI layer, logic layer, and data layer.
|
|
139
|
+
* The Flutter team strongly recommends using clearly defined **data and UI layers**.
|
|
140
|
+
* Within each layer, further separate your application by **feature or functionality**. For example, authentication logic should be in a different class than search logic.
|
|
141
|
+
|
|
142
|
+
**2. Structure the UI Layer:**
|
|
143
|
+
* The **UI layer** displays data to the user that is exposed by the business logic layer, and handles user interaction. It is also commonly referred to as the 'presentation layer'.
|
|
144
|
+
* The UI layer contains separate classes for UI logic and widgets.
|
|
145
|
+
* Use **ViewModels and Views** in the UI layer. Views and ViewModels make up the UI layer of an application.
|
|
146
|
+
* Implement the **MVVM architectural pattern** (Model-View-ViewModel) in the UI layer. MVVM separates a feature into three parts: Model, ViewModel, and View.
|
|
147
|
+
* Write **reusable, lean widgets** that hold as little logic as possible. Do not put logic in widgets.
|
|
148
|
+
* Use **ChangeNotifiers and Listenables** to handle widget updates. The ChangeNotifier API is part of the Flutter SDK and is a convenient way for widgets to observe changes in ViewModels.
|
|
149
|
+
|
|
150
|
+
**3. Structure the Logic Layer (Optional):**
|
|
151
|
+
* The **Logic layer** implements core business logic and facilitates interaction between the data layer and UI layer. It is commonly known as the 'domain layer'.
|
|
152
|
+
* This layer is **optional** and only needs to be implemented if your application has complex business logic that happens on the client. Many apps are only concerned with presenting and changing data (CRUD apps).
|
|
153
|
+
|
|
154
|
+
**4. Structure the Data Layer:**
|
|
155
|
+
* The **data layer** exposes application data to the rest of the app and contains most of the business logic.
|
|
156
|
+
* Use the **repository pattern** in the data layer. This pattern isolates data access logic from the rest of the application, creating an abstraction layer between business logic and underlying data storage mechanisms (databases, APIs, file systems, etc.).
|
|
157
|
+
* In practice, this means creating **Repository classes and Service classes**.
|
|
158
|
+
* Repositories and services represent the data of an application, or the model layer of MVVM.
|
|
159
|
+
* Services interact with external APIs, such as client servers and platform plugins.
|
|
160
|
+
|
|
161
|
+
**5. Project Organization and Best Practices:**
|
|
162
|
+
* A single feature in an application might require a View, a ViewModel, one or more Repositories, and zero or more Services.
|
|
163
|
+
* Well-organized code is easier for multiple engineers to work on with minimal code conflicts and is easier for new engineers to navigate and understand.
|
|
164
|
+
* These recommendations are guidelines, not steadfast rules, and should be adapted to your unique requirements.
|
|
165
|
+
* The Flutter team strongly recommends implementing these practices when starting a new application and strongly considering refactoring existing apps unless it fundamentally clashes with the current approach.
|
|
166
|
+
|
|
167
|
+
resources:
|
|
168
|
+
- https://docs.flutter.dev/app-architecture
|
|
169
|
+
- https://docs.flutter.dev/app-architecture/case-study
|
|
170
|
+
- https://docs.flutter.dev/app-architecture/case-study/data-layer
|
|
171
|
+
- https://docs.flutter.dev/app-architecture/case-study/ui-layer
|
|
172
|
+
- https://docs.flutter.dev/app-architecture/concepts
|
|
173
|
+
- https://docs.flutter.dev/app-architecture/design-patterns
|
|
174
|
+
- https://docs.flutter.dev/app-architecture/guide
|
|
175
|
+
- https://docs.flutter.dev/app-architecture/recommendations
|
|
176
|
+
- https://docs.flutter.dev/learn/pathway/how-flutter-works
|
|
177
|
+
- https://docs.flutter.dev/reference/create-new-app
|
|
178
|
+
- https://docs.flutter.dev/resources/architectural-overview
|
|
179
|
+
- https://docs.flutter.dev/resources/faq
|
|
180
|
+
- https://docs.flutter.dev/ui/layout/tutorial
|
|
181
|
+
- name: flutter-build-responsive-layout
|
|
182
|
+
description: Use `LayoutBuilder`, `MediaQuery`, or `Expanded/Flexible` to
|
|
183
|
+
create a layout that adapts to different screen sizes. Use when you need the
|
|
184
|
+
UI to look good on both mobile and tablet/desktop form factors.
|
|
185
|
+
examplePrompt: "Make the home screen responsive so it displays a grid on tablets and a list on phones"
|
|
186
|
+
instructions: |
|
|
187
|
+
1. **Determine the available space**:
|
|
188
|
+
* Use `MediaQuery.sizeOf(context)` or `LayoutBuilder` to get the size of the window your app is currently running in.
|
|
189
|
+
* `LayoutBuilder` builds a widget tree that can depend on the parent widget's size. Its builder callback provides `BoxConstraints` from its parent, which can be used to return different widgets based on the available space.
|
|
190
|
+
* Avoid using `MediaQuery.orientationOf` or `OrientationBuilder` near the top of your widget tree to switch between different app layouts, as the device's orientation doesn't necessarily inform you of the app window's space.
|
|
191
|
+
* Do not check for hardware types like "phone" or "tablet" when making layout decisions, as the space an app renders in isn't always tied to the full screen size of the device. Flutter apps can run in resizable windows, multi-window modes, or picture-in-picture.
|
|
192
|
+
* For large screen devices, `MediaQuery` can be used to get the app window size rather than the physical device size.
|
|
193
|
+
* Another approach is to use the `maxWidth` property of `BoxConstraints` by wrapping a widget like `GridView` in a `ConstrainedBox` or `Container`.
|
|
194
|
+
|
|
195
|
+
2. **Implement adaptive layouts based on available space**:
|
|
196
|
+
* Use `LayoutBuilder` to return different layouts based on the `BoxConstraints` received. For example, you can check `constraints.maxWidth` to determine if the screen is large (e.g., `maxWidth > largeScreenMinWidth`) and return a different widget tree accordingly.
|
|
197
|
+
* For small screens, you might use a navigation-style approach, while for large screens, you could use a `Row` to place elements side-by-side.
|
|
198
|
+
* Consider using adaptive breakpoints, such as those recommended by Material Design.
|
|
199
|
+
|
|
200
|
+
3. **Manage widget sizing and positioning within layouts**:
|
|
201
|
+
* Utilize `Expanded` and `Flexible` widgets within `Row`, `Column`, or `Flex` to distribute available space among children.
|
|
202
|
+
* `Expanded` stretches a child to fill any remaining available space. It is equivalent to `Flexible` with a `flex` factor of 1.0.
|
|
203
|
+
* `Flexible` allows a child to be sized to a specific size while still allowing it to expand or contract. You can specify a `flex` factor to determine the ratio in which `Expanded` or `Flexible` children consume available space. For example, a `flex` factor of 2 will make a widget twice as wide as others with a `flex` factor of 1.
|
|
204
|
+
* To prevent widgets from gobbling up all horizontal space on large screens, consider constraining their width.
|
|
205
|
+
* For lists with an unknown number of items, `ListView.builder` can be used to lazily render items.
|
|
206
|
+
|
|
207
|
+
4. **Consider specific device and orientation behaviors**:
|
|
208
|
+
* Avoid locking screen orientation, as it can cause issues on foldable devices, potentially leading to letterboxing where the app is centered with black borders.
|
|
209
|
+
* If screen orientation must be locked (though generally discouraged), use the `Display API` to get physical screen dimensions instead of `MediaQuery`. The `Display API` is useful in situations where `MediaQuery` might not receive the larger window size due to compatibility modes.
|
|
210
|
+
* Android and Flutter design guidance recommends not locking screen orientation. Android large format tiers require both portrait and landscape support.
|
|
211
|
+
* Support a variety of input devices, including basic mice, trackpads, and keyboard shortcuts.
|
|
212
|
+
resources:
|
|
213
|
+
- https://docs.flutter.dev/cookbook/design/orientation
|
|
214
|
+
- https://docs.flutter.dev/get-started/fundamentals/layout
|
|
215
|
+
- https://docs.flutter.dev/learn/pathway/tutorial/adaptive-layout
|
|
216
|
+
- https://docs.flutter.dev/release/breaking-changes/layout-builder-optimization
|
|
217
|
+
- https://docs.flutter.dev/testing/common-errors
|
|
218
|
+
- https://docs.flutter.dev/ui
|
|
219
|
+
- https://docs.flutter.dev/ui/adaptive-responsive
|
|
220
|
+
- https://docs.flutter.dev/ui/adaptive-responsive/best-practices
|
|
221
|
+
- https://docs.flutter.dev/ui/adaptive-responsive/general
|
|
222
|
+
- https://docs.flutter.dev/ui/adaptive-responsive/large-screens
|
|
223
|
+
- https://docs.flutter.dev/ui/adaptive-responsive/safearea-mediaquery
|
|
224
|
+
- https://docs.flutter.dev/ui/layout
|
|
225
|
+
- https://docs.flutter.dev/ui/layout/constraints
|
|
226
|
+
- https://docs.flutter.dev/ui/layout/tutorial
|
|
227
|
+
- https://docs.flutter.dev/ui/widgets/layout
|
|
228
|
+
- name: flutter-setup-declarative-routing
|
|
229
|
+
description: Configure `MaterialApp.router` using a package like `go_router`
|
|
230
|
+
for advanced URL-based navigation. Use when developing web applications or
|
|
231
|
+
mobile apps that require specific deep linking and browser history support.
|
|
232
|
+
examplePrompt: "Set up GoRouter with paths for home, details, and settings"
|
|
233
|
+
instructions: |
|
|
234
|
+
1. **Create a new Flutter application**:
|
|
235
|
+
* Use the command `flutter create <app-name>`. For example, `flutter create deeplink_cookbook`.
|
|
236
|
+
|
|
237
|
+
2. **Add the `go_router` package as a dependency**:
|
|
238
|
+
* Run `flutter pub add go_router`. The Flutter team maintains the `go_router` package, which offers a simple API for complex routing scenarios.
|
|
239
|
+
|
|
240
|
+
3. **Configure `MaterialApp.router` with a `GoRouter` object**:
|
|
241
|
+
* In your `main.dart` file, import `package:go_router/go_router.dart'` and `package:flutter/material.dart'`.
|
|
242
|
+
* Create a `GoRouter` object that defines your application's routes. This object will handle routing, including paths like '/' and '/details'.
|
|
243
|
+
* Set up your `main` function to run `MaterialApp.router` and provide it with the `routerConfig` property, which should be your `GoRouter` object.
|
|
244
|
+
* For example, you can define routes within the `GoRouter` object using `GoRoute` for different paths and their corresponding builders.
|
|
245
|
+
* Routing packages like `go_router` are declarative, meaning they will consistently display the same screen(s) when a deep link is received.
|
|
246
|
+
|
|
247
|
+
4. **Configure deep linking for specific platforms (if needed)**:
|
|
248
|
+
* **For iOS:**
|
|
249
|
+
* If using a Flutter version earlier than 3.27, manually opt-in to deep linking by adding `FlutterDeepLinkingEnabled` with a value of `YES` to `Info.plist`.
|
|
250
|
+
* If using third-party plugins for deep links (e.g., `app_links`), you should opt out of Flutter's default deep link handler by setting `FlutterDeepLinkingEnabled` to `NO` in `Info.plist`.
|
|
251
|
+
* Add associated domains by launching Xcode, selecting the top-level Runner, clicking the Runner target, and then "Signing & Capabilities". Add a new capability for "Associated Domains" and enter `applinks:<web domain>`.
|
|
252
|
+
* Open `ios/Runner/Runner.entitlements` and add the associated domain inside the `<dict>` tag.
|
|
253
|
+
* Host an `apple-app-site-association` file in your web domain, which tells the mobile browser to open your iOS app instead of the browser. This file requires your app's `appID`, formatted as `<team id>.<bundle id>`.
|
|
254
|
+
* **For Android:**
|
|
255
|
+
* Web apps read the deep link path from the URL fragment by default, using the pattern `/#/path/to/app/screen`, but this can be changed by configuring the URL strategy.
|
|
256
|
+
* To configure your Android application to handle deep links, refer to the deep linking documentation.
|
|
257
|
+
resources:
|
|
258
|
+
- https://docs.flutter.dev/cookbook/animation/page-route-animation
|
|
259
|
+
- https://docs.flutter.dev/cookbook/effects/nested-nav
|
|
260
|
+
- https://docs.flutter.dev/cookbook/navigation/named-routes
|
|
261
|
+
- https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments
|
|
262
|
+
- https://docs.flutter.dev/cookbook/navigation/navigation-basics
|
|
263
|
+
- https://docs.flutter.dev/cookbook/navigation/set-up-app-links
|
|
264
|
+
- https://docs.flutter.dev/cookbook/navigation/set-up-universal-links
|
|
265
|
+
- https://docs.flutter.dev/packages-and-plugins/using-packages
|
|
266
|
+
- https://docs.flutter.dev/platform-integration/web
|
|
267
|
+
- https://docs.flutter.dev/platform-integration/web/building
|
|
268
|
+
- https://docs.flutter.dev/platform-integration/web/embedding-flutter-web
|
|
269
|
+
- https://docs.flutter.dev/platform-integration/web/initialization
|
|
270
|
+
- https://docs.flutter.dev/release/breaking-changes/deep-links-flag-change
|
|
271
|
+
- https://docs.flutter.dev/release/breaking-changes/route-navigator-refactoring
|
|
272
|
+
- https://docs.flutter.dev/tools/devtools/deep-links
|
|
273
|
+
- https://docs.flutter.dev/ui/navigation
|
|
274
|
+
- https://docs.flutter.dev/ui/navigation/deep-linking
|
|
275
|
+
- https://docs.flutter.dev/ui/navigation/url-strategies
|
|
276
|
+
- https://pub.dev/documentation/go_router/latest/topics/Configuration-topic.html
|
|
277
|
+
- https://pub.dev/documentation/go_router/latest/topics/Deep%20linking-topic.html
|
|
278
|
+
- https://pub.dev/documentation/go_router/latest/topics/Error%20handling-topic.html
|
|
279
|
+
- https://pub.dev/documentation/go_router/latest/topics/Get%20started-topic.html
|
|
280
|
+
- https://pub.dev/documentation/go_router/latest/topics/Named%20routes-topic.html
|
|
281
|
+
- https://pub.dev/documentation/go_router/latest/topics/Navigation-topic.html
|
|
282
|
+
- https://pub.dev/documentation/go_router/latest/topics/Redirection-topic.html
|
|
283
|
+
- https://pub.dev/documentation/go_router/latest/topics/State%20restoration-topic.html
|
|
284
|
+
- https://pub.dev/documentation/go_router/latest/topics/Transition%20animations-topic.html
|
|
285
|
+
- https://pub.dev/documentation/go_router/latest/topics/Type-safe%20routes-topic.html
|
|
286
|
+
- https://pub.dev/documentation/go_router/latest/topics/Upgrading-topic.html
|
|
287
|
+
- https://pub.dev/documentation/go_router/latest/topics/Web-topic.html
|
|
288
|
+
- name: flutter-add-widget-test
|
|
289
|
+
description: Implement a component-level test using `WidgetTester` to verify
|
|
290
|
+
UI rendering and user interactions (tapping, scrolling, entering text). Use
|
|
291
|
+
when validating that a specific widget displays correct data and responds to
|
|
292
|
+
events as expected.
|
|
293
|
+
examplePrompt: "Add a widget test for the CustomButton to verify the onTap callback is called"
|
|
294
|
+
instructions: |
|
|
295
|
+
1. **Add the `flutter_test` dependency**. This dependency should be included in the `dev_dependencies` section of your `pubspec.yaml` file. If you created your Flutter project using command-line tools or a code editor, this dependency might already be present.
|
|
296
|
+
2. **Create the widget to test**. For example, you might create a widget that displays a title and a message.
|
|
297
|
+
3. **Create a `testWidgets` test**. Use the `testWidgets()` function from the `flutter_test` package to define your test. This function automatically provides a `WidgetTester` for each test case. The `WidgetTester` allows you to build and interact with widgets in the test environment.
|
|
298
|
+
4. **Build the widget using the `WidgetTester`**. Use the `pumpWidget()` method provided by `WidgetTester` to build and render your widget within the test environment. For instance, you can create an instance of `MyWidget` with specific title and message values. After the initial `pumpWidget()` call, `WidgetTester` offers additional methods like `tester.pump()` to rebuild the widget, which is useful for `StatefulWidget`s or animations where Flutter doesn't automatically rebuild after state changes in the test environment.
|
|
299
|
+
5. **Search for the widget using a `Finder`**. `Finder` classes allow you to locate widgets in the test environment. For example, you can use `find.text('Your Text')` to find a `Text` widget.
|
|
300
|
+
6. **Verify the widget using a `Matcher`**. Widget-specific `Matcher` constants help confirm whether a `Finder` successfully locates a widget or multiple widgets. For example, `findsOneWidget` can verify that a `Text` widget appears exactly once in the widget tree. You can also use `matchesGoldenFile` to verify that a widget's rendering matches a specific bitmap image (golden file testing).
|
|
301
|
+
7. **Simulate user interactions**. The `WidgetTester` provides methods for simulating interactions like entering text, tapping, and dragging.
|
|
302
|
+
* To enter text, use `enterText()`.
|
|
303
|
+
* To tap, use `tap()`.
|
|
304
|
+
* To drag, use `drag()`.
|
|
305
|
+
* To handle scrolling, the `WidgetTester` class provides the `scrollUntilVisible()` method, which scrolls until a specific widget is visible. This is useful when the height of items in a list can vary.
|
|
306
|
+
8. **Rebuild the widget tree after interactions**. Since Flutter doesn't automatically rebuild widgets in the test environment after user interactions update the app's state, you need to call `pump()` or `pumpAndSettle()` methods provided by the `WidgetTester` to ensure the widget tree is rebuilt.
|
|
307
|
+
9. **Run the tests**. Execute the tests using the command `flutter test test/widget_test.dart` from the root of your project.
|
|
308
|
+
|
|
309
|
+
A widget test (also known as a component test in other UI frameworks) aims to verify that a single widget's UI looks and interacts as expected. It involves multiple classes and requires a test environment that provides the appropriate widget lifecycle context. Widget tests are more comprehensive than unit tests because the widget being tested can receive user actions, perform layout, and instantiate child widgets. However, like unit tests, the widget test environment is a simpler implementation than a full UI system.
|
|
310
|
+
resources:
|
|
311
|
+
- https://docs.flutter.dev/app-architecture/case-study/testing
|
|
312
|
+
- https://docs.flutter.dev/cookbook/testing/integration/introduction
|
|
313
|
+
- https://docs.flutter.dev/cookbook/testing/unit/introduction
|
|
314
|
+
- https://docs.flutter.dev/cookbook/testing/widget/introduction
|
|
315
|
+
- https://docs.flutter.dev/cookbook/testing/widget/orientation
|
|
316
|
+
- https://docs.flutter.dev/cookbook/testing/widget/scrolling
|
|
317
|
+
- https://docs.flutter.dev/cookbook/testing/widget/tap-drag
|
|
318
|
+
- https://docs.flutter.dev/get-started/fundamentals/user-input
|
|
319
|
+
- https://docs.flutter.dev/release/breaking-changes/mock-platform-channels
|
|
320
|
+
- https://docs.flutter.dev/testing
|
|
321
|
+
- https://docs.flutter.dev/testing/integration-tests
|
|
322
|
+
- https://docs.flutter.dev/testing/overview
|
|
323
|
+
- https://docs.flutter.dev/testing/testing-plugins
|
|
324
|
+
- name: flutter-setup-localization
|
|
325
|
+
description: Add `flutter_localizations` and `intl` dependencies, enable
|
|
326
|
+
"generate true" in `pubspec.yaml`, and create an `l10n.yaml` configuration
|
|
327
|
+
file. Use when initializing localization support for a new Flutter project.
|
|
328
|
+
examplePrompt: "Setup localization and add English and Spanish translations"
|
|
329
|
+
instructions: |
|
|
330
|
+
1. **Add `flutter_localizations` and `intl` dependencies**:
|
|
331
|
+
* Add `flutter_localizations` and `intl` packages to your `pubspec.yaml` file. You can do this by running `$ flutter pub add flutter_localizations --sdk=flutter` and `$ flutter pub add intl:any`.
|
|
332
|
+
* The `flutter_localizations` package is a Flutter SDK package that enables the localization of ARB files and is often used with the `intl` package.
|
|
333
|
+
* After adding the packages, your `pubspec.yaml` file should include entries like:
|
|
334
|
+
```yaml
|
|
335
|
+
dependencies:
|
|
336
|
+
flutter:
|
|
337
|
+
sdk: flutter
|
|
338
|
+
flutter_localizations:
|
|
339
|
+
sdk: flutter
|
|
340
|
+
intl: any
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
* After adding a package dependency, run `flutter pub get` in your terminal to install it.
|
|
344
|
+
|
|
345
|
+
2. **Enable `generate: true` in `pubspec.yaml`**:
|
|
346
|
+
* Open your `pubspec.yaml` file.
|
|
347
|
+
* In the `flutter` section, add `generate: true`. This flag handles localization tasks.
|
|
348
|
+
* The `flutter` section in `pubspec.yaml` is specific to Flutter.
|
|
349
|
+
|
|
350
|
+
3. **Create an `l10n.yaml` configuration file**:
|
|
351
|
+
* Add a new YAML file named `l10n.yaml` to the root directory of your Flutter project.
|
|
352
|
+
* This file can be used to specify options like `synthetic-package: false` to generate localized messages directly into source files instead of a synthetic package. You can also specify `arb-dir` or `output-dir` in this file.
|
|
353
|
+
|
|
354
|
+
4. **Configure `MaterialApp` or `CupertinoApp`**:
|
|
355
|
+
* Import the `flutter_localizations` library.
|
|
356
|
+
* Specify `localizationsDelegates` and `supportedLocales` for your `MaterialApp` or `CupertinoApp`. For example:
|
|
357
|
+
```dart
|
|
358
|
+
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
359
|
+
// ...
|
|
360
|
+
return const MaterialApp(
|
|
361
|
+
title: 'Localizations Sample App',
|
|
362
|
+
localizationsDelegates: [
|
|
363
|
+
GlobalMaterialLocalizations.delegate,
|
|
364
|
+
GlobalWidgetsLocalizations.delegate,
|
|
365
|
+
GlobalCupertinoLocalizations.delegate,
|
|
366
|
+
],
|
|
367
|
+
supportedLocales: [
|
|
368
|
+
Locale('en'), // English
|
|
369
|
+
Locale('es'), // Spanish
|
|
370
|
+
],
|
|
371
|
+
home: MyHomePage(),
|
|
372
|
+
);
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
* After these steps, Material and Cupertino packages should be correctly localized in the supported locales, and widgets should adapt to localized messages and layout.
|
|
376
|
+
resources:
|
|
377
|
+
- https://docs.flutter.dev/ui/internationalization
|
|
378
|
+
- name: flutter-use-http-package
|
|
379
|
+
description: Use the `http` package to execute GET, POST, PUT, or DELETE
|
|
380
|
+
requests. Use when you need to fetch from or send data to a REST API.
|
|
381
|
+
examplePrompt: "Use the http package to fetch the list of products from the API"
|
|
382
|
+
instructions: |
|
|
383
|
+
1. **Add the `http` package as a dependency**.
|
|
384
|
+
* Run `flutter pub add http` in your terminal.
|
|
385
|
+
2. **Import the `http` package**.
|
|
386
|
+
* Add `import 'package:http/http.dart' as http;` to your Dart file.
|
|
387
|
+
3. **Configure platform-specific permissions (if deploying to Android or macOS)**.
|
|
388
|
+
* For Android, add the Internet permission to your `AndroidManifest.xml` file: `<uses-permission android:name="android.permission.INTERNET" />`.
|
|
389
|
+
* For macOS, include the network client entitlement in `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements` files: `<key>com.apple.security.network.client</key><true/>`.
|
|
390
|
+
4. **Make a network request**.
|
|
391
|
+
* The `http` package provides methods for GET, POST, PUT, and DELETE operations.
|
|
392
|
+
* For example, to make a GET request, use `http.get(Uri.parse('your_url'))`.
|
|
393
|
+
* To make a POST request, use `http.post()`.
|
|
394
|
+
* To make a PUT request, use `http.put()`.
|
|
395
|
+
* You can add authorization headers to your requests using the `headers` parameter. For example: `headers: {HttpHeaders.authorizationHeader: 'Basic your_api_token_here'}`.
|
|
396
|
+
* For POST requests, you might need to set `Content-Type` headers and encode the body as JSON.
|
|
397
|
+
5. **Handle the response**.
|
|
398
|
+
* The `http.Response` object contains the server's response.
|
|
399
|
+
* Check the `statusCode` of the response to determine success or failure (e.g., `200 OK` for success, `201 CREATED` for a successful POST).
|
|
400
|
+
* Parse the JSON response if applicable.
|
|
401
|
+
* Convert the response into a custom Dart object.
|
|
402
|
+
* Handle errors by throwing exceptions, especially for non-success status codes, to prevent indefinite loading indicators.
|
|
403
|
+
6. **Display the data with Flutter**.
|
|
404
|
+
* Use widgets like `FutureBuilder` to display data fetched asynchronously and handle loading and error states.
|
|
405
|
+
* For long-running tasks, consider showing a `ProgressIndicator` widget.
|
|
406
|
+
* For expensive computations like JSON parsing, perform them in a separate Isolate to avoid UI jank.
|
|
407
|
+
resources:
|
|
408
|
+
- https://docs.flutter.dev/cookbook/networking/authenticated-requests
|
|
409
|
+
- https://docs.flutter.dev/cookbook/networking/background-parsing
|
|
410
|
+
- https://docs.flutter.dev/cookbook/networking/delete-data
|
|
411
|
+
- https://docs.flutter.dev/cookbook/networking/fetch-data
|
|
412
|
+
- https://docs.flutter.dev/cookbook/networking/send-data
|
|
413
|
+
- https://docs.flutter.dev/cookbook/networking/update-data
|
|
414
|
+
- https://docs.flutter.dev/get-started/fundamentals/networking
|
|
415
|
+
- name: flutter-implement-json-serialization
|
|
416
|
+
description: Create model classes with `fromJson` and `toJson` methods using
|
|
417
|
+
`dart:convert`. Use when manually mapping JSON keys to class properties for
|
|
418
|
+
simple data structures.
|
|
419
|
+
examplePrompt: "Implement JSON serialization for the User model class"
|
|
420
|
+
instructions: |
|
|
421
|
+
1. **Import the `dart:convert` library**: Flutter includes a built-in `dart:convert` library that provides a straightforward JSON encoder and decoder. This library allows you to serialize JSON manually.
|
|
422
|
+
2. **Define a model class**: Create a plain model class, for example, named `User`. This class will contain the properties that correspond to your JSON structure.
|
|
423
|
+
3. **Implement a `fromJson` constructor**: Inside your model class, create a factory constructor, such as `User.fromJson()`, which takes a `Map` structure as input. This constructor is responsible for constructing a new instance of your model class from the JSON map. For example, if you receive a 200 OK response from a server, you can parse the JSON using `jsonDecode(response.body) as Map<String, dynamic>` and then pass it to your `fromJson` constructor.
|
|
424
|
+
4. **Implement a `toJson` method**: Add a `toJson()` method to your model class. This method converts an instance of your model class into a `Map`.
|
|
425
|
+
5. **Benefits of this approach**: Using model classes with `fromJson` and `toJson` methods provides type safety, autocompletion for fields, and compile-time exceptions. This helps combat issues like typos or incorrect type usage that would otherwise lead to runtime crashes.
|
|
426
|
+
6. **Considerations for `jsonDecode()`**: When using `jsonDecode()`, it returns a `dynamic` type, meaning the types of values are not known until runtime.
|
|
427
|
+
7. **Testing**: In a production application, it is important to ensure that serialization works correctly by having unit tests in place for both the `User.fromJson()` and `User.toJson()` methods.
|
|
428
|
+
resources:
|
|
429
|
+
- https://docs.flutter.dev/cookbook/networking/background-parsing
|
|
430
|
+
- https://docs.flutter.dev/cookbook/networking/fetch-data
|
|
431
|
+
- https://docs.flutter.dev/cookbook/networking/send-data
|
|
432
|
+
- https://docs.flutter.dev/cookbook/networking/update-data
|
|
433
|
+
- https://docs.flutter.dev/data-and-backend/serialization
|
|
434
|
+
- https://docs.flutter.dev/data-and-backend/serialization/json
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flutter-add-integration-test
|
|
3
|
+
description: Configures Flutter Driver for app interaction and converts MCP actions into permanent integration tests. Use when adding integration testing to a project, exploring UI components via MCP, or automating user flows with the integration_test package.
|
|
4
|
+
metadata:
|
|
5
|
+
model: models/gemini-3.1-pro-preview
|
|
6
|
+
last_modified: Tue, 21 Apr 2026 18:29:20 GMT
|
|
7
|
+
---
|
|
8
|
+
# Implementing Flutter Integration Tests
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
- [Project Setup and Dependencies](#project-setup-and-dependencies)
|
|
12
|
+
- [Interactive Exploration via MCP](#interactive-exploration-via-mcp)
|
|
13
|
+
- [Test Authoring Guidelines](#test-authoring-guidelines)
|
|
14
|
+
- [Execution and Profiling](#execution-and-profiling)
|
|
15
|
+
- [Workflow: End-to-End Integration Testing](#workflow-end-to-end-integration-testing)
|
|
16
|
+
- [Examples](#examples)
|
|
17
|
+
|
|
18
|
+
## Project Setup and Dependencies
|
|
19
|
+
|
|
20
|
+
Configure the project to support integration testing and Flutter Driver extensions.
|
|
21
|
+
|
|
22
|
+
1. Add required development dependencies to `pubspec.yaml`:
|
|
23
|
+
```bash
|
|
24
|
+
flutter pub add 'dev:integration_test:{"sdk":"flutter"}'
|
|
25
|
+
flutter pub add 'dev:flutter_test:{"sdk":"flutter"}'
|
|
26
|
+
```
|
|
27
|
+
2. Enable the Flutter Driver extension in your application entry point (typically `lib/main.dart` or a dedicated `lib/main_test.dart`):
|
|
28
|
+
- Import `package:flutter_driver/driver_extension.dart`.
|
|
29
|
+
- Call `enableFlutterDriverExtension();` before `runApp()`.
|
|
30
|
+
3. Add `Key` parameters (e.g., `ValueKey('login_button')`) to critical widgets in the application code to ensure reliable targeting during tests.
|
|
31
|
+
|
|
32
|
+
## Interactive Exploration via MCP
|
|
33
|
+
|
|
34
|
+
Use the Dart/Flutter MCP server tools to interactively explore and manipulate the application state before writing static tests.
|
|
35
|
+
|
|
36
|
+
- **Launch**: Execute `launch_app` with `target: "lib/main_test.dart"` to start the application and acquire the DTD URI.
|
|
37
|
+
- **Inspect**: Execute `get_widget_tree` to discover available `Key`s, `Text` nodes, and widget `Type`s.
|
|
38
|
+
- **Interact**: Execute `tap`, `enter_text`, and `scroll` to simulate user flows.
|
|
39
|
+
- **Wait**: Always execute `waitFor` or verify state with `get_health` when navigating or triggering animations.
|
|
40
|
+
- **Troubleshoot Unmounted Widgets**: If a widget is not found in the tree, it may be lazily loaded in a `SliverList` or `ListView`. Execute `scroll` or `scrollIntoView` to force the widget to mount before interacting with it.
|
|
41
|
+
|
|
42
|
+
## Test Authoring Guidelines
|
|
43
|
+
|
|
44
|
+
Structure integration tests using the `flutter_test` API paradigm.
|
|
45
|
+
|
|
46
|
+
- Create a dedicated `integration_test/` directory at the project root.
|
|
47
|
+
- Name all test files using the `<name>_test.dart` convention.
|
|
48
|
+
- Initialize the binding by calling `IntegrationTestWidgetsFlutterBinding.ensureInitialized();` at the start of `main()`.
|
|
49
|
+
- Load the application UI using `await tester.pumpWidget(MyApp());`.
|
|
50
|
+
- Trigger frames and wait for animations to complete using `await tester.pumpAndSettle();` after interactions like `tester.tap()`.
|
|
51
|
+
- Assert widget visibility using `expect(find.byKey(ValueKey('foo')), findsOneWidget);` or `findsNothing`.
|
|
52
|
+
- Scroll to specific off-screen widgets using `await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder);`.
|
|
53
|
+
|
|
54
|
+
**Conditional Logic for Legacy `flutter_driver`:**
|
|
55
|
+
- If maintaining or migrating legacy `flutter_driver` tests, use `driver.waitFor()`, `driver.waitForAbsent()`, `driver.tap()`, and `driver.scroll()` instead of the `WidgetTester` APIs.
|
|
56
|
+
|
|
57
|
+
## Execution and Profiling
|
|
58
|
+
|
|
59
|
+
Execute tests using the `flutter drive` command. Require a host driver script located in `test_driver/integration_test.dart` that calls `integrationDriver()`.
|
|
60
|
+
|
|
61
|
+
**Conditional Execution Targets:**
|
|
62
|
+
- **If testing on Chrome:** Launch `chromedriver --port=4444` in a separate terminal, then run:
|
|
63
|
+
`flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome`
|
|
64
|
+
- **If testing headless web:** Run with `-d web-server`.
|
|
65
|
+
- **If testing on Android (Local):** Run `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart`.
|
|
66
|
+
- **If testing on Firebase Test Lab (Android):**
|
|
67
|
+
1. Build debug APK: `flutter build apk --debug`
|
|
68
|
+
2. Build test APK: `./gradlew app:assembleAndroidTest`
|
|
69
|
+
3. Upload both APKs to the Firebase Test Lab console.
|
|
70
|
+
|
|
71
|
+
## Workflow: End-to-End Integration Testing
|
|
72
|
+
|
|
73
|
+
Copy and follow this checklist to implement and verify integration tests.
|
|
74
|
+
|
|
75
|
+
- [ ] **Task Progress: Setup**
|
|
76
|
+
- [ ] Add `integration_test` and `flutter_test` to `pubspec.yaml`.
|
|
77
|
+
- [ ] Inject `enableFlutterDriverExtension()` into the app entry point.
|
|
78
|
+
- [ ] Assign `ValueKey`s to target widgets.
|
|
79
|
+
- [ ] **Task Progress: Exploration**
|
|
80
|
+
- [ ] Run `launch_app` via MCP.
|
|
81
|
+
- [ ] Map the widget tree using `get_widget_tree`.
|
|
82
|
+
- [ ] Validate interaction paths using MCP tools (`tap`, `enter_text`).
|
|
83
|
+
- [ ] **Task Progress: Authoring**
|
|
84
|
+
- [ ] Create `integration_test/app_test.dart`.
|
|
85
|
+
- [ ] Write test cases using `WidgetTester` APIs.
|
|
86
|
+
- [ ] Create `test_driver/integration_test.dart` with `integrationDriver()`.
|
|
87
|
+
- [ ] **Task Progress: Execution & Feedback Loop**
|
|
88
|
+
- [ ] Run `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart`.
|
|
89
|
+
- [ ] **Feedback Loop**: Review test output -> If `PumpAndSettleTimedOutException` occurs, check for infinite animations -> If widget not found, add `scrollUntilVisible` -> Re-run test until passing.
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
### Standard Integration Test (`integration_test/app_test.dart`)
|
|
94
|
+
|
|
95
|
+
```dart
|
|
96
|
+
import 'package:flutter/material.dart';
|
|
97
|
+
import 'package:flutter_test/flutter_test.dart';
|
|
98
|
+
import 'package:integration_test/integration_test.dart';
|
|
99
|
+
import 'package:my_app/main.dart';
|
|
100
|
+
|
|
101
|
+
void main() {
|
|
102
|
+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
103
|
+
|
|
104
|
+
group('End-to-end test', () {
|
|
105
|
+
testWidgets('tap on the floating action button, verify counter', (tester) async {
|
|
106
|
+
// Load app widget.
|
|
107
|
+
await tester.pumpWidget(const MyApp());
|
|
108
|
+
|
|
109
|
+
// Verify the counter starts at 0.
|
|
110
|
+
expect(find.text('0'), findsOneWidget);
|
|
111
|
+
|
|
112
|
+
// Find the floating action button to tap on.
|
|
113
|
+
final fab = find.byKey(const ValueKey('increment'));
|
|
114
|
+
|
|
115
|
+
// Emulate a tap on the floating action button.
|
|
116
|
+
await tester.tap(fab);
|
|
117
|
+
|
|
118
|
+
// Trigger a frame and wait for animations.
|
|
119
|
+
await tester.pumpAndSettle();
|
|
120
|
+
|
|
121
|
+
// Verify the counter increments by 1.
|
|
122
|
+
expect(find.text('1'), findsOneWidget);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Host Driver Script (`test_driver/integration_test.dart`)
|
|
129
|
+
|
|
130
|
+
```dart
|
|
131
|
+
import 'package:integration_test/integration_test_driver.dart';
|
|
132
|
+
|
|
133
|
+
Future<void> main() => integrationDriver();
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Performance Profiling Driver Script (`test_driver/perf_driver.dart`)
|
|
137
|
+
|
|
138
|
+
Use this driver script if you wrap your test actions in `binding.traceAction()` to capture performance metrics.
|
|
139
|
+
|
|
140
|
+
```dart
|
|
141
|
+
import 'package:flutter_driver/flutter_driver.dart' as driver;
|
|
142
|
+
import 'package:integration_test/integration_test_driver.dart';
|
|
143
|
+
|
|
144
|
+
Future<void> main() {
|
|
145
|
+
return integrationDriver(
|
|
146
|
+
responseDataCallback: (data) async {
|
|
147
|
+
if (data != null) {
|
|
148
|
+
final timeline = driver.Timeline.fromJson(
|
|
149
|
+
data['scrolling_timeline'] as Map<String, dynamic>,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
final summary = driver.TimelineSummary.summarize(timeline);
|
|
153
|
+
|
|
154
|
+
await summary.writeTimelineToFile(
|
|
155
|
+
'scrolling_timeline',
|
|
156
|
+
pretty: true,
|
|
157
|
+
includeSummary: true,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|