v0.0.4 — experimental preview
Warning
Experimental. Ennio is at an early experimental stage. APIs, package
names, internals, and behavior may change without notice between releases.
iOS only. Expect rough edges; do not rely on it for production-critical test
suites yet. The 0.0.x line is a public preview, not a stability commitment.
Second preview release. Headline: native UIKit / SwiftUI component coverage.
Every common native iOS UI piece a React Native app uses is now driven from
Ennio end-to-end, including the iOS 26 SwiftUI-hosted variants where the
legacy UIKit class is gone from the view tree.
What's new
Native component handlers (Unix-domain control socket)
All routed through a new in-app socket so the handler isn't queued behind a
busy JS thread.
| Component | Mechanism | Why |
|---|---|---|
UITabBarController (bottom tabs) |
selectedIndex via UITabBarControllerDelegate (faster path) |
iOS 26 liquid-glass tab bar takes 2 s+ when routed through CDP — socket bypass makes it ~3 ms |
UIAlertController |
walk window scenes + invoke UIAlertAction.handler |
alert lives on its own UIWindowLevelAlert window |
Header items (headerLeft / headerRight) |
existing getViewWindowFrame + HID tap |
RNScreens custom views are reachable in the tree |
UIRefreshControl pull-to-refresh |
two consecutive HID swipes | single swipe is flaky on iOS 26 simulator |
UIPickerView (@react-native-picker/picker) |
selectRow:inComponent: + delegate notify |
HID swipes against wheels are unreliable |
UISearchBar (iOS 26 SwiftUI host) |
walk for UISearchBarTextField (the surviving private text-field class) |
iOS 26 replaced UISearchBar with InlineSearchBarViewRepresentation |
UISegmentedControl |
setSelectedSegmentIndex: + UIControlEventValueChanged |
text-tap retry loop was ~14 s per tap |
UIDatePicker spinner |
multi-component picker walk | inner 3-wheel UIPickerView reachable via the same picker handler |
Runner
tap()text-only fast-paths chained in order: tab → search-bar focus → segmented → picker → alert → HIDinputText/eraseTextauto-route to native UISearchBar ops when a search field is focused- Per-flow profile summary in verbose mode (
bucket / count / total / avg / pct) - Per-step
Δcolumn in--verboselog so the slow step is obvious - HID daemon gains
key,keyrep, andtextops —eraseText: 50drops from ~8 s of subprocess spawns to ~50 ms in one gRPC call
Cross-version verified
iOS 26 (iPhone Air) full suite: 41 / 41 PASS.
iOS 18.5 (iPhone 16 Pro) native subset: 7 / 7 PASS.
Install
bun add @reactiive/ennio react-native-nitro-modules
bun add -d @reactiive/ennio-expo-pluginSame setup as v0.0.3 — add the plugin to app.json, npx expo prebuild --clean,
npx expo run:ios, write a Maestro YAML.
Limitations
- iOS only. Android scaffolding exists but no runtime.
- Metro must be running. No Metro → no Hermes Inspector → CLI errors out.
- Bridgeless / Fabric only. Old-architecture RN is not supported.
- iOS 26 SwiftUI-hosted components. The search-bar handler walks
UISearchBarTextFieldrather thanUISearchBar; if Apple migrates more
components similarly (segmented control, picker) the same workaround pattern
applies.
Inventory not yet covered
UIMenu/UIContextMenuInteraction/ zeego dropdown — out-of-process UI,
needs private accessibility-audit APIs; deferred to a separate branch.- Native
UIActionSheet(deprecated). - Apple Pay (
PKPaymentAuthorizationViewController) — system sheet, can't be
driven from the app process.
Full Changelog: v0.0.3...v0.0.4