Compatibility matrix
How klera compares to the major mobile E2E frameworks for React Native and native iOS / Android apps. Rows are graded against what an adopter actually ships against today — not what a roadmap promises.
Legend: ✅ shipped · ◐ partial / platform-limited · 🔜 deferred · ⛔ out-of-scope (not shipped by any framework on the list)
klera requires React Native New Architecture (Bridgeless / Fabric,
default since RN 0.74). Old Architecture is not supported — the
runtime probes global.RN$Bridgeless at startup and refuses to
register otherwise.
Gestures and element interaction
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
| Tap by testID / label / text | ✅ | ✅ | ✅ | ✅ |
| Long-press by element | ✅ | ✅ | ✅ | ✅ |
| Type text into input | ✅ | ✅ | ✅ | ✅ |
| Scroll | ✅ | ✅ | ✅ | ✅ |
| Swipe (direction or coordinate) | ✅ | ✅ | ✅ | ✅ |
| Tap at raw coordinate | ✅ | ✅ | ✅ | ✅ |
| Multi-touch / pinch / zoom | ✅ | ✅ | ◐ | ✅ |
| Self-healing strategy ladder | ✅ | ⛔ | ⛔ | ⛔ |
The matcher walks testID → accessibilityLabel → role + text → fuzzy text
on every step, with bounded drift recovery and a full trace per
attempt. Detox, Maestro, and Appium all couple to the first matching
strategy and fail hard when it breaks.
Assertions and introspection
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
assert visible / notVisible | ✅ | ✅ | ✅ | ✅ |
assert hasText | ✅ | ✅ | ✅ | ✅ |
| Per-step screenshot | ✅ | ✅ | ✅ | ✅ |
| Visual regression diff | ✅ | ◐ | ✅ | ◐ |
| State assertions (JS eval) | ✅ | ⛔ | ⛔ | ⛔ |
Detox image diffing requires the separate detox-snapshot-diff
plugin. klera ships pixel-diff visual regression as a first-class IR
step (visualSnapshot) with a baseline → actual → diff PNG triplet on
mismatch and configurable tolerance.
State assertions (assertJS) run a sandboxed read-only expression
against the runtime’s JS context — useful for asserting Redux state
shape or computed properties without coupling to a UI selector.
Synchronisation
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
| Animation-idle wait | ✅ | ✅ | ◐ | ⛔ |
| Network-idle wait | ✅ | ✅ | ⛔ | ⛔ |
| Flaky retry / self-heal | ✅ | ⛔ | ◐ | ⛔ |
A single waitForIdle step gates on animations + network. The
runtime owns the activity counters: Animated / LayoutAnimation / rAF
for animations; wrapped fetch / XHR / WebSocket for network. The
engine owns the timeout.
Device state
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
setOrientation | ✅ | ✅ | ✅ | ✅ |
| Clipboard get / set | ✅ | ✅ | ✅ | ✅ |
openURL deep link | ✅ | ✅ | ✅ | ✅ |
| Set location (simulator) | ✅ | ✅ | ✅ | ✅ |
| Set biometric result (simulator) | ✅ | ✅ | ✅ | ✅ |
| Camera frame injection | ⛔ | ⛔ | ⛔ | ⛔ |
| Microphone audio injection | ⛔ | ⛔ | ⛔ | ⛔ |
| Set location / biometric on device | ⛔ | ⛔ | ⛔ | ⛔ |
iOS and Android do not expose public APIs for injecting camera frames, microphone audio, or sensor streams. Apps that need to exercise those flows solve it at the application-architecture layer with a debug-build fake — the same answer Detox, Maestro, and Appium give.
System UI
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
Dismiss native Alert | ✅ | ✅ | ✅ | ✅ |
Dismiss ActionSheet | ✅ | ✅ | ✅ | ✅ |
| Dismiss soft keyboard | ✅ | ✅ | ✅ | ✅ |
| Hardware back (Android) | ✅ | ✅ | ✅ | ✅ |
| Permission prompts (simulator) | ✅ | ✅ | ✅ | ✅ |
| Permission prompts (device) | ✅ | ✅ | ◐ | ✅ |
| Permission grant (Android runtime) | ✅ | ✅ | ✅ | ✅ |
| Share sheets / pickers | 🔜 | ✅ | ◐ | ✅ |
| Cross-app / Springboard | 🔜 | ✅ | ◐ | ✅ |
App lifecycle
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
backgroundApp | ✅ | ✅ | ✅ | ✅ |
foregroundApp | ✅ | ✅ | ✅ | ✅ |
| Relaunch with launch args / URL | ✅ | ✅ | ✅ | ✅ |
| Push-notification payload | 🔜 | ✅ | ✅ | ✅ |
Authoring modes
| Mode | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
| Free-form prose flows (lead surface) | ✅ | ⛔ | ◐ | ⛔ |
| Run-time intent-drift recovery | ✅ | ⛔ | ⛔ | ⛔ |
| In-app recorder (Cmd+Shift+R) | ✅ | ⛔ | ◐ | ⛔ |
Recording mode (capture → .flow.md) | ✅ | ⛔ | ◐ | ⛔ |
| YAML steps (power-user opt-in) | ✅ | ⛔ | ✅ | ⛔ |
| Reads existing Maestro YAML flows | ✅ | ⛔ | ✅ | ⛔ |
| Code-based steps (JS / Swift) | ⛔ | ✅ | ⛔ | ✅ |
Maestro Studio surfaces prose hints during authoring, but flows
execute as committed YAML — intent isn’t preserved at run time, so
its recordings break on the first UI change. klera records via the
runtime’s existing event-synthesis layer and compiles to free-form
prose plus a .flow.json cache; recordings inherit the same drift
recovery prose flows get.
klera is declarative-only by design. Code-based steps remain the territory of Detox and Appium.
Observability and CI
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
| JSON report artefact | ✅ | ◐ | ⛔ | ✅ |
| HTML report (visual + sync) | ✅ | ⛔ | ✅ | ⛔ |
| Failure evidence capture | ✅ | ⛔ | ⛔ | ⛔ |
| Auto-triage on failure | ✅ | ⛔ | ⛔ | ⛔ |
| Cross-platform divergence (lockstep) | ✅ | ⛔ | ⛔ | ⛔ |
| Network mocking + assertions | ✅ | ◐ | ⛔ | ◐ |
| Proactive PR-time maintenance | ✅ | ⛔ | ⛔ | ⛔ |
| JUnit XML output | ✅ | ✅ | ✅ | ✅ |
| OpenTelemetry-native runs | ✅ | ⛔ | ⛔ | ⛔ |
| Watch-mode authoring | ✅ | ⛔ | ⛔ | ⛔ |
Zero-config adoption (klera init) | ✅ | ⛔ | ⛔ | ⛔ |
CI workflow scaffolds (klera ci) | ✅ | ⛔ | ⛔ | ⛔ |
| JSON Schema for editor autocomplete | ✅ | ⛔ | ⛔ | ⛔ |
| Live video recording | 🔜 | ✅ | ✅ | ✅ |
Secrets, fixtures, and BYO-LLM
| Capability | klera | Detox | Maestro | Appium |
|---|---|---|---|---|
| Data fixtures + secret refs | ✅ | ◐ | ◐ | ◐ |
| Secret redaction at every wire egress | ✅ | ⛔ | ⛔ | ⛔ |
| BYO-LLM prose authoring | ✅ | ⛔ | ◐ | ⛔ |
| Local CLI planner (claude / codex / gemini) | ✅ | ⛔ | ⛔ | ⛔ |
| MCP server for editor agents | ✅ | ⛔ | ⛔ | ⛔ |
Every framework on the list lets you reference env vars or a dotenv
loader for credentials — that’s the basic ◐ row. None of them
automatically scrubs the resolved value from snapshots, videos, or
test traces. klera redacts at every wire sink by construction:
${secret:KEY} values never leak past the process boundary, so
failure-evidence dumps, OTel spans, and reports are safe to upload
without per-CI gating.
What’s NOT supported
These rows are real gaps. If you need them today, klera isn’t the right choice yet:
- Code-based steps. No JS / Swift authoring path, and we don’t plan one. Adopters who need imperative tests stick with Detox or Appium.
- Camera / microphone / ARKit injection. No public iOS or Android API exists. Solve at the app layer with a debug-build fake.
- Set location / biometric on a physical device. Simulator-only; not a klera limitation, an OS one.
- Live video recording during runs. Tracked but no committed schedule. PNG triplets per failure step ship today; a continuous MP4 doesn’t.
- Push-notification payload injection. Tracked.
- Share sheets and Springboard cross-app interactions. Tracked.
- Hermes heap telemetry. CPU profiling ships as a read-only observability side-channel; heap inspection is deferred.
Driver selection
The engine picks a device driver per run:
- Native module (preferred). App has
@klera/native-driver-iosor@klera/native-driver-androidlinked. Requires a dev client, not Expo Go. Engine sendsdevice_actionover the existing bridge; the native module answers directly. Zero external tooling, full parity, works on simulator and device. - idb / adb fallback (Expo Go path). App has no native driver
linked, so the runtime replies
capability_unsupported. Engine falls through to Meta’sidb(iOS) oradb(Android). Simulator / emulator only; coversdismissAlertplus a subset of device state. - Sim-host driver.
xcrun simctl(iOS) oradb emu(Android) handlessetLocation,setBiometric, and relaunch with launch args / URL.
klera doctor reports which driver is active before flows run, so
surprises surface before the run, not during it.
Coming from another framework?
The Maestro-compatibility loader is a one-way bridge: klera detects Maestro-shape YAML at load time, converts to klera IR in memory, and runs it through the same Zod validator. Existing Maestro flows execute as-is; klera-only features (self-healing matcher, network mocking, parallel divergence detection, OTel-native runs, prose authoring, fixtures + secrets) require klera-shape authoring.
What “feature parity” means here
For a flow author, parity means: anything you’d write against Detox or Maestro, you can write against klera without reaching for shell scripts or out-of-band tooling. That’s the bar for the ✅ rows.
For 🔜 rows, we have a clear path but no shipped work yet — often because the demand hasn’t surfaced from real adopters. File an issue if you hit one.