flutter-skill 0.7.4
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/README.md +440 -0
- package/bin/cli.js +316 -0
- package/dart/bin/server.dart +3 -0
- package/dart/lib/flutter_skill.dart +1283 -0
- package/dart/lib/src/cli/act.dart +118 -0
- package/dart/lib/src/cli/inspect.dart +65 -0
- package/dart/lib/src/cli/launch.dart +89 -0
- package/dart/lib/src/cli/server.dart +654 -0
- package/dart/lib/src/cli/setup.dart +76 -0
- package/dart/lib/src/flutter_skill_client.dart +294 -0
- package/dart/pubspec.yaml +26 -0
- package/index.js +7 -0
- package/package.json +45 -0
- package/scripts/build.js +67 -0
- package/scripts/check-dart.js +39 -0
- package/scripts/postinstall.js +142 -0
package/README.md
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# Flutter Skill
|
|
2
|
+
|
|
3
|
+
> **AI-Powered End-to-End Testing for Flutter Apps**
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
**Flutter Skill** is an E2E testing bridge that gives AI agents (Claude Code, Cursor, Windsurf, etc.) full control over running apps across **Flutter, Web, React Native, iOS, and Android**. Describe what you want to test in natural language, and the AI sees the screen, taps buttons, fills forms, scrolls, and verifies results - just like a human tester would.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
You: "Test the login flow - enter test@example.com and password123, tap Login, verify Dashboard appears"
|
|
14
|
+
|
|
15
|
+
AI Agent:
|
|
16
|
+
1. screenshot() → sees the login screen
|
|
17
|
+
2. enter_text("email") → types the email
|
|
18
|
+
3. enter_text("password") → types the password
|
|
19
|
+
4. tap("Login") → taps the button
|
|
20
|
+
5. wait_for_element("Dashboard") → confirms navigation
|
|
21
|
+
6. screenshot() → captures the result
|
|
22
|
+
✅ Login flow verified!
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Why Flutter Skill?
|
|
26
|
+
|
|
27
|
+
| Traditional E2E Testing | Flutter Skill |
|
|
28
|
+
|------------------------|---------------|
|
|
29
|
+
| Write Dart test code manually | Describe tests in natural language |
|
|
30
|
+
| Learn WidgetTester API | AI handles the automation |
|
|
31
|
+
| Maintain brittle test scripts | AI adapts to UI changes |
|
|
32
|
+
| Debug test failures manually | AI sees screenshots and self-corrects |
|
|
33
|
+
| Setup takes hours | Setup takes 2 minutes |
|
|
34
|
+
|
|
35
|
+
**Flutter Skill is for you if:**
|
|
36
|
+
- You want E2E tests without writing test code
|
|
37
|
+
- You're using AI coding agents (Claude Code, Cursor, Windsurf)
|
|
38
|
+
- You want to automate QA workflows with natural language
|
|
39
|
+
- You need to test real app behavior on simulators/emulators
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Quick Start (2 minutes)
|
|
44
|
+
|
|
45
|
+
### 1. Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# One-click install (macOS/Linux) - recommended
|
|
49
|
+
curl -fsSL https://raw.githubusercontent.com/ai-dashboad/flutter-skill/main/install.sh | bash
|
|
50
|
+
|
|
51
|
+
# Or: npm (all platforms)
|
|
52
|
+
npm install -g flutter-skill
|
|
53
|
+
|
|
54
|
+
# Or: Homebrew (macOS/Linux)
|
|
55
|
+
brew tap ai-dashboad/flutter-skill && brew install flutter-skill
|
|
56
|
+
|
|
57
|
+
# Or: Dart
|
|
58
|
+
dart pub global activate flutter_skill
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
<details>
|
|
62
|
+
<summary>More installation methods (Windows, Docker, IDE extensions...)</summary>
|
|
63
|
+
|
|
64
|
+
| Method | Command | Platform |
|
|
65
|
+
|--------|---------|----------|
|
|
66
|
+
| **One-click** | `curl -fsSL .../install.sh \| bash` | macOS/Linux |
|
|
67
|
+
| **Windows** | `iwr .../install.ps1 -useb \| iex` | Windows |
|
|
68
|
+
| **npm** | `npm install -g flutter-skill` | All |
|
|
69
|
+
| **Homebrew** | `brew install ai-dashboad/flutter-skill/flutter-skill` | macOS/Linux |
|
|
70
|
+
| **Scoop** | `scoop install flutter-skill` | Windows |
|
|
71
|
+
| **Docker** | `docker pull ghcr.io/ai-dashboad/flutter-skill` | All |
|
|
72
|
+
| **pub.dev** | `dart pub global activate flutter_skill` | All |
|
|
73
|
+
| **VSCode** | Extensions -> "Flutter Skill" | All |
|
|
74
|
+
| **IntelliJ** | Plugins -> "Flutter Skill" | All |
|
|
75
|
+
|
|
76
|
+
</details>
|
|
77
|
+
|
|
78
|
+
### 2. Configure Your AI Agent
|
|
79
|
+
|
|
80
|
+
Add to your agent's MCP config:
|
|
81
|
+
|
|
82
|
+
**Claude Code** (`~/.claude/settings.json`):
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"mcpServers": {
|
|
86
|
+
"flutter-skill": {
|
|
87
|
+
"command": "flutter-skill",
|
|
88
|
+
"args": ["server"]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
<details>
|
|
95
|
+
<summary>Cursor, Windsurf, and other agents</summary>
|
|
96
|
+
|
|
97
|
+
**Cursor** (`~/.cursor/mcp.json`):
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"flutter-skill": {
|
|
102
|
+
"command": "flutter-skill",
|
|
103
|
+
"args": ["server"]
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Any MCP-compatible agent uses the same config format.
|
|
110
|
+
|
|
111
|
+
</details>
|
|
112
|
+
|
|
113
|
+
### 3. Add to Your Flutter App
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
# pubspec.yaml
|
|
117
|
+
dependencies:
|
|
118
|
+
flutter_skill: ^0.7.4
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```dart
|
|
122
|
+
// main.dart
|
|
123
|
+
import 'package:flutter/foundation.dart';
|
|
124
|
+
import 'package:flutter_skill/flutter_skill.dart';
|
|
125
|
+
|
|
126
|
+
void main() {
|
|
127
|
+
if (kDebugMode) {
|
|
128
|
+
FlutterSkillBinding.ensureInitialized();
|
|
129
|
+
}
|
|
130
|
+
runApp(MyApp());
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
> **Tip:** `launch_app` can auto-add this for you. The `kDebugMode` guard ensures it's stripped from release builds.
|
|
135
|
+
|
|
136
|
+
### 4. Start Testing
|
|
137
|
+
|
|
138
|
+
Just tell your AI agent what to test:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
"Launch my app on iPhone simulator, tap the Sign Up button, fill in the form, and verify the success screen"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Or use tools directly:
|
|
145
|
+
```javascript
|
|
146
|
+
flutter-skill.launch_app({ project_path: "." })
|
|
147
|
+
flutter-skill.inspect() // See all interactive elements
|
|
148
|
+
flutter-skill.tap({ text: "Sign Up" }) // Tap by text
|
|
149
|
+
flutter-skill.enter_text({ key: "email", text: "user@test.com" })
|
|
150
|
+
flutter-skill.screenshot() // Visual verification
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Multi-Platform Support
|
|
156
|
+
|
|
157
|
+
Flutter Skill isn't just for Flutter — it works with **5 platforms**, giving AI agents control over any app:
|
|
158
|
+
|
|
159
|
+
| Platform | SDK | Status |
|
|
160
|
+
|----------|-----|--------|
|
|
161
|
+
| **Flutter** (Dart) | Core — `flutter_skill` package | ✅ Stable |
|
|
162
|
+
| **Web** (JavaScript) | `sdks/web/flutter-skill.js` | ✅ Stable |
|
|
163
|
+
| **React Native** | `sdks/react-native/` npm package | ✅ Stable |
|
|
164
|
+
| **iOS** (Swift/SwiftUI) | `sdks/ios/` Swift Package | ✅ Stable |
|
|
165
|
+
| **Android** (Kotlin) | `sdks/android/` Gradle dependency | ✅ Stable |
|
|
166
|
+
|
|
167
|
+
### Web
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<script src="flutter-skill.js"></script>
|
|
171
|
+
<script>
|
|
172
|
+
FlutterSkill.start({ port: 50000 });
|
|
173
|
+
</script>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### React Native
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
npm install flutter-skill
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
import FlutterSkill from 'flutter-skill';
|
|
184
|
+
FlutterSkill.start();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### iOS (Swift / SwiftUI)
|
|
188
|
+
|
|
189
|
+
Add via Swift Package Manager:
|
|
190
|
+
```
|
|
191
|
+
https://github.com/ai-dashboad/flutter-skill (sdks/ios)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```swift
|
|
195
|
+
import FlutterSkill
|
|
196
|
+
|
|
197
|
+
// Initialize in your app
|
|
198
|
+
FlutterSkillBridge.shared.start()
|
|
199
|
+
|
|
200
|
+
// Register SwiftUI elements for AI interaction
|
|
201
|
+
Text("Hello")
|
|
202
|
+
.flutterSkillId("greeting")
|
|
203
|
+
|
|
204
|
+
Button("Submit") { submit() }
|
|
205
|
+
.flutterSkillButton("submitBtn")
|
|
206
|
+
|
|
207
|
+
TextField("Email", text: $email)
|
|
208
|
+
.flutterSkillTextField("emailField")
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Android (Kotlin)
|
|
212
|
+
|
|
213
|
+
```kotlin
|
|
214
|
+
// build.gradle.kts
|
|
215
|
+
implementation("com.flutterskill:flutter-skill:0.7.3")
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```kotlin
|
|
219
|
+
// In your Activity
|
|
220
|
+
import com.flutterskill.FlutterSkillBridge
|
|
221
|
+
|
|
222
|
+
FlutterSkillBridge.start(this)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Connecting the AI Agent
|
|
226
|
+
|
|
227
|
+
Once integrated, **the same CLI and MCP tools work for all platforms**:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
flutter_skill inspect # See all UI elements
|
|
231
|
+
flutter_skill act tap "login" # Tap a button
|
|
232
|
+
flutter_skill act enter_text "email" "user@test.com"
|
|
233
|
+
flutter_skill act screenshot # Capture the screen
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
All platforms support the same 14 capabilities: inspect, tap, enter_text, scroll, screenshot, get_text, find_element, wait_for_element, and more.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## What Can It Do?
|
|
241
|
+
|
|
242
|
+
### 40+ MCP Tools for Complete App Control
|
|
243
|
+
|
|
244
|
+
**Launch & Connect**
|
|
245
|
+
| Tool | What it does |
|
|
246
|
+
|------|-------------|
|
|
247
|
+
| `launch_app` | Launch app with dart-defines, flavors, custom targets |
|
|
248
|
+
| `scan_and_connect` | Auto-find and connect to any running Flutter app |
|
|
249
|
+
| `hot_reload` / `hot_restart` | Reload code without restarting |
|
|
250
|
+
|
|
251
|
+
**See the Screen**
|
|
252
|
+
| Tool | What it does |
|
|
253
|
+
|------|-------------|
|
|
254
|
+
| `screenshot` | Full app screenshot (configurable quality) |
|
|
255
|
+
| `screenshot_region` | Screenshot a specific area |
|
|
256
|
+
| `screenshot_element` | Screenshot a single widget |
|
|
257
|
+
| `native_screenshot` | OS-level screenshot (native dialogs, permission popups) |
|
|
258
|
+
| `inspect` | List all interactive elements with coordinates |
|
|
259
|
+
| `get_widget_tree` | Full widget tree structure |
|
|
260
|
+
| `find_by_type` | Find widgets by type (e.g., `ElevatedButton`) |
|
|
261
|
+
| `get_text_content` | Extract all visible text |
|
|
262
|
+
|
|
263
|
+
**Interact Like a User**
|
|
264
|
+
| Tool | What it does |
|
|
265
|
+
|------|-------------|
|
|
266
|
+
| `tap` | Tap by Key, text, or coordinates |
|
|
267
|
+
| `double_tap` | Double tap |
|
|
268
|
+
| `long_press` | Long press with configurable duration |
|
|
269
|
+
| `enter_text` | Type into text fields (by key or focused field) |
|
|
270
|
+
| `swipe` | Swipe gestures (up/down/left/right) |
|
|
271
|
+
| `scroll_to` | Scroll until element is visible |
|
|
272
|
+
| `drag` | Drag from one element to another |
|
|
273
|
+
| `go_back` | Navigate back |
|
|
274
|
+
| `native_tap` | Tap native UI (permission dialogs, photo pickers) |
|
|
275
|
+
| `native_input_text` | Type into native text fields |
|
|
276
|
+
| `native_swipe` | Scroll native views |
|
|
277
|
+
|
|
278
|
+
**Verify & Assert**
|
|
279
|
+
| Tool | What it does |
|
|
280
|
+
|------|-------------|
|
|
281
|
+
| `assert_text` | Verify element contains expected text |
|
|
282
|
+
| `assert_visible` | Verify element is visible |
|
|
283
|
+
| `assert_not_visible` | Verify element is gone |
|
|
284
|
+
| `assert_element_count` | Verify number of matching elements |
|
|
285
|
+
| `wait_for_element` | Wait for element to appear (with timeout) |
|
|
286
|
+
| `wait_for_gone` | Wait for element to disappear |
|
|
287
|
+
| `get_checkbox_state` | Read checkbox/switch state |
|
|
288
|
+
| `get_slider_value` | Read slider value |
|
|
289
|
+
| `get_text_value` | Read text field value |
|
|
290
|
+
|
|
291
|
+
**Debug & Monitor**
|
|
292
|
+
| Tool | What it does |
|
|
293
|
+
|------|-------------|
|
|
294
|
+
| `get_logs` | Read application logs |
|
|
295
|
+
| `get_errors` | Read application errors |
|
|
296
|
+
| `get_performance` | Performance metrics |
|
|
297
|
+
| `get_memory_stats` | Memory usage stats |
|
|
298
|
+
|
|
299
|
+
**Multi-Session**
|
|
300
|
+
| Tool | What it does |
|
|
301
|
+
|------|-------------|
|
|
302
|
+
| `list_sessions` | See all connected apps |
|
|
303
|
+
| `switch_session` | Switch between apps |
|
|
304
|
+
| `close_session` | Disconnect from an app |
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Example Workflows
|
|
309
|
+
|
|
310
|
+
### Login Flow Test
|
|
311
|
+
```
|
|
312
|
+
You: "Test login with test@example.com / password123, verify it reaches the dashboard"
|
|
313
|
+
```
|
|
314
|
+
The AI agent will:
|
|
315
|
+
1. `launch_app` or `scan_and_connect` to your app
|
|
316
|
+
2. `screenshot` to see the current screen
|
|
317
|
+
3. `enter_text(key: "email_field", text: "test@example.com")`
|
|
318
|
+
4. `enter_text(key: "password_field", text: "password123")`
|
|
319
|
+
5. `tap(text: "Login")`
|
|
320
|
+
6. `wait_for_element(text: "Dashboard")`
|
|
321
|
+
7. `screenshot` to confirm
|
|
322
|
+
|
|
323
|
+
### Form Validation Test
|
|
324
|
+
```
|
|
325
|
+
You: "Submit the registration form empty and check that all validation errors appear"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Navigation Test
|
|
329
|
+
```
|
|
330
|
+
You: "Navigate through all tabs, take a screenshot of each, and verify the back button works"
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Visual Regression
|
|
334
|
+
```
|
|
335
|
+
You: "Take screenshots of the home, profile, and settings pages - compare them with last time"
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Native Platform Support
|
|
341
|
+
|
|
342
|
+
Flutter Skill can interact with **native dialogs** that Flutter can't see (permission popups, photo pickers, share sheets):
|
|
343
|
+
|
|
344
|
+
| Tool | iOS Simulator | Android Emulator |
|
|
345
|
+
|------|--------------|-----------------|
|
|
346
|
+
| `native_screenshot` | `xcrun simctl screenshot` | `adb screencap` |
|
|
347
|
+
| `native_tap` | macOS Accessibility API | `adb input tap` |
|
|
348
|
+
| `native_input_text` | Pasteboard + Cmd+V | `adb input text` |
|
|
349
|
+
| `native_swipe` | Accessibility scroll | `adb input swipe` |
|
|
350
|
+
|
|
351
|
+
No external tools needed - works with built-in OS capabilities.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Flutter 3.x Compatibility
|
|
356
|
+
|
|
357
|
+
Flutter 3.x defaults to the DTD protocol. Flutter Skill auto-adds `--vm-service-port=50000` to ensure VM Service protocol is available. No manual configuration needed.
|
|
358
|
+
|
|
359
|
+
If you see "no VM Service URI" errors:
|
|
360
|
+
```javascript
|
|
361
|
+
// Explicitly set a port
|
|
362
|
+
flutter-skill.launch_app({
|
|
363
|
+
project_path: ".",
|
|
364
|
+
extra_args: ["--vm-service-port=50000"]
|
|
365
|
+
})
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Tool Priority Setup (Claude Code)
|
|
371
|
+
|
|
372
|
+
For Claude Code users, ensure it always uses Flutter Skill for Flutter testing:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
flutter_skill setup
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
This installs priority rules so Claude Code automatically chooses Flutter Skill over Dart MCP, giving you full UI automation (tap, screenshot, swipe) instead of read-only inspection.
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## IDE Extensions
|
|
383
|
+
|
|
384
|
+
### VSCode Extension
|
|
385
|
+
- Auto-detects Flutter projects
|
|
386
|
+
- Status bar shows connection state
|
|
387
|
+
- Commands: Launch, Inspect, Screenshot
|
|
388
|
+
|
|
389
|
+
### IntelliJ / Android Studio Plugin
|
|
390
|
+
- Same features as VSCode
|
|
391
|
+
- Integrates with IDE notifications
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Troubleshooting
|
|
396
|
+
|
|
397
|
+
### "Not connected to Flutter app"
|
|
398
|
+
```javascript
|
|
399
|
+
flutter-skill.get_connection_status() // Shows suggestions
|
|
400
|
+
flutter-skill.scan_and_connect() // Auto-find running apps
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### "Unknown method ext.flutter.flutter_skill.xxx"
|
|
404
|
+
Your app doesn't have the flutter_skill package:
|
|
405
|
+
```bash
|
|
406
|
+
flutter pub add flutter_skill
|
|
407
|
+
```
|
|
408
|
+
Then restart the app (hot reload is not enough for new packages).
|
|
409
|
+
|
|
410
|
+
### More help
|
|
411
|
+
- [Usage Guide](docs/USAGE_GUIDE.md)
|
|
412
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
413
|
+
- [Troubleshooting](docs/TROUBLESHOOTING.md)
|
|
414
|
+
- [Flutter 3.x Fix](docs/FLUTTER_3X_FIX.md)
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Links
|
|
419
|
+
|
|
420
|
+
- [GitHub](https://github.com/ai-dashboad/flutter-skill)
|
|
421
|
+
- [pub.dev](https://pub.dev/packages/flutter_skill)
|
|
422
|
+
- [npm](https://www.npmjs.com/package/flutter-skill)
|
|
423
|
+
- [VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=ai-dashboad.flutter-skill)
|
|
424
|
+
- [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/29991-flutter-skill)
|
|
425
|
+
- [Roadmap](docs/ROADMAP.md)
|
|
426
|
+
|
|
427
|
+
## Support This Project
|
|
428
|
+
|
|
429
|
+
If Flutter Skill helps you build better Flutter apps, consider supporting its development:
|
|
430
|
+
|
|
431
|
+
- [GitHub Sponsors](https://github.com/sponsors/ai-dashboad)
|
|
432
|
+
- [Buy Me a Coffee](https://buymeacoffee.com/ai-dashboad)
|
|
433
|
+
|
|
434
|
+
Your support helps maintain the project, add new features, and keep it free and open source.
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## License
|
|
439
|
+
|
|
440
|
+
MIT
|