Skip to content

Reference

Testing

The testing skill provides knowledge for writing and running UI test flows for React Native feature verification. Covers test runner selection, timing rules, flow structure, multi-device testing, auth pre-flight, and permission handling.

Activates when Claude encounters tasks involving Maestro tests, E2E flows, testIDs, UI test execution, network mocking, store state inspection, or test assertions.

Test Runner: maestro-runner floor (>= 1.1.24)

Section titled “Test Runner: maestro-runner floor (>= 1.1.24)”

All YAML replay uses rn-dev-agent’s tools and pin-cache maestro-runner >= 1.1.24 (attested 1.1.24 is the default known-good). Missing, older, unverified, checksum-mismatched, or unsupported runners are terminal before UI mutation; PATH, brew Maestro, and ~/.maestro-runner are never replay engines.

After any UI interaction, React needs time to commit updates to the fiber tree.

Correct sequence:

  1. device_find / Maestro tap
  2. device_snapshot / Maestro assertVisible (wait for settle)
  3. cdp_store_state (now safe to read)

Wrong (race condition): tapping then immediately querying CDP returns stale state.

Per-step timing with maestro-runner + JPEG: ~1.4s (2.2x faster than Maestro + PNG baseline of ~3.1s).

  • Basic structure: appId header + step list
  • Never use clearState: true with Expo Dev Client (wipes Metro URL)
  • Navigation via deep links or testID taps
  • Assertions: assertVisible, assertNotVisible, text content matching
  • Stable semantic names: add-to-cart-btn, cart-badge, search-input
  • Dynamic IDs for list items: testID={`product-item-${item.id}`}
  • Every Pressable, TouchableOpacity, Button, TextInput, and scrollable container must have a testID
  • Never call cdp_component_tree without a filter parameter (full dumps produce 10K+ tokens)
  • Fiber tree presence does not mean screen visibility

Before testing, check cdp_navigation_state for auth screens. If logged out, call cdp_login_prologue, which inventories and replays only the exact user-login action and requires a fresh passing RunRecord. A failed action replay returns its failure envelope unchanged and latches nothing, but the journey stops there: do not fall back to credentials, cdp_auto_login, ad-hoc Maestro, navigation shortcuts, or store mutation. The passing helper is not PR proof; lock and run the exact login e2e candidate for formal proof.

For permission-gated flows, queries and sets the correct state:

PlatformQueryGrantRevokeReset
Androiddumpsyspm grantpm revokepm reset-permissions
iOS SimNot supportedsimctl privacy grantsimctl privacy revokesimctl privacy reset

Injects mocks via cdp_evaluate using global.__RN_AGENT_MOCKS__ before navigating to the screen under test.

Zustand v4+ uses useSyncExternalStore (not React Context), so fiber tree walking cannot detect stores. Projects must register store hooks:

if (__DEV__) {
global.__ZUSTAND_STORES__ = {
auth: useAuthStore,
cart: useCartStore,
};
}

Then cdp_store_state(path="cart.items") reads the live state.