Mobile Testing Skill
Jest + Maestro plans from acceptance criteria - an Agent Skill that turns product AC into a test pyramid slice for Expo SDK 57 apps.
Search across all documentation pages
Jest + Maestro plans from acceptance criteria - an Agent Skill that turns product AC into a test pyramid slice for Expo SDK 57 apps.
From written acceptance criteria, produces:
jest-expo + RNTL)e2e-test profile| Input | Why |
|---|---|
| Acceptance criteria | Source of test cases |
appId / bundle ID | Maestro appId field |
| Screen/route names | Stable selectors and navigation |
testID policy | Team convention for Maestro id: taps |
| Build profile | e2e-test APK / simulator build |
| Mock boundaries | APIs, SecureStore, sensors |
*.test.ts(x) files with RNTL queries (role/label first).maestro/<journey>.yml flowsjest.setup.ts additions if neededeas.json e2e-test profile snippetnpm run test:ci, maestro test .maestro/getByRole, getByLabelText before testID (RNTL).appId exact match - bundle ID ≠ display name.Quick-reference recipe card - copy-paste ready.
Input AC (example):
- Guest can add item to cart from product list
- Cart badge shows item count
- Signed-in user sees saved address at checkoutSkill output skeleton:
// src/features/cart/cart.test.ts
import { addToCart } from "./cart-logic";
describe("addToCart", () => {
it("increments quantity for existing sku", () => {
expect(addToCart({ sku: "A1", qty: 1 }, { sku: "A1", qty: 2 })).toEqual({
sku: "A1",
qty: 3,
});
});
});// src/features/cart/CartBadge.test.tsx
import { render, screen } from "@testing-library/react-native";
import { CartBadge } from "./CartBadge";
it("shows count when items present", () => {
render(<CartBadge count={3} />);
expect(screen.getByLabelText("Cart, 3 items")).toBeTruthy();
});# .maestro/add-to-cart.yml
appId: com.example.shop
---
- launchApp
- tapOn: "Products"
- tapOn:
id: "product-tile-A1"
- tapOn: "Add to cart"
- assertVisible:
id: "cart-badge"
text: "1"npm run test:ci
maestro test .maestro/add-to-cart.ymlWhen to reach for this skill:
| AC | Layer | Artifact |
|---|---|---|
| Add to cart logic | Unit | cart-logic.test.ts |
| Badge visible | Component | CartBadge.test.tsx |
| List → detail → cart | E2E | .maestro/add-to-cart.yml |
| Saved address at checkout | Integration + E2E | mocked API test + checkout flow |
npx expo install jest-expo jest @types/jest @testing-library/react-native test-renderer --dev{
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
],
"setupFilesAfterEnv": ["<rootDir>/jest.setup.ts"]
}
}Full preset: Jest Setup for Expo.
// eas.json excerpt
{
"build": {
"e2e-test": {
"withoutCredentials": true,
"ios": { "simulator": true },
"android": { "buildType": "apk" }
}
}
}# .eas/workflows/e2e-test-android.yml
name: e2e-test-android
on:
pull_request:
branches: ["*"]
jobs:
build_android_for_e2e:
type: build
params:
platform: android
profile: e2e-test
maestro_test:
needs: [build_android_for_e2e]
type: maestro
params:
build_id: ${{ needs.build_android_for_e2e.outputs.build_id }}
flow_path: [".maestro/add-to-cart.yml"]assertVisible: "Welcome back.*"extendedWaitUntil for slow network screensUse Mobile Testing skill. SDK 57.
AC:
1. User can reset password via email link
2. Invalid code shows inline error
Deliver: Jest tests for validation + Maestro happy path only.
appId: com.example.auth. testID prefix: auth-Use Mobile Testing skill - review mode.
Existing tests attached. AC changed: cart supports quantity edit.
Diff test plan only - which Jest files to update, new Maestro flow or extend?Use Mobile Testing skill.
Add contract test stub for GET /v1/orders response shape.
Cross-link jest-expo setup. No Detox - Maestro only for E2E.- [ ] AC → test case traceability table
- [ ] Unit tests for pure logic
- [ ] RNTL component tests for visible behavior
- [ ] ≤ 2 Maestro flows for critical paths
- [ ] jest-expo preset confirmed
- [ ] appId matches app.config bundle ID
- [ ] CI command: npm run test:ci
- [ ] E2E build profile documented
- [ ] Listed AC explicitly NOT covered by E2E (with reason)Default to Maestro for SDK 57 Expo teams. Mention Detox only when AC requires native synchronization Detox excels at - see Detox E2E.
One happy path + one critical failure path maximum per feature. More belongs in Jest.
Only for small presentational components - not full screens. Prefer role/label assertions.
Stack versions: This page was written for React 19.2.3, React Native 0.86.0, and Expo SDK 57 (
expo~57.0.4).
Reviewed by Chris St. John·Last updated Jul 16, 2026