rn-devtools-hub

Hubflow scenarios

A .hubflow file is a versioned, reviewable scenario for React Native and Expo. It records actions executed inside the app runtime and events observed between them. The association is temporal: background work may appear in the same window, so review the expectations before adopting a recording as a test.

ui_act reports execution.mode and execution.nativeGesture:false. Calling a JS handler checks application logic but does not exercise native hit testing or prove that a user's touch can reach the element. Use native actions when testing touch reachability, overlays or gesture recognition.

Recorded HTTP responses with a known URL, method and status become positive assert checks with kind:"network_response". They require an observed matching response; mocks require explicit allowMocked:true, preserved when the recording captured one. The runner scopes event expectations without an explicit since to the cursor before each action. wait_for_event checks retained events after that cursor before waiting, including events emitted while the action was executing.

network_ok checks only for observed errors. An empty network window does not prove a request completed. Negative event assertions return ok:false, conclusive:false, reason:"observation-unavailable" when current capture coverage is unavailable or unknown. Older SDKs need upgrading to report crash coverage. no_crash covers captured JS errors and unhandled rejections, not native process crashes or periods before instrumentation.

Scenario files normally live under tests/hub/ and belong in Git. Run reports and screenshots live under .rn-devtools/flows/runs/ and stay local.

Record and save

start_recording  name: "checkout"
ui_act           action: "tap", by: "role", value: "button", name: "Order"
stop_recording
save_flow        path: "checkout.hubflow"

save_flow refuses an active recording and a recording that already contains a failed request or crash. The final event cursor is captured by stop_recording, so unrelated events that happen later cannot leak into the last step.

For a typed secret, pass recordAs to ui_act:

ui_act action: "type", by: "placeholder", value: "Password",
       text: "the live value", recordAs: "TEST_PASSWORD"

The live app receives the value, but the recording stores only ${TEST_PASSWORD}. Set that environment variable before replay. Recording refuses password, OTP, token and React Native secure text targets without recordAs, so those values cannot silently enter a versioned scenario.

File format

{
  "format": "rn-devtools-hub/flow",
  "version": 1,
  "name": "checkout",
  "setup": [
    {
      "tool": "freeze_time",
      "arguments": { "iso": "2026-08-29T10:00:00Z" }
    }
  ],
  "steps": [
    {
      "name": "Submit the order",
      "capture": true,
      "act": {
        "tool": "ui_act",
        "arguments": {
          "action": "tap",
          "by": "role",
          "value": "button",
          "name": "Order"
        }
      },
      "expect": [
        {
          "tool": "wait_for_event",
          "arguments": {
            "type": "screen.ready",
            "payloadContains": "Confirmation"
          }
        },
        {
          "tool": "assert",
          "arguments": {
            "kind": "no_console_error",
            "windowMs": 5000
          }
        }
      ]
    }
  ],
  "teardown": [
    { "tool": "restore_time", "arguments": {} }
  ],
  "visualEvidence": {
    "screenshots": "important-and-failure",
    "final": true
  }
}

The replay allowlist contains app-driving, assertion, deterministic state and selected native setup tools. A scenario cannot invoke another flow, modify store releases, build an app, run arbitrary commands or call an unknown tool.

Run

From an MCP client:

run_flow path: "tests/hub/checkout.hubflow"

Pass the native target returned by list_targets when screenshots are enabled. This keeps the visual proof on the same simulator or device chosen for the scenario. RN_DEVTOOLS_SCREENSHOTS=off disables Hubflow captures too.

From a terminal or CI job while the app is connected:

npx rn-devtools-hub run tests/hub/checkout.hubflow

The command exits with a nonzero status when the scenario fails. The dashboard Tests workspace can launch the same runner and shows live step progress, assertions, failure diagnosis and visual evidence.

Screenshot policy

The default important-and-failure policy saves:

Available policies are off, failure-only, important-and-failure and every-step. Captures are written to disk and never returned as image content to an agent. A missing native capture adapter is reported as an evidence error and does not turn a functionally successful scenario into a failure.

Repair a changed target

A target mismatch can include up to five bounded candidates with testID, role, accessible name and source location. The Tests workspace can create a repair candidate, or an agent can call:

propose_flow_repair path: "tests/hub/checkout.hubflow",
                    stepIndex: 1, candidateIndex: 0

The proposal is accepted only when testID, component or source file provides strong identity evidence. It writes checkout.candidate.hubflow. It never changes the original scenario, removes an assertion, changes an expected HTTP status, accepts a console error or ignores a crash.

Review and replay the candidate before replacing the original file.