Maestro E2E testing patterns for React Native. Use when implementing end-to-end tests.
/plugin marketplace add IvanTorresEdge/molcajete.ai/plugin install ivantorresedge-react-native-tech-stacks-js-react-native@IvanTorresEdge/molcajete.aiThis skill inherits all available tools. When active, it can use any tool Claude has access to.
This skill covers Maestro E2E testing for React Native apps.
Use this skill when:
YAML SIMPLICITY - Maestro uses simple YAML syntax for readable, maintainable tests.
# macOS/Linux
curl -Ls "https://get.maestro.mobile.dev" | bash
# Verify installation
maestro -v
__tests__/
└── e2e/
├── flows/
│ ├── login.yaml
│ └── common.yaml
├── login_flow.yaml
├── signup_flow.yaml
├── navigation_flow.yaml
└── checkout_flow.yaml
# __tests__/e2e/login_flow.yaml
appId: com.myapp
---
- launchApp
- tapOn: "Email"
- inputText: "test@example.com"
- tapOn: "Password"
- inputText: "password123"
- tapOn: "Sign In"
- assertVisible: "Welcome"
# Launch app
- launchApp
# Clear app state and launch
- launchApp:
clearState: true
# Stop app
- stopApp
# Tap by text
- tapOn: "Button Text"
# Tap by accessibility ID
- tapOn:
id: "submit-button"
# Tap by index (when multiple matches)
- tapOn:
text: "Item"
index: 0
# Long press
- longPressOn: "Delete"
# Input text
- inputText: "Hello World"
# Clear and input
- clearText
- inputText: "New Text"
# Input in specific field
- tapOn: "Email"
- inputText: "user@example.com"
# Assert element is visible
- assertVisible: "Success"
# Assert element is not visible
- assertNotVisible: "Error"
# Assert with timeout
- extendedWaitUntil:
visible: "Loaded"
timeout: 10000
# Scroll down
- scroll
# Scroll until visible
- scrollUntilVisible:
element: "Target Item"
direction: DOWN
timeout: 10000
# Scroll in element
- scroll:
element:
id: "scrollable-list"
direction: DOWN
# Swipe left (delete)
- swipe:
direction: LEFT
start: "Item to delete"
# Swipe down (refresh)
- swipe:
direction: DOWN
start:
above: "First Item"
# Wait for animation
- waitForAnimationToEnd
# Wait specific time (ms)
- wait: 2000
# Wait until visible
- extendedWaitUntil:
visible: "Element"
timeout: 5000
# Take screenshot
- takeScreenshot: screen_name
# flows/login.yaml
- tapOn: "Email"
- inputText: ${email}
- tapOn: "Password"
- inputText: ${password}
- tapOn: "Sign In"
- assertVisible: "Welcome"
# main_test.yaml
- launchApp
- runFlow:
file: flows/login.yaml
env:
email: "test@example.com"
password: "password123"
- tapOn: "Profile"
# Handle optional popups
- runFlow:
when:
visible: "Accept Cookies"
commands:
- tapOn: "Accept"
- tapOn: "Continue"
# Use environment variables
appId: ${APP_ID}
---
- launchApp
- tapOn: "Email"
- inputText: ${TEST_EMAIL}
# Run with variables
APP_ID=com.myapp TEST_EMAIL=test@test.com maestro test test.yaml
# iOS-specific
- runFlow:
when:
platform: iOS
commands:
- tapOn: "iOS Settings"
# Android-specific
- runFlow:
when:
platform: Android
commands:
- tapOn: "Android Settings"
# __tests__/e2e/login_flow.yaml
appId: com.myapp
---
- launchApp:
clearState: true
# Navigate to login
- tapOn: "Sign In"
# Enter credentials
- tapOn:
id: "email-input"
- inputText: "test@example.com"
- tapOn:
id: "password-input"
- inputText: "password123"
# Submit
- tapOn:
id: "login-button"
# Wait for navigation
- waitForAnimationToEnd
# Verify success
- assertVisible: "Welcome back"
- assertVisible: "Home"
# Take screenshot
- takeScreenshot: login_success
# __tests__/e2e/form_validation.yaml
appId: com.myapp
---
- launchApp
# Test empty submission
- tapOn: "Submit"
- assertVisible: "Email is required"
# Test invalid email
- tapOn: "Email"
- inputText: "invalid"
- tapOn: "Submit"
- assertVisible: "Invalid email"
# Test valid submission
- clearText
- inputText: "valid@example.com"
- tapOn: "Password"
- inputText: "ValidPass123!"
- tapOn: "Submit"
- assertVisible: "Success"
# __tests__/e2e/navigation_flow.yaml
appId: com.myapp
---
- launchApp
# Test tab navigation
- tapOn:
id: "tab-home"
- assertVisible: "Home Screen"
- tapOn:
id: "tab-search"
- assertVisible: "Search"
- tapOn:
id: "tab-profile"
- assertVisible: "Profile"
# Test back navigation
- tapOn: "Settings"
- assertVisible: "Settings"
- back
- assertVisible: "Profile"
# Run single test
maestro test __tests__/e2e/login_flow.yaml
# Run all tests
maestro test __tests__/e2e/
# Run on specific platform
maestro test __tests__/e2e/ --platform ios
# Generate JUnit report
maestro test __tests__/e2e/ --format junit --output results/
# .github/workflows/e2e.yml
name: E2E Tests
on: [push, pull_request]
jobs:
e2e:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
- name: Install dependencies
run: npm ci
- name: Install Maestro
run: |
curl -Ls "https://get.maestro.mobile.dev" | bash
echo "$HOME/.maestro/bin" >> $GITHUB_PATH
- name: Build app
run: npx expo prebuild && npx expo run:ios
- name: Run E2E tests
run: maestro test __tests__/e2e/
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: e2e-results
path: results/
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.