@bdayadev/flutter-ultra-mcp 1.11.6 → 1.12.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.
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "flutter",
12
12
  "description": "Durable cross-platform Flutter automation via 8 specialized MCP servers, in-app mixin binding, and an optional DevTools panel. Replaces marionette_mcp and the official dart mcp-server for Claude Code.",
13
- "version": "1.11.6",
13
+ "version": "1.12.0",
14
14
  "author": {
15
15
  "name": "Bdaya-Dev",
16
16
  "url": "https://github.com/Bdaya-Dev"
@@ -23,5 +23,5 @@
23
23
  "tags": ["flutter", "dart", "mcp", "testing", "automation", "patrol", "cross-platform"]
24
24
  }
25
25
  ],
26
- "version": "1.11.6"
26
+ "version": "1.12.0"
27
27
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "flutter",
4
- "version": "1.11.6",
4
+ "version": "1.12.0",
5
5
  "description": "Durable cross-platform Flutter automation via 8 specialized MCP servers, in-app mixin binding, and an optional DevTools panel. Replaces marionette_mcp and the official dart mcp-server for Claude Code.",
6
6
  "author": {
7
7
  "name": "Bdaya-Dev",
package/.mcp.json CHANGED
@@ -27,7 +27,8 @@
27
27
  "args": ["${CLAUDE_PLUGIN_ROOT}/packages/flutter-ultra-browser/dist/bin.cjs"],
28
28
  "env": {
29
29
  "PLAYWRIGHT_BROWSERS_PATH": "${CLAUDE_PLUGIN_DATA}/browsers",
30
- "FLUTTER_ULTRA_STATE_DIR": "${CLAUDE_PLUGIN_DATA}/state"
30
+ "FLUTTER_ULTRA_STATE_DIR": "${CLAUDE_PLUGIN_DATA}/state",
31
+ "NODE_PATH": "${CLAUDE_PLUGIN_DATA}/node_modules"
31
32
  }
32
33
  },
33
34
  "flutter-ultra-native-mobile": {
@@ -4,7 +4,7 @@ description: >-
4
4
  extensions (gesture, screenshot, inspector, screencast, log collection)
5
5
  for the flutter-ultra-mcp Claude Code plugin. Composable with Sentry and
6
6
  other WidgetsFlutterBinding subclasses via the mixin form.
7
- version: 1.11.6
7
+ version: 1.12.0
8
8
  homepage: https://github.com/Bdaya-Dev/flutter-ultra-mcp
9
9
  repository: https://github.com/Bdaya-Dev/flutter-ultra-mcp
10
10
  issue_tracker: https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues
@@ -2,7 +2,7 @@ name: ultra_flutter_devtools
2
2
  description: >-
3
3
  Flutter DevTools extension showing live MCP activity for the flutter-ultra-mcp
4
4
  Claude Code plugin (sessions, recent tool calls, errors, screenshot grid).
5
- version: 1.11.6
5
+ version: 1.12.0
6
6
  homepage: https://github.com/Bdaya-Dev/flutter-ultra-mcp
7
7
  repository: https://github.com/Bdaya-Dev/flutter-ultra-mcp
8
8
  issue_tracker: https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bdayadev/flutter-ultra-mcp",
3
- "version": "1.11.6",
3
+ "version": "1.12.0",
4
4
  "description": "Flutter Ultra MCP plugin monorepo — 8 MCP servers + ultra_flutter Dart packages + skills for Claude Code.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp",
@@ -0,0 +1,75 @@
1
+ The following vendored skills are sourced from upstream repositories under
2
+ the BSD 3-Clause License. The flutter-ultra plugin itself is Apache-2.0.
3
+
4
+ ================================================================================
5
+ flutter/skills — https://github.com/flutter/skills
6
+ ================================================================================
7
+
8
+ Copyright 2026 The Flutter Authors. All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without modification,
11
+ are permitted provided that the following conditions are met:
12
+
13
+ 1. Redistributions of source code must retain the above copyright notice, this
14
+ list of conditions and the following disclaimer.
15
+
16
+ 2. Redistributions in binary form must reproduce the above copyright notice,
17
+ this list of conditions and the following disclaimer in the documentation
18
+ and/or other materials provided with the distribution.
19
+
20
+ 3. Neither the name of the copyright holder nor the names of its contributors
21
+ may be used to endorse or promote products derived from this software without
22
+ specific prior written permission.
23
+
24
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+
35
+ Skills vendored:
36
+ add-integration-test, add-widget-preview, add-widget-test,
37
+ apply-architecture-best-practices, build-responsive-layout,
38
+ fix-layout-issues, implement-json-serialization,
39
+ setup-declarative-routing, setup-localization, use-http-package
40
+
41
+ ================================================================================
42
+ dart-lang/skills — https://github.com/dart-lang/skills
43
+ ================================================================================
44
+
45
+ Copyright 2012, the Dart project authors.
46
+
47
+ Redistribution and use in source and binary forms, with or without modification,
48
+ are permitted provided that the following conditions are met:
49
+
50
+ 1. Redistributions of source code must retain the above copyright notice, this
51
+ list of conditions and the following disclaimer.
52
+
53
+ 2. Redistributions in binary form must reproduce the above copyright notice,
54
+ this list of conditions and the following disclaimer in the documentation
55
+ and/or other materials provided with the distribution.
56
+
57
+ 3. Neither the name of the copyright holder nor the names of its contributors
58
+ may be used to endorse or promote products derived from this software without
59
+ specific prior written permission.
60
+
61
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
62
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
65
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
67
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
68
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71
+
72
+ Skills vendored:
73
+ add-unit-test, build-cli-app, collect-coverage, fix-runtime-errors,
74
+ generate-test-mocks, migrate-to-checks-package, resolve-package-conflicts,
75
+ run-static-analysis, use-pattern-matching
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: 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
+ ---
5
+
6
+ # Implementing Flutter Integration Tests
7
+
8
+ ## Contents
9
+
10
+ - [Project Setup and Dependencies](#project-setup-and-dependencies)
11
+ - [Interactive Exploration via MCP](#interactive-exploration-via-mcp)
12
+ - [Test Authoring Guidelines](#test-authoring-guidelines)
13
+ - [Execution and Profiling](#execution-and-profiling)
14
+ - [Workflow: End-to-End Integration Testing](#workflow-end-to-end-integration-testing)
15
+ - [Examples](#examples)
16
+
17
+ ## Project Setup and Dependencies
18
+
19
+ Configure the project to support integration testing and Flutter Driver extensions.
20
+
21
+ 1. Add required development dependencies to `pubspec.yaml`:
22
+ ```bash
23
+ flutter pub add 'dev:integration_test:{"sdk":"flutter"}'
24
+ flutter pub add 'dev:flutter_test:{"sdk":"flutter"}'
25
+ ```
26
+ 2. Enable the Flutter Driver extension in your application entry point (typically `lib/main.dart` or a dedicated `lib/main_test.dart`):
27
+ - Import `package:flutter_driver/driver_extension.dart`.
28
+ - Call `enableFlutterDriverExtension();` before `runApp()`.
29
+ 3. Add `Key` parameters (e.g., `ValueKey('login_button')`) to critical widgets for reliable targeting.
30
+
31
+ ## Interactive Exploration via MCP
32
+
33
+ Use MCP tools to interactively explore and manipulate the application state before writing static tests.
34
+
35
+ - **Launch**: Execute `launch_app` with `target: "lib/main_test.dart"` to start the application and acquire the DTD URI.
36
+ - **Inspect**: Execute `get_widget_tree` to discover available `Key`s, `Text` nodes, and widget `Type`s.
37
+ - **Interact**: Execute `tap`, `enter_text`, and `scroll` to simulate user flows.
38
+ - **Wait**: Always execute `waitFor` or verify state with `get_health` when navigating or triggering animations.
39
+ - **Troubleshoot Unmounted Widgets**: If a widget is not found, it may be lazily loaded. Execute `scroll` or `scrollIntoView` to force the widget to mount.
40
+
41
+ ## Test Authoring Guidelines
42
+
43
+ Structure integration tests using the `flutter_test` API paradigm.
44
+
45
+ - Create a dedicated `integration_test/` directory at the project root.
46
+ - Name all test files using the `<name>_test.dart` convention.
47
+ - Initialize the binding: `IntegrationTestWidgetsFlutterBinding.ensureInitialized();`
48
+ - Load the application UI: `await tester.pumpWidget(MyApp());`
49
+ - Trigger frames: `await tester.pumpAndSettle();` after interactions.
50
+ - Assert visibility: `expect(find.byKey(ValueKey('foo')), findsOneWidget);`
51
+ - Scroll to off-screen widgets: `await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder);`
52
+
53
+ ## Execution and Profiling
54
+
55
+ Execute tests using the `flutter drive` command. Require a host driver script at `test_driver/integration_test.dart`.
56
+
57
+ - **Chrome:** Launch `chromedriver --port=4444`, then: `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome`
58
+ - **Headless web:** Run with `-d web-server`.
59
+ - **Android (Local):** `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart`
60
+
61
+ ## Workflow: End-to-End Integration Testing
62
+
63
+ - [ ] **Setup**
64
+ - [ ] Add `integration_test` and `flutter_test` to `pubspec.yaml`.
65
+ - [ ] Inject `enableFlutterDriverExtension()` into the app entry point.
66
+ - [ ] Assign `ValueKey`s to target widgets.
67
+ - [ ] **Exploration**
68
+ - [ ] Run `launch_app` via MCP.
69
+ - [ ] Map the widget tree using `get_widget_tree`.
70
+ - [ ] Validate interaction paths using MCP tools (`tap`, `enter_text`).
71
+ - [ ] **Authoring**
72
+ - [ ] Create `integration_test/app_test.dart`.
73
+ - [ ] Write test cases using `WidgetTester` APIs.
74
+ - [ ] Create `test_driver/integration_test.dart` with `integrationDriver()`.
75
+ - [ ] **Execution & Feedback Loop**
76
+ - [ ] Run `flutter drive`.
77
+ - [ ] Review output -> fix `PumpAndSettleTimedOutException` or missing widget issues -> re-run.
78
+
79
+ ## Examples
80
+
81
+ ### Standard Integration Test
82
+
83
+ ```dart
84
+ import 'package:flutter/material.dart';
85
+ import 'package:flutter_test/flutter_test.dart';
86
+ import 'package:integration_test/integration_test.dart';
87
+ import 'package:my_app/main.dart';
88
+
89
+ void main() {
90
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
91
+
92
+ group('End-to-end test', () {
93
+ testWidgets('tap on the floating action button, verify counter', (tester) async {
94
+ await tester.pumpWidget(const MyApp());
95
+ expect(find.text('0'), findsOneWidget);
96
+
97
+ final fab = find.byKey(const ValueKey('increment'));
98
+ await tester.tap(fab);
99
+ await tester.pumpAndSettle();
100
+
101
+ expect(find.text('1'), findsOneWidget);
102
+ });
103
+ });
104
+ }
105
+ ```
106
+
107
+ ### Host Driver Script
108
+
109
+ ```dart
110
+ import 'package:integration_test/integration_test_driver.dart';
111
+
112
+ Future<void> main() => integrationDriver();
113
+ ```
114
+
115
+ ## Flutter Ultra Integration
116
+
117
+ After writing the integration test, use these tools to launch the app and verify it:
118
+
119
+ - `mcp__plugin_flutter_flutter-ultra-runtime__launch_app` — Launch the app with the integration test target
120
+ - `mcp__plugin_flutter_flutter-ultra-runtime__attach` — Attach to the running app's VM Service
121
+ - `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` — Capture screenshots during test verification
122
+ - `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` — Inspect the widget tree to verify test assertions
123
+
124
+ ---
125
+
126
+ > **Attribution:** This skill is vendored from [flutter/skills](https://github.com/flutter/skills) (BSD-3-Clause).
127
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: add-unit-test
3
+ description: Write and organize unit tests for functions, methods, and classes using `package:test`. Use when creating new logic or fixing bugs to ensure code remains correct and regression-free.
4
+ ---
5
+
6
+ # Testing Dart and Flutter Applications
7
+
8
+ ## Contents
9
+
10
+ - [Structuring Test Files](#structuring-test-files)
11
+ - [Writing Tests](#writing-tests)
12
+ - [Executing Tests](#executing-tests)
13
+ - [Test Implementation Workflow](#test-implementation-workflow)
14
+ - [Examples](#examples)
15
+
16
+ ## Structuring Test Files
17
+
18
+ Organize test files to mirror the `lib` directory structure to maintain predictability.
19
+
20
+ - Place all test code within the `test` directory at the root of the package.
21
+ - Append `_test.dart` to the end of all test file names (e.g., `lib/src/utils.dart` should be tested in `test/src/utils_test.dart`).
22
+ - If writing integration tests, place them in an `integration_test` directory at the root of the package.
23
+
24
+ ## Writing Tests
25
+
26
+ Utilize `package:test` as the standard testing library for Dart applications.
27
+
28
+ - Import `package:test/test.dart` (or `package:flutter_test/flutter_test.dart` for Flutter).
29
+ - Group related tests using the `group()` function to provide shared context.
30
+ - Define individual test cases using the `test()` function.
31
+ - Validate outcomes using the `expect()` function alongside matchers (e.g., `equals()`, `isTrue`, `throwsA()`).
32
+ - Write asynchronous tests using standard `async`/`await` syntax. The test runner automatically waits for the `Future` to complete.
33
+ - Manage test setup and teardown using `setUp()` and `tearDown()` callbacks.
34
+ - If testing code that relies on dependency injection, use `package:mockito` alongside `package:test` to generate mock objects, configure fixed scenarios, and verify interactions.
35
+
36
+ ## Executing Tests
37
+
38
+ Select the appropriate test runner based on the project type and test location.
39
+
40
+ - If working on a pure Dart project, execute tests using the `dart test` command.
41
+ - If working on a Flutter project, execute tests using the `flutter test` command.
42
+ - If running integration tests, explicitly specify the directory path, as the default runner ignores it: `dart test integration_test` or `flutter test integration_test`.
43
+
44
+ ## Test Implementation Workflow
45
+
46
+ Follow this sequential workflow when implementing new test suites. Copy the checklist to track your progress.
47
+
48
+ ### Task Progress
49
+
50
+ - [ ] 1. Create the test file in the `test/` directory, ensuring the `_test.dart` suffix.
51
+ - [ ] 2. Import `package:test/test.dart` and the target library.
52
+ - [ ] 3. Define a `main()` function.
53
+ - [ ] 4. Initialize shared resources or mocks using `setUp()`.
54
+ - [ ] 5. Write `test()` cases grouped by functionality using `group()`.
55
+ - [ ] 6. Execute the test suite using the appropriate CLI command.
56
+ - [ ] 7. **Feedback Loop**: Run test -> Review stack trace for failures -> Fix implementation or assertions -> Re-run until passing.
57
+
58
+ ## Examples
59
+
60
+ ### Standard Unit Test Suite
61
+
62
+ Demonstrates grouping, setup, synchronous, and asynchronous testing.
63
+
64
+ ```dart
65
+ import 'package:test/test.dart';
66
+ import 'package:my_package/calculator.dart';
67
+
68
+ void main() {
69
+ group('Calculator', () {
70
+ late Calculator calc;
71
+
72
+ setUp(() {
73
+ calc = Calculator();
74
+ });
75
+
76
+ test('adds two numbers correctly', () {
77
+ expect(calc.add(2, 3), equals(5));
78
+ });
79
+
80
+ test('handles asynchronous operations', () async {
81
+ final result = await calc.fetchRemoteValue();
82
+ expect(result, isNotNull);
83
+ expect(result, greaterThan(0));
84
+ });
85
+ });
86
+ }
87
+ ```
88
+
89
+ ### Mocking with Mockito
90
+
91
+ Demonstrates configuring a mock object for dependency injection testing.
92
+
93
+ ```dart
94
+ import 'package:test/test.dart';
95
+ import 'package:mockito/mockito.dart';
96
+ import 'package:mockito/annotations.dart';
97
+ import 'package:my_package/api_client.dart';
98
+ import 'package:my_package/data_service.dart';
99
+
100
+ // Generate the mock using build_runner: dart run build_runner build
101
+ @GenerateNiceMocks([MockSpec<ApiClient>()])
102
+ import 'data_service_test.mocks.dart';
103
+
104
+ void main() {
105
+ group('DataService', () {
106
+ late MockApiClient mockApiClient;
107
+ late DataService dataService;
108
+
109
+ setUp(() {
110
+ mockApiClient = MockApiClient();
111
+ dataService = DataService(apiClient: mockApiClient);
112
+ });
113
+
114
+ test('returns parsed data on successful API call', () async {
115
+ // Configure the mock
116
+ when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');
117
+
118
+ // Execute the system under test
119
+ final result = await dataService.fetchData();
120
+
121
+ // Verify outcomes and interactions
122
+ expect(result.id, equals(1));
123
+ verify(mockApiClient.get('/data')).called(1);
124
+ });
125
+ });
126
+ }
127
+ ```
128
+
129
+ ## Flutter Ultra Integration
130
+
131
+ After writing the unit test, run and validate it:
132
+
133
+ - `mcp__plugin_flutter_flutter-ultra-build__start_run_unit_tests` — Execute unit tests (supports `testNamePattern` and `coverage`)
134
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_run_unit_tests` — Monitor test progress until completion
135
+ - `mcp__plugin_flutter_flutter-ultra-build__get_run_unit_tests_result` — Get detailed results with per-failure info
136
+
137
+ ---
138
+
139
+ > **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/skills) (BSD-3-Clause).
140
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: add-widget-preview
3
+ description: Adds interactive widget previews to the project using the previews.dart system. Use when creating new UI components or updating existing screens to ensure consistent design and interactive testing.
4
+ ---
5
+
6
+ # Previewing Flutter Widgets
7
+
8
+ ## Contents
9
+
10
+ - [Preview Guidelines](#preview-guidelines)
11
+ - [Handling Limitations](#handling-limitations)
12
+ - [Workflows](#workflows)
13
+ - [Examples](#examples)
14
+
15
+ ## Preview Guidelines
16
+
17
+ Use the Flutter Widget Previewer to render widgets in real-time, isolated from the full application context.
18
+
19
+ - **Target Elements:** Apply the `@Preview` annotation to top-level functions, static methods, or public widget constructors/factories that have no required arguments and return a `Widget` or `WidgetBuilder`.
20
+ - **Imports:** Always import `package:flutter/widget_previews.dart`.
21
+ - **Custom Annotations:** Extend the `Preview` class to create custom annotations that inject common properties (themes, wrappers).
22
+ - **Multiple Configurations:** Apply multiple `@Preview` annotations to generate multiple preview instances. Or extend `MultiPreview`.
23
+ - **Runtime Transformations:** Override `transform()` in custom `Preview` or `MultiPreview` classes for dynamic modification.
24
+
25
+ ## Handling Limitations
26
+
27
+ The Widget Previewer runs in a web environment:
28
+
29
+ - **No Native APIs:** Do not use `dart:io` or `dart:ffi`. Use conditional imports to mock or bypass.
30
+ - **Asset Paths:** Use package-based paths (e.g., `packages/my_package_name/assets/my_image.png`).
31
+ - **Public Callbacks:** Ensure all callback arguments are public and constant.
32
+ - **Constraints:** Apply explicit constraints using the `size` parameter if your widget is unconstrained.
33
+
34
+ ## Workflows
35
+
36
+ ### Creating a Widget Preview
37
+
38
+ - [ ] Import `package:flutter/widget_previews.dart`.
39
+ - [ ] Identify a valid target (top-level function, static method, or parameter-less constructor).
40
+ - [ ] Apply the `@Preview` annotation.
41
+ - [ ] Configure parameters (`name`, `group`, `size`, `theme`, `brightness`).
42
+ - [ ] If applying same config to multiple widgets, extract into a custom class extending `Preview`.
43
+
44
+ ### Interacting with Previews
45
+
46
+ **If using a supported IDE (Flutter 3.38+):**
47
+
48
+ 1. Launch the IDE. Widget Previewer starts automatically.
49
+ 2. Open the "Flutter Widget Preview" tab.
50
+ 3. Toggle "Filter previews by selected file" if needed.
51
+
52
+ **If using the Command Line:**
53
+
54
+ 1. Navigate to the project root.
55
+ 2. Run `flutter widget-preview start`.
56
+ 3. View in the Chrome environment.
57
+
58
+ ## Examples
59
+
60
+ ### Basic Preview
61
+
62
+ ```dart
63
+ import 'package:flutter/widget_previews.dart';
64
+ import 'package:flutter/material.dart';
65
+
66
+ @Preview(name: 'My Sample Text', group: 'Typography')
67
+ Widget mySampleText() {
68
+ return const Text('Hello, World!');
69
+ }
70
+ ```
71
+
72
+ ### MultiPreview Implementation
73
+
74
+ ```dart
75
+ import 'package:flutter/widget_previews.dart';
76
+ import 'package:flutter/material.dart';
77
+
78
+ final class MultiBrightnessPreview extends MultiPreview {
79
+ const MultiBrightnessPreview({required this.name});
80
+ final String name;
81
+
82
+ @override
83
+ List<Preview> get previews => const [
84
+ Preview(brightness: Brightness.light),
85
+ Preview(brightness: Brightness.dark),
86
+ ];
87
+
88
+ @override
89
+ List<Preview> transform() {
90
+ final previews = super.transform();
91
+ return previews.map((preview) {
92
+ final builder = preview.toBuilder()
93
+ ..group = 'Brightness'
94
+ ..name = '$name - ${preview.brightness!.name}';
95
+ return builder.toPreview();
96
+ }).toList();
97
+ }
98
+ }
99
+
100
+ @MultiBrightnessPreview(name: 'Primary Card')
101
+ Widget cardPreview() => const Card(
102
+ child: Padding(padding: EdgeInsets.all(8.0), child: Text('Content')),
103
+ );
104
+ ```
105
+
106
+ ## Flutter Ultra Integration
107
+
108
+ After adding `@Preview` annotations, use these tools to view and capture previews:
109
+
110
+ - `mcp__plugin_flutter_flutter-ultra-runtime__launch_app` — Launch the app to render previews
111
+ - `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` — Capture preview screenshots for documentation
112
+ - `mcp__plugin_flutter_flutter-ultra-build__analyze` — Verify preview annotations are syntactically correct
113
+
114
+ ---
115
+
116
+ > **Attribution:** This skill is vendored from [flutter/skills](https://github.com/flutter/skills) (BSD-3-Clause).
117
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
@@ -0,0 +1,142 @@
1
+ ---
2
+ name: add-widget-test
3
+ description: Implement a component-level test using `WidgetTester` to verify UI rendering and user interactions (tapping, scrolling, entering text). Use when validating that a specific widget displays correct data and responds to events as expected.
4
+ ---
5
+
6
+ # Writing Flutter Widget Tests
7
+
8
+ ## Contents
9
+
10
+ - [Setup & Configuration](#setup--configuration)
11
+ - [Core Components](#core-components)
12
+ - [Workflow: Implementing a Widget Test](#workflow-implementing-a-widget-test)
13
+ - [Interaction & State Management](#interaction--state-management)
14
+ - [Examples](#examples)
15
+
16
+ ## Setup & Configuration
17
+
18
+ 1. Add `flutter_test` to `dev_dependencies` in `pubspec.yaml`.
19
+ 2. Place all test files in `test/` at the project root.
20
+ 3. Suffix all test file names with `_test.dart`.
21
+
22
+ ## Core Components
23
+
24
+ - **`WidgetTester`**: Primary interface for building and interacting with widgets. Provided by `testWidgets()`.
25
+ - **`Finder`**: Locates widgets (e.g., `find.text('Submit')`, `find.byType(TextField)`, `find.byKey(Key('submit_btn'))`).
26
+ - **`Matcher`**: Verifies presence or state (e.g., `findsOneWidget`, `findsNothing`, `findsNWidgets(2)`).
27
+
28
+ ## Workflow: Implementing a Widget Test
29
+
30
+ ### Task Progress
31
+
32
+ - [ ] **Step 1:** Define the test with `testWidgets('description', (WidgetTester tester) async { ... })`.
33
+ - [ ] **Step 2:** Build the widget with `await tester.pumpWidget(MyWidget())`. Wrap in `MaterialApp` if needed.
34
+ - [ ] **Step 3:** Locate elements with `Finder` objects.
35
+ - [ ] **Step 4:** Verify initial state with `expect(finder, matcher)`.
36
+ - [ ] **Step 5:** Simulate interactions (e.g., `await tester.tap(buttonFinder)`).
37
+ - [ ] **Step 6:** Rebuild the tree with `await tester.pump()` or `await tester.pumpAndSettle()`.
38
+ - [ ] **Step 7:** Verify updated state with `expect()`.
39
+ - [ ] **Step 8:** Run with `flutter test test/your_test_file_test.dart`.
40
+ - [ ] **Step 9:** Feedback Loop: Review output -> fix assertions -> re-run.
41
+
42
+ ## Interaction & State Management
43
+
44
+ - **Static rendering:** `pumpWidget()` once, then immediately assert.
45
+ - **Standard state changes (button taps):** `tester.tap()` then `tester.pump()`.
46
+ - **Animations/transitions:** Trigger the action then `tester.pumpAndSettle()`.
47
+ - **Text input:** `await tester.enterText(textFieldFinder, 'Input string')`.
48
+ - **Long lists:** `await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder)`.
49
+
50
+ ## Examples
51
+
52
+ ### TodoList Widget Test
53
+
54
+ **Target Widget (`lib/todo_list.dart`):**
55
+
56
+ ```dart
57
+ import 'package:flutter/material.dart';
58
+
59
+ class TodoList extends StatefulWidget {
60
+ const TodoList({super.key});
61
+ @override
62
+ State<TodoList> createState() => _TodoListState();
63
+ }
64
+
65
+ class _TodoListState extends State<TodoList> {
66
+ final todos = <String>[];
67
+ final controller = TextEditingController();
68
+
69
+ @override
70
+ Widget build(BuildContext context) {
71
+ return MaterialApp(
72
+ home: Scaffold(
73
+ body: Column(
74
+ children: [
75
+ TextField(controller: controller),
76
+ Expanded(
77
+ child: ListView.builder(
78
+ itemCount: todos.length,
79
+ itemBuilder: (context, index) {
80
+ final todo = todos[index];
81
+ return Dismissible(
82
+ key: Key('$todo$index'),
83
+ onDismissed: (_) => setState(() => todos.removeAt(index)),
84
+ child: ListTile(title: Text(todo)),
85
+ );
86
+ },
87
+ ),
88
+ ),
89
+ ],
90
+ ),
91
+ floatingActionButton: FloatingActionButton(
92
+ onPressed: () {
93
+ setState(() {
94
+ todos.add(controller.text);
95
+ controller.clear();
96
+ });
97
+ },
98
+ child: const Icon(Icons.add),
99
+ ),
100
+ ),
101
+ );
102
+ }
103
+ }
104
+ ```
105
+
106
+ **Test (`test/todo_list_test.dart`):**
107
+
108
+ ```dart
109
+ import 'package:flutter/material.dart';
110
+ import 'package:flutter_test/flutter_test.dart';
111
+ import 'package:my_app/todo_list.dart';
112
+
113
+ void main() {
114
+ testWidgets('Add and remove a todo item', (WidgetTester tester) async {
115
+ await tester.pumpWidget(const TodoList());
116
+ expect(find.byType(ListTile), findsNothing);
117
+
118
+ await tester.enterText(find.byType(TextField), 'Buy groceries');
119
+ await tester.tap(find.byType(FloatingActionButton));
120
+ await tester.pump();
121
+ expect(find.text('Buy groceries'), findsOneWidget);
122
+
123
+ await tester.drag(find.byType(Dismissible), const Offset(500, 0));
124
+ await tester.pumpAndSettle();
125
+ expect(find.text('Buy groceries'), findsNothing);
126
+ });
127
+ }
128
+ ```
129
+
130
+ ## Flutter Ultra Integration
131
+
132
+ After writing the widget test, run and validate it with these tools:
133
+
134
+ - `mcp__plugin_flutter_flutter-ultra-build__start_run_widget_tests` — Execute widget tests (supports `testNamePattern` to scope)
135
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_run_widget_tests` — Monitor test progress until completion
136
+ - `mcp__plugin_flutter_flutter-ultra-build__get_run_widget_tests_result` — Get detailed results: passed, failed, skipped, per-failure info
137
+ - `mcp__plugin_flutter_flutter-ultra-build__analyze` — Static analysis before running tests
138
+
139
+ ---
140
+
141
+ > **Attribution:** This skill is vendored from [flutter/skills](https://github.com/flutter/skills) (BSD-3-Clause).
142
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.