Skip to main content

smix_driver/
ios.rs

1//! v6.0 c1a — iOS `Driver` impl. Pure delegation layer onto the existing
2//! `IosDriver` (renamed from `SimctlDriver`) inherent methods in lib.rs.
3//!
4//! 26 trait methods → 26 1-line delegations. No new logic.
5
6use async_trait::async_trait;
7use std::time::Duration;
8
9use smix_error::ExpectationFailure;
10use smix_input::{KeyName, SwipeDirection};
11use smix_runner_client::{IncludeScope, OcrFrame, SystemPopup, TapMode};
12use smix_screen::A11yNode;
13use smix_selector::Selector;
14
15use crate::traits::{Driver, Platform};
16use crate::{IosDriver, Orientation};
17
18#[async_trait]
19impl Driver for IosDriver {
20    fn platform(&self) -> Platform {
21        Platform::Ios
22    }
23
24    fn as_ios_driver(&self) -> Option<&IosDriver> {
25        Some(self)
26    }
27
28    /// v0.2.1 — iOS impl: mutate the wrapped `HttpRunnerClient` so every
29    /// subsequent request carries the `App-Bundle-Id` header. Runner
30    /// side rebinds `XCUIApplication(bundleIdentifier:)` per request.
31    fn set_target_bundle_id(&mut self, bundle: &str) {
32        self.runner_mut().set_target_bundle_id(bundle);
33    }
34
35    /// v0.2.1 — iOS impl: mutate the wrapped client to send
36    /// `App-Activate: true` on every request.
37    fn set_auto_activate(&mut self, activate: bool) {
38        self.runner_mut().set_auto_activate(activate);
39    }
40
41    /// v1.0 Phase A7 — iOS impl: force key-event dispatch mode on the
42    /// wrapped client. Sends `Input-Dispatch-Mode: key-events` header
43    /// on every request; runner-side dispatches via daemon key events
44    /// instead of a11y-anchored XCUIElement.typeText.
45    fn set_force_key_events(&mut self, force: bool) {
46        use smix_runner_client::InputDispatchMode;
47        if force {
48            self.runner_mut()
49                .set_input_dispatch_mode(InputDispatchMode::KeyEvents);
50        }
51    }
52
53    // === Sense ===
54
55    async fn tree(&self, include: Option<IncludeScope>) -> Result<A11yNode, ExpectationFailure> {
56        IosDriver::tree(self, include).await
57    }
58
59    async fn find(
60        &self,
61        selector: &Selector,
62        include: Option<IncludeScope>,
63    ) -> Result<bool, ExpectationFailure> {
64        IosDriver::find(self, selector, include).await
65    }
66
67    async fn find_one(
68        &self,
69        selector: &Selector,
70        include: Option<IncludeScope>,
71    ) -> Result<Option<A11yNode>, ExpectationFailure> {
72        IosDriver::find_one(self, selector, include).await
73    }
74
75    async fn find_all(
76        &self,
77        selector: &Selector,
78        include: Option<IncludeScope>,
79    ) -> Result<Vec<A11yNode>, ExpectationFailure> {
80        IosDriver::find_all(self, selector, include).await
81    }
82
83    async fn find_norm_coord(
84        &self,
85        selector: &Selector,
86    ) -> Result<Option<(f64, f64)>, ExpectationFailure> {
87        IosDriver::find_norm_coord(self, selector).await
88    }
89
90    async fn find_text_by_ocr(
91        &self,
92        text: &str,
93        locales: &[String],
94        recognition_level: &str,
95    ) -> Result<Option<OcrFrame>, ExpectationFailure> {
96        IosDriver::find_text_by_ocr(self, text, locales, recognition_level).await
97    }
98
99    async fn system_popups(
100        &self,
101        include: Option<IncludeScope>,
102    ) -> Result<Vec<SystemPopup>, ExpectationFailure> {
103        IosDriver::system_popups(self, include).await
104    }
105
106    async fn system_popup_action(
107        &self,
108        popup_id: &str,
109        button_id: &str,
110    ) -> Result<bool, ExpectationFailure> {
111        IosDriver::system_popup_action(self, popup_id, button_id).await
112    }
113
114    async fn wait_for(
115        &self,
116        selector: &Selector,
117        timeout: Duration,
118        include: Option<IncludeScope>,
119    ) -> Result<A11yNode, ExpectationFailure> {
120        IosDriver::wait_for(self, selector, timeout, include).await
121    }
122
123    // === Act ===
124
125    async fn tap(
126        &self,
127        selector: &Selector,
128        include: Option<IncludeScope>,
129    ) -> Result<(), ExpectationFailure> {
130        IosDriver::tap(self, selector, include).await
131    }
132
133    async fn tap_with_mode(
134        &self,
135        selector: &Selector,
136        mode: TapMode,
137        include: Option<IncludeScope>,
138    ) -> Result<(), ExpectationFailure> {
139        IosDriver::tap_with_mode(self, selector, mode, include).await
140    }
141
142    async fn tap_at_norm_coord(&self, nx: f64, ny: f64) -> Result<(), ExpectationFailure> {
143        IosDriver::tap_at_norm_coord(self, nx, ny).await
144    }
145
146    async fn tap_by_id(&self, id: &str) -> Result<(), ExpectationFailure> {
147        IosDriver::tap_by_id(self, id).await
148    }
149
150    async fn double_tap(
151        &self,
152        selector: &Selector,
153        include: Option<IncludeScope>,
154    ) -> Result<(), ExpectationFailure> {
155        IosDriver::double_tap(self, selector, include).await
156    }
157
158    async fn long_press(
159        &self,
160        selector: &Selector,
161        duration: Duration,
162        include: Option<IncludeScope>,
163    ) -> Result<(), ExpectationFailure> {
164        IosDriver::long_press(self, selector, duration, include).await
165    }
166
167    async fn fill(
168        &self,
169        selector: &Selector,
170        text: &str,
171        include: Option<IncludeScope>,
172    ) -> Result<(), ExpectationFailure> {
173        IosDriver::fill(self, selector, text, include).await
174    }
175
176    async fn clear(
177        &self,
178        selector: &Selector,
179        include: Option<IncludeScope>,
180    ) -> Result<(), ExpectationFailure> {
181        IosDriver::clear(self, selector, include).await
182    }
183
184    async fn press_key(&self, key: KeyName) -> Result<(), ExpectationFailure> {
185        IosDriver::press_key(self, key).await
186    }
187
188    async fn scroll(
189        &self,
190        selector: &Selector,
191        direction: SwipeDirection,
192    ) -> Result<(), ExpectationFailure> {
193        IosDriver::scroll(self, selector, direction).await
194    }
195
196    async fn swipe_once(&self, direction: SwipeDirection) -> Result<(), ExpectationFailure> {
197        IosDriver::swipe_once(self, direction).await
198    }
199
200    async fn swipe_at_norm_coord(
201        &self,
202        from: (f64, f64),
203        to: (f64, f64),
204    ) -> Result<(), ExpectationFailure> {
205        IosDriver::swipe_at_norm_coord(self, from, to).await
206    }
207
208    async fn hide_keyboard(&self) -> Result<(), ExpectationFailure> {
209        IosDriver::hide_keyboard(self).await
210    }
211
212    async fn back(&self) -> Result<(), ExpectationFailure> {
213        IosDriver::back(self).await
214    }
215
216    async fn set_orientation(&self, orientation: Orientation) -> Result<(), ExpectationFailure> {
217        IosDriver::set_orientation(self, orientation).await
218    }
219
220    async fn foreground(&self, bundle_id: &str) -> Result<(), ExpectationFailure> {
221        IosDriver::foreground(self, bundle_id).await
222    }
223
224    async fn webview_eval(&self, js: &str) -> Result<serde_json::Value, ExpectationFailure> {
225        IosDriver::webview_eval(self, js).await
226    }
227}