skills/e2e-testing/SKILL.md
AI-powered E2E testing for any app — Flutter, React Native, iOS, Android, Electron, Tauri, KMP, .NET MAUI. Test 8 platforms with natural language through MCP. No test code needed. Just describe what to test and the agent sees screenshots, taps elements, enters text, scrolls, and verifies UI state automatically.
npx skillsauth add ai-dashboad/flutter-skill e2e-testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Give your AI agent eyes and hands inside any running app.
flutter-skill is an MCP server that connects AI agents to running apps. The agent can see screenshots, tap elements, enter text, scroll, navigate, inspect UI trees, and verify state — all through natural language.
| Platform | Setup |
|----------|-------|
| Flutter (iOS/Android/Web) | flutter pub add flutter_skill |
| React Native | npm install flutter-skill-react-native |
| Electron | npm install flutter-skill-electron |
| iOS (Swift/UIKit) | SPM: FlutterSkillSDK |
| Android (Kotlin) | Gradle: flutter-skill-android |
| Tauri (Rust) | cargo add flutter-skill-tauri |
| KMP Desktop | Gradle dependency |
| .NET MAUI | NuGet package |
Test scorecard: 562/567 (99.1%) across all 8 platforms.
# npm (recommended)
npm install -g flutter-skill
# Homebrew
brew install ai-dashboad/flutter-skill/flutter-skill
# Or download binary from GitHub Releases
Add to your AI agent's MCP config (Claude Desktop, Cursor, Windsurf, OpenClaw, etc.):
{
"mcpServers": {
"flutter-skill": {
"command": "flutter-skill",
"args": ["server"]
}
}
}
If using OpenClaw, add to your gateway config under mcp.servers:
mcp:
servers:
flutter-skill:
command: flutter-skill
args: ["server"]
cd /path/to/your/app
flutter-skill init
Auto-detects project type and patches your app with the testing bridge.
flutter-skill launch .
Tell the agent what to test:
"Test the login flow — enter [email protected] and password123, tap Login, verify Dashboard appears"
The agent will automatically:
screenshot() → see the current screeninspect_interactive() → discover all tappable/typeable elements with semantic refstap(ref: "button:Login") → tap using stable semantic referenceenter_text(ref: "input:Email", text: "[email protected]") → type into fieldwait_for_element(key: "Dashboard") → verify navigationscreenshot() → confirm final state| Tool | Description |
|------|-------------|
| screenshot | Capture current screen as image |
| tap | Tap element by key, text, ref, or coordinates |
| enter_text | Type text into a field |
| scroll | Scroll up/down/left/right |
| swipe | Swipe gesture between points |
| long_press | Long press an element |
| drag | Drag from point A to B |
| go_back | Navigate back |
| press_key | Send keyboard key events |
| Tool | Description |
|------|-------------|
| inspect_interactive | NEW — Get all interactive elements with semantic ref IDs |
| get_elements | List all elements on screen |
| find_element | Find element by key or text |
| wait_for_element | Wait for element to appear (with timeout) |
| get_element_properties | Get detailed properties of an element |
| Tool | Description |
|------|-------------|
| set_text | Replace text in a field |
| clear_text | Clear a text field |
| get_text | Read text content |
| Tool | Description |
|------|-------------|
| get_logs | Read app logs |
| clear_logs | Clear log buffer |
inspect_interactive returns elements with stable semantic reference IDs:
button:Login → Login button
input:Email → Email text field
toggle:Dark Mode → Dark mode switch
button:Submit[1] → Second Submit button (disambiguated)
Format: {role}:{content}[{index}]
7 roles: button, input, toggle, slider, select, link, item
Use refs for reliable element targeting that survives UI changes:
tap(ref: "button:Login")
enter_text(ref: "input:Email", text: "[email protected]")
screenshot() → inspect_interactive() → tap/enter_text → screenshot() → verify
"Explore every screen of this app. Test all buttons, forms, navigation, and edge cases. Report any bugs you find."
The agent will systematically:
Quick smoke test:
"Tap every tab and screenshot each page"
Form testing:
"Fill the registration form with edge case data — emoji name, very long email, short password — and verify error messages"
Navigation:
"Test the complete user journey: sign up → create post → like → comment → delete → sign out"
Accessibility:
"Check every screen for missing labels, small tap targets, and contrast issues"
screenshot() — see before you actinspect_interactive() to discover elements — don't guess at selectorsref: selectors — more stable than text or coordinateswait_for_element() after navigation — apps need time to transitionpress_key for keyboard shortcuts — test keyboard navigationdevelopment
Control and automate Flutter applications - inspect UI, perform gestures, validate state, take screenshots, and debug. Connects AI agents to running Flutter apps via Dart VM Service Protocol.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------