Skip to main content

App

Struct App 

Source
pub struct App { /* private fields */ }

Implementations§

Source§

impl App

Source

pub fn new(driver: SimctlDriver, simctl: SimctlClient) -> Self

Construct from a fully-wired driver + simctl client. Use this when you already manage Cell / UDID lifecycle externally.

Back-compat constructor: still accepts SimctlDriver (alias to IosDriver) and SimctlClient; internally wraps into Box<dyn Driver> and Box::new(IosDeviceControl::with_client(...)).

Source

pub fn new_with(driver: Box<dyn Driver>, device: Box<dyn DeviceControl>) -> Self

Generic constructor for cross-platform tests. Use this when constructing with non-iOS Driver / DeviceControl impls.

Source

pub fn http_runner_client(&self) -> Option<&HttpRunnerClient>

Accessor for the underlying HTTP runner client, used by Session to drive the /session/* routes. Returns None when the driver is not backed by an HTTP runner (e.g. mock driver in tests).

Source

pub async fn open_session( self, bundle_id: &str, activate: bool, ) -> Result<Session, ExpectationFailure>

Open a runner-side session bound to bundle_id. Subsequent requests via the returned Session send the Session-Id header and skip per-request activation entirely.

activate = true causes the runner to .activate() the target once as part of the open (idiomatic when the target may not be foregrounded yet). activate = false opens a passive binding suitable when the caller has already ensured foreground state.

This is the recommended surface for long-running gates. See the Session docs for the lifecycle contract.

Source

pub async fn open_session_in_place( &mut self, bundle_id: &str, activate: bool, ) -> Result<(), ExpectationFailure>

Open a runner session in place, keeping ownership of the App. Same wire call + client mutation as Self::open_session, but does not consume self into a Session. For long-lived shared App holders (the MCP server, the real-sim harness) that drive through &App and so cannot move into a Session. After this the iOS session guard on every driving verb is satisfied (v2 break #1).

Source

pub async fn connect_to_runner(port: u16) -> Result<Self, ExpectationFailure>

Convenience: connect to a runner on 127.0.0.1:{port} and probe GET /health once. Returns App ready for sense+act calls.

Source

pub fn connect_to_runner_lazy(port: u16) -> Self

Like Self::connect_to_runner but WITHOUT the startup health probe: construction always succeeds, and a runner that is not up yet is reported by the first real call instead (every request path already tells the unreachable story with an actionable hint, and the client memoizes the probe).

This exists for hosts whose own lifecycle starts before the runner’s — the MCP server is launched by the MCP client at client startup, and dying there left a permanently dead server in every session where smix runner up came second.

Source

pub async fn connect_to_runner_android( port: u16, ) -> Result<Self, ExpectationFailure>

Connect to an Android Kotlin runner on 127.0.0.1:{port} (the host-forwarded port that proxies to the device-side runner instrumentation). Returns App ready for cross-platform sense+act calls dispatched via AndroidDriver + AndroidDeviceControl.

Source

pub fn with_udid<S: Into<String>>(self, udid: S) -> Self

Bind a UDID for lifecycle operations (launch/terminate/install/etc.).

Source

pub fn with_bundle_id<S: Into<String>>(self, bundle: S) -> Self

Thread the target bundle id down to the driver, which forwards it to the runner via the App-Bundle-Id HTTP header.

The two platforms use it for different things. iOS rebinds XCUIApplication(bundleIdentifier:) per request, so calls stay pinned to the right app even when something else briefly claims foreground. Android has nothing to rebind — /tree walks every attached window — and uses the package to spell the <pkg>:id/<tag> resource ids that Compose emits on some layouts.

Source

pub fn with_auto_activate(self, activate: bool) -> Self

Enable auto-activate on every request. The iOS runner .activate()s the resolved target before operating. Costs one XCUITest activate call per request (~50-100ms); opt-in.

iOS only. Android has no per-request activation to enable — foregrounding there is a am start shell command, which is what open_session(.., activate: true) and foreground() issue once, deliberately, rather than on every request.

Source

pub fn with_force_key_events(self, force: bool) -> Self

Force key-event dispatch mode on text-input verbs. Sends Input-Dispatch-Mode: key-events header on every request. Covers the RN hidden-input pattern where a11y-focus lookup returns nothing. Also opt-in via smix run --force-key-events.

Source

pub fn with_assert_screenshot_strict(self, strict: Option<bool>) -> Self

Inject the assert_screenshot strict-mode decision (v2 break #3). Some(true) = missing baseline is a DriverError; Some(false) = auto-record. None leaves the method on its SMIX_ASSERT_SCREENSHOT_NO_AUTORECORD env fallback. smix run always injects Some(resolved) from .smix/config.yaml.

Source

pub fn with_launch_fresh_force_reinstall(self, force: Option<bool>) -> Self

Inject the launch_fresh force-reinstall decision (v2 break #3). Some(true) = uninstall+install path; Some(false) = in-place clear. None leaves the method on its SMIX_LAUNCH_FRESH_FORCE_REINSTALL env fallback. smix run always injects Some(resolved) from .smix/config.yaml.

Source

pub fn udid(&self) -> Option<&str>

Source

pub fn driver(&self) -> &dyn Driver

Direct access to underlying Driver trait object. Use app.driver() for cross-platform calls; downcast to IosDriver only if iOS-specific behavior needed.

Source

pub fn simctl(&self) -> &SimctlClient

Back-compat &SimctlClient accessor. iOS-only. Panics on Android (use app.device() instead).

Source

pub fn device(&self) -> &dyn DeviceControl

Cross-platform sim/host control trait object.

Source

pub async fn clear_app_data(&self) -> Result<u64, ExpectationFailure>

Clear the current session’s target app data IN PLACE via cooperative XCUIApplication.terminate() + host SimctlClient sandbox wipe + cooperative XCUIApplication.launch(). Preserves XCUITest binding and does NOT signal com.apple.ReportCrash — the fix for the “ quit unexpectedly” system dialog that both simctl uninstall + install and simctl terminate + simctl spawn rm still tripped.

Requires a Session-Id set on the driver (auto-populated by smix run and by App::open_session); errors otherwise. Requires an iOS driver + UDID (SimctlClient access for the host-side wipe). Android is not supported yet — Android’s UiAutomator lifecycle differs and needs its own charter.

Source

pub async fn clear_app_data_with_launch( &self, launch_args: &[String], launch_env: &BTreeMap<String, String>, ) -> Result<u64, ExpectationFailure>

Same three-step orchestration as Self::clear_app_data, but applies caller-supplied launchArguments and launchEnvironment to the runner’s cooperative launch step. Unblocks scaffolding like the Expo SDK 57 dev-launcher server picker that clearAppData wipes from persisted state and can no longer restore via a URL Example yaml:

- clearAppData:
    launchArgs: ["-EXInternalMetroPort", "8081"]
    launchEnv:
      EX_DEV_CLIENT_METRO_URL: "http://localhost:8081"

Empty args + empty env is equivalent to Self::clear_app_data.

Source

pub async fn launch(&self, bundle_id: &str) -> Result<(), ExpectationFailure>

Source

pub async fn terminate(&self, bundle_id: &str) -> Result<(), ExpectationFailure>

Source

pub async fn install(&self, app_path: &str) -> Result<(), ExpectationFailure>

Source

pub async fn uninstall(&self, bundle_id: &str) -> Result<(), ExpectationFailure>

Source

pub async fn launch_fresh( &self, bundle_id: &str, clear_state: bool, clear_keychain: bool, app_path: Option<&str>, launch_arguments: &[String], ) -> Result<Vec<String>, ExpectationFailure>

Launch the app with optional state / keychain wipe before launch. See plan_launch_fresh_calls for the op sequence semantics. Returns the warnings produced by the planner (graceful fallback path is taken when clear_state=true but app_path is None). The caller should append these warnings to its own collector (e.g. RunReport::warnings in the maestro adapter). launch_arguments is process-level argv (simctl launch -- <args>). Empty &[] skips argv injection.

Source

pub async fn set_permission( &self, bundle_id: &str, permission: SimctlPermission, action: PermissionAction, ) -> Result<(), ExpectationFailure>

Apply a permission action to a bundle. Maps maestro yaml permissions: { camera: allow|deny|unset } to simctl privacy. Sense+act live in core; the adapter only translates maestro yaml strings to the PermissionAction enum.

Source

pub async fn launch_app_with_options( &self, opts: &LaunchAppOptions, ) -> Result<Vec<String>, ExpectationFailure>

Typed launch entry: apply permissions in declaration order, then dispatch to Self::launch_fresh (when clear_state / clear_keychain) or simctl terminate + launch_with_args (otherwise). Maps maestro yaml launchApp: { ... } in full (permissions / arguments / clearState / clearKeychain). Returns warnings emitted by launch_fresh (caller appends to its own collector).

Source

pub async fn set_animations_quiet( &self, quiet: bool, ) -> Result<(), ExpectationFailure>

Ask the device to stop animating, and refuse if it did not.

The strength differs by platform and the wording does not paper over it: Android zeroes three animation scales, which is off; iOS gets Reduce Motion, which is weaker but is as far as smix can push without the app under test cooperating. See DeviceControl::set_animations_quiet.

Source

pub async fn clear_user_defaults( &self, bundle_id: &str, keys: &[String], ) -> Result<(), ExpectationFailure>

Delete keys from the target app’s persisted user-defaults store (iOS: NSUserDefaults via simctl spawn defaults delete; Android: unsupported, explicit error). Contract is “ensure keys absent” — already-absent keys are success. Terminate the app first: a running process caches its defaults in-memory and may rewrite keys at exit.

Motivating case: expo-dev-launcher persists the most recent deep link and re-delivers it after every JS bundle load; deleting its storage key between terminate and relaunch neutralizes the replay at the source.

Source

pub async fn open_url(&self, url: &str) -> Result<(), ExpectationFailure>

Source

pub async fn send_push( &self, bundle_id: &str, apns_json_path: &str, ) -> Result<(), ExpectationFailure>

Deliver an APNS payload to bundle_id via simctl push. The payload file must contain a JSON dictionary with at least an aps key (per Apple’s spec). Mirrors maestro yaml sendPush: once that command lands upstream — there is no public maestro yaml sendPush today, so this is SDK-only surface.

Source

pub async fn screenshot(&self) -> Result<Vec<u8>, ExpectationFailure>

Source

pub async fn capture_bgra(&self) -> Result<CapturedFrame, ExpectationFailure>

Capture a frame preferring the fast raw-BGRA path (skips PNG encode+decode for diff-loop consumers). Falls back to a PNG frame when the direct IOSurface path is unavailable. See DeviceControl::capture_bgra.

Since smix 2.0.0.

Source

pub fn mark_fixture_action(&self, action_id: &str)

Register a fixture-side action anchor in the SDK ledger so that the capsule_reconcile window can attribute the kAXFirstResponderChangedNotification (1018) the fixture’s UIKit modal present is about to emit. Use this immediately before triggering a fixture-owned present path (UIActivityViewController, UIDocumentPickerViewController, SpringBoard system popup) that smix-driver would otherwise leave unattributed — without it, the phantom focus change inflates unattributed_count.

Source

pub async fn tree(&self) -> Result<A11yNode, ExpectationFailure>

Source

pub async fn describe(&self) -> Result<ScreenDescription, ExpectationFailure>

Source

pub async fn find_one( &self, selector: &Selector, ) -> Result<Option<A11yNode>, ExpectationFailure>

Source

pub async fn find_all( &self, selector: &Selector, ) -> Result<Vec<A11yNode>, ExpectationFailure>

Source

pub async fn find( &self, selector: &Selector, ) -> Result<bool, ExpectationFailure>

Source

pub async fn system_popups( &self, ) -> Result<Vec<SystemPopup>, ExpectationFailure>

Source

pub async fn system_popup_action( &self, popup_id: &str, button_id: &str, ) -> Result<bool, ExpectationFailure>

Tap a button on a previously enumerated system popup. popup_id and button_id round-trip from system_popups() — the runner walks the same scan order so callers don’t need to manage an id map. Returns Ok(true) when matched and tapped, Ok(false) when the runner returned 404 not_found (popup or button id stale). Paired with system_popups() to close the sense/act loop on iOS system popups.

Source

pub async fn tap( &self, selector: &Selector, ) -> Result<ActOutcome, ExpectationFailure>

Tap a selector, and report what the touch landed on.

Returns an outcome rather than unit. “A touch was synthesised at that coordinate” and “the element was tapped” are different claims, and this made the first while callers read the second — a consumer watched it succeed ten times against a button whose counter never moved.

The outcome carries what was aimed at, every named element containing the point afterwards, and a verdict. The elements come back even when the verdict is Confirmed, because the verdict cannot see occlusion and the list can.

Source

pub async fn tap_burst( &self, selector: &Selector, times: u32, interval_ms: Option<u32>, hold_ms: Option<u32>, ) -> Result<(), ExpectationFailure>

Tap a selector times times in a row.

One resolve and one synthesise, with the touches spaced by interval_ms on the event timeline. repeat around tapOn sends each tap as its own request, which at ~400 ms per synthesise makes a rapid-tap gesture undriveable — and leaves the interval as whatever the round trip cost, so a flow cannot tell a slow harness from a broken app.

None for either timing takes the runner’s default.

Source

pub async fn tap_with_mode( &self, selector: &Selector, mode: TapMode, ) -> Result<(), ExpectationFailure>

Tap a selector via an explicit dispatch mode. Use TapMode::DaemonProxySynthesize for RN Pressable buttons that don’t fire onPress with the default tap() Apple-native-event -chain dispatch. All other selectors should use tap(selector) (no mode) — the default host-resolve plus tap_at_norm_coord path is faster and works for non-RN-Pressable elements.

Source

pub async fn fill( &self, selector: &Selector, text: &str, ) -> Result<(), ExpectationFailure>

Source

pub async fn clear(&self, selector: &Selector) -> Result<(), ExpectationFailure>

Source

pub async fn press_key(&self, key: KeyName) -> Result<(), ExpectationFailure>

Source

pub async fn scroll( &self, selector: &Selector, direction: SwipeDirection, ) -> Result<(), ExpectationFailure>

Source

pub async fn swipe_once( &self, direction: SwipeDirection, ) -> Result<(), ExpectationFailure>

Source

pub async fn hide_keyboard(&self) -> Result<(), ExpectationFailure>

Source

pub async fn go_back(&self) -> Result<(), ExpectationFailure>

Source

pub async fn tap_at_coord( &self, nx: f64, ny: f64, ) -> Result<(), ExpectationFailure>

Tap at normalized (nx, ny) coordinates — escape hatch for coord-based maestro yaml port and other no-a11y-semantic scenarios. (nx, ny) MUST be in [0, 1] (normalized to viewport).

Escape hatch: the Selector surface still forbids xpath/coord — this method is NOT a Selector, it is the direct Apple-native-event-chain wire entry. Only tap is exposed; fill_at_coord / anchor_at_coord are intentionally NOT provided.

Prefer tap(&selector) for any path with a11y semantic. Use this only for yaml-port edge cases (e.g. maestro point: "X%,Y%").

Source

pub async fn tap_xcui(&self, id: &str) -> Result<(), ExpectationFailure>

Tap via XCUIElement.tap() over the XCTest gesture-recognizer chain instead of the default host-HID-at-coord path. The id selector is resolved runner-side via XCUIApplication.descendants(matching: .any) .matching(identifier:).firstMatch.tap().

Why this exists: SwiftUI .sheet / .alert / .confirmationDialog / .fullScreenCover dismiss buttons present in a separate modal window scene. The default tap(&selector) resolves the button frame and injects an IOKit event at that coord, but iOS routes the touch to the underlying scene’s hit-target, so SwiftUI’s onTap closure for the modal-window button never fires. XCUIElement.tap() operates on the resolved element handle and reaches the binding regardless of window topology.

Use tap(&selector) for everything else — the default path is faster and works on non-modal SwiftUI / UIKit hierarchies.

Source

pub async fn find_norm_coord( &self, selector: &Selector, ) -> Result<Option<(f64, f64)>, ExpectationFailure>

Apple Vision OCR find. Returns the matching text observation’s bounding box (UIKit normalized) or None. locales are BCP-47 language subtags; empty defaults to the SDK’s current locale (["en"] if unset). Covers “lib without testID but with visible text” scenarios.

Find a selector’s centroid as viewport-normalized (nx, ny). Used by adapter AnchorRelative dispatch. Returns None when the selector resolves no node / empty frame.

Source

pub async fn webview_eval(&self, js: &str) -> Result<Value, ExpectationFailure>

Eval JS against the app-side WKWebView bridge. Returns the JS result as a JSON Value. Bridge must be running in the target app.

Source

pub async fn find_by_text_ocr( &self, text: &str, locales: &[String], ) -> Result<Option<OcrFrame>, ExpectationFailure>

Source

pub async fn tap_by_text_ocr( &self, text: &str, locales: &[String], ) -> Result<(), ExpectationFailure>

Find by OCR + tap at frame center via IOHID synthesize. Convenience for the common OCR fallback path (OCR keyword → tap). Returns ElementNotFound when OCR finds no match.

Source

pub async fn swipe_at_coord( &self, from: (f64, f64), to: (f64, f64), ) -> Result<(), ExpectationFailure>

Swipe between two normalized coordinate points — escape hatch for coord-based maestro yaml port (swipe: { from: "X%,Y%", to: "X%,Y%" }). Both points MUST be in [0, 1].

Escape hatch: companion to Self::tap_at_coord. The Selector surface still forbids xpath/coord — this method is NOT a Selector, it is the direct Apple-native-event-chain wire entry. Only the tap and swipe coord forms are exposed; fill_at_coord / anchor_at_coord / hover_at_coord are intentionally NOT provided.

Source

pub async fn swipe_from( &self, direction: SwipeDirection, from: &Selector, ) -> Result<(), ExpectationFailure>

Swipe one gesture anchored at an element: the gesture starts from the selector’s resolved centroid instead of the viewport centre.

Composite of Self::find_norm_coord + Self::swipe_at_coord. Self::swipe_once and Self::scroll_screen always start at the viewport centre, so a caller holding an anchor element had no way to express “drag this row” — that gap is what this closes.

direction follows the same navigation convention as Self::swipe_once / Self::scroll_screen: Down advances the content downward, so the finger travels upward.

Source

pub async fn scroll_screen( &self, direction: SwipeDirection, ) -> Result<(), ExpectationFailure>

Viewport scroll one swipe in the given direction — no selector required. Maps to maestro yaml scroll: (bare, no args, defaults to down).

Implementation: a single normalized-coord swipe from the viewport center to one edge (sense+act layer). Self::scroll is the scroll-until-visible composite and is orthogonal; scroll_screen is a pure act primitive.

Source

pub async fn wait_for_not_visible( &self, selector: &Selector, timeout: Duration, ) -> Result<(), ExpectationFailure>

Assert that the selector is NOT visible. Dual of Self::assert_visible. Maps to maestro yaml assertNotVisible:.

Assertion is a core sense+assertion primitive, not an adapter-only synthesis. Uses a single non-waiting Self::find probe; if the selector matches, raise AssertionFailed. Wait until the selector is NOT visible. Dual of Self::wait_for. Polls Self::find at 250ms intervals; returns Ok the first instant the element is absent. Returns AssertionFailed if the element is still visible after timeout elapses.

The assertion+sense composite is a core platform capability, not adapter-only synthesis. Maps to maestro yaml extendedWaitUntil: { notVisible: ... , timeout: N }.

Source

pub async fn assert_screenshot( &self, baseline_path: &Path, max_hamming: u32, ) -> Result<AssertScreenshotOutcome, ExpectationFailure>

Assert the current sim screenshot matches a recorded baseline PNG via 64-bit dhash perceptual diff. Maestro assertScreenshot: <baseline-path>.

Baseline lifecycle (same as maestro):

  • Baseline missing → write the captured PNG + return Recorded { path } (auto-record default).
  • SMIX_ASSERT_SCREENSHOT_NO_AUTORECORD=1 env → strict mode: missing baseline = DriverError.
  • Baseline present → dhash(baseline) vs dhash(current) → hamming distance; ≤ max_hamming = Matched { hamming }, otherwise AssertionFailed.

max_hamming typically ≤ 10 (adapter runtime arm pins 5).

Source

pub async fn assert_not_visible( &self, selector: &Selector, ) -> Result<(), ExpectationFailure>

Source

pub async fn set_clipboard(&self, text: &str) -> Result<(), ExpectationFailure>

Write text to the iOS Simulator device pasteboard via xcrun simctl pbcopy <udid>. Maps to maestro yaml setClipboard: "literal".

Clipboard set is a core act primitive. Uses the simctl host-side path (device-scoped, explicit UDID) rather than the swift sim-side UIPasteboard wire — SimctlClient::pasteboard_set already has a stable wire, no need to add a new swift route.

Source

pub async fn get_clipboard(&self) -> Result<String, ExpectationFailure>

Read the current iOS Simulator device pasteboard via xcrun simctl pbpaste <udid>. Returns the raw string (may be empty).

Source

pub async fn paste_text( &self, text: Option<&str>, ) -> Result<(), ExpectationFailure>

Paste text into the currently-focused input field. Maps maestro yaml pasteText: "literal" (text-bearing form) and bare - pasteText (None form, reads current clipboard first).

Both forms preserve the clipboard side-effect maestro yaml users implicitly rely on (literal form writes clipboard so the post-flow pasteboard mirrors the typed text — same as native “paste from clipboard” UX).

Source

pub async fn double_tap( &self, selector: &Selector, ) -> Result<(), ExpectationFailure>

Double-tap an element. Maps to maestro yaml doubleTapOn: <selector>. Backed by XCUIElement.doubleTap() on the swift sim side.

Source

pub async fn long_press( &self, selector: &Selector, duration: Duration, ) -> Result<(), ExpectationFailure>

Long-press an element for duration. Maps to maestro yaml longPressOn (optional duration: ms, default 500 on the adapter side). Backed by XCUIElement.press(forDuration:) on the swift sim side.

Source

pub async fn long_press_capturing( &self, selector: &Selector, duration: Duration, ) -> Result<PressCapture, ExpectationFailure>

Long-press an element while capturing frames of the held state.

The two halves run on different transports on purpose. The press goes to the runner, and every runner route that touches XCUITest queues behind an in-flight gesture — a /tree sent one second into a four-second press was measured returning only after the press ended. So the frames come from simctl, which does not go through XCUITest and answers while the runner is occupied.

Each frame is judged against the interval the touch was provably down for, and frames that cannot be placed inside it say so. Handing back an unjudged frame is what this exists to stop: a consumer who screenshotted alongside a press got the resting screen and read it as “the animation never fired”.

Source

pub async fn set_location( &self, latitude: f64, longitude: f64, ) -> Result<(), ExpectationFailure>

Set sim location. Maestro setLocation: { latitude, longitude }.

Source

pub async fn travel( &self, points: &[(f64, f64)], speed_mps: Option<f64>, ) -> Result<(), ExpectationFailure>

Interpolate sim location along waypoints. Maestro travel. Fire-and-return: simctl injects scenario and returns immediately; sim continues interpolation in background. Caller must explicitly waitForAnimationToEnd / sleep if downstream logic depends on playback completion.

Source

pub async fn add_media( &self, paths: &[String], ) -> Result<(), ExpectationFailure>

Add photos / videos / contacts to the sim library. Maestro addMedia: <path> (scalar) or addMedia: [paths] (array; adapter flattens to Vec).

Source

pub async fn start_recording( &self, path: &str, ) -> Result<(), ExpectationFailure>

Start recording the sim display to path. Maestro startRecording: <path>. Spawns xcrun simctl io recordVideo as a long-running child; returns immediately. Errors if a recording is already in progress (call stop_recording first — no silent no-op).

Source

pub async fn stop_recording(&self) -> Result<(), ExpectationFailure>

Stop the active recording (SIGINT-and-wait simctl child; flushes mp4 trailer). Maestro stopRecording. Errors if no recording is active — explicit DriverError + hint, not a silent no-op.

Source

pub async fn set_orientation( &self, orientation: MaestroOrientation, ) -> Result<(), ExpectationFailure>

Rotate sim. Maestro setOrientation: portrait | portraitUpsideDown | landscapeLeft | landscapeRight. Walks driver.set_orientation → POST /set-orientation → swift XCUIDevice.shared.orientation.

Source

pub async fn set_permissions( &self, bundle_id: &str, permissions: &[(SimctlPermission, PermissionAction)], ) -> Result<(), ExpectationFailure>

Batch permission setter. Maestro setPermissions: { camera: allow, location: deny, ... } (top-level command, distinct from launchApp.permissions). Reuses set_permission per entry (sequential apply; fail-fast on first error).

Source

pub async fn copy_text_from( &self, selector: &Selector, ) -> Result<(), ExpectationFailure>

Read text content from the matched element and write it to the device pasteboard. Maps to maestro yaml copyTextFrom: <selector>. Field priority follows the maestro iOS driver: value → text → label. All three empty raises AssertionFailed — no silent no-op.

Source

pub async fn start_capsule_recording(&self) -> Result<(), ExpectationFailure>

Start Capsule recording — triggers the UITest runner EventRecorder.installSwizzle registration path (if TEST_RUNNER_SMIX_RECORD_ENABLED=1 is set in the env) and clears the SDK-internal issued-action ledger. The runner must be started with TEST_RUNNER_SMIX_RECORD_ENABLED=1; otherwise swift-side recordEnabled is false, installSwizzle is skipped, and /record/start returns 404.

Source

pub async fn stop_capsule_recording_and_reconcile( &self, window_ms: Option<u64>, ) -> Result<CapsuleReconciliation, ExpectationFailure>

Stop recording and reconcile. window_ms = None uses DEFAULT_RECONCILE_WINDOW_MS (500 ms). Returned CapsuleReconciliation includes the full unattributed_events detail.

Source

pub async fn foreground( &self, bundle_id: &str, ) -> Result<(), ExpectationFailure>

Source

pub async fn wait_for( &self, selector: &Selector, timeout: Duration, ) -> Result<A11yNode, ExpectationFailure>

Source

pub async fn assert_visible( &self, selector: &Selector, ) -> Result<(), ExpectationFailure>

Assert that the selector matches a visible element. Re-uses wait_for semantics (5s default budget) with NotVisible failure code.

Source

pub async fn assert_enabled( &self, selector: &Selector, ) -> Result<(), ExpectationFailure>

Assert that the matched element has enabled = true.

Source

pub async fn assert_text(&self, literal: &str) -> Result<(), ExpectationFailure>

Assert that the screen contains at least one element whose text / label / 6-field OR scan matches the literal. Useful for “page rendered” smoke checks without crafting a full selector tree.

Auto Trait Implementations§

§

impl !RefUnwindSafe for App

§

impl !UnwindSafe for App

§

impl Freeze for App

§

impl Send for App

§

impl Sync for App

§

impl Unpin for App

§

impl UnsafeUnpin for App

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more