// Jackson Coxson #pragma once #include #include #include #include #include #include #include #include #include #include namespace IdeviceFFI { using WdaClientPtr = std::unique_ptr>; /// Minimal WebDriverAgent client over a single device's direct connections. /// /// `Wda::create` consumes the `Provider` argument; subsequent calls reuse the /// owned provider to open per-request sockets, matching the underlying Rust /// `WdaClient` semantics. class Wda { public: static Result create(Provider&& provider); // Builder-style configuration Result set_ports(uint16_t http, uint16_t mjpeg); Result set_timeout_ms(uint64_t ms); Result, FfiError> get_ports() const; Option session_id() const; // Status / session Result status(); Result wait_until_ready(uint64_t timeout_ms); Result start_session(Option bundle_id); Result delete_session(const std::string& session_id); // Element finding & state Result find_element(const std::string& using_, const std::string& value, Option session_id); Result, FfiError> find_elements(const std::string& using_, const std::string& value, Option session_id); Result element_attribute(const std::string& element_id, const std::string& name, Option session_id); Result element_text(const std::string& element_id, Option session_id); Result element_rect(const std::string& element_id, Option session_id); Result element_displayed(const std::string& element_id, Option session_id); Result element_enabled(const std::string& element_id, Option session_id); Result element_selected(const std::string& element_id, Option session_id); // Interaction Result click(const std::string& element_id, Option session_id); Result send_keys(const std::string& text, Option session_id); Result press_button(const std::string& name, Option session_id); Result unlock(Option session_id); Result swipe(int64_t start_x, int64_t start_y, int64_t end_x, int64_t end_y, double duration, Option session_id); Result tap(Option x, Option y, Option element_id, Option session_id); Result double_tap(Option x, Option y, Option element_id, Option session_id); Result touch_and_hold(double duration, Option x, Option y, Option element_id, Option session_id); Result scroll(Option direction, Option name, Option predicate_string, Option to_visible, Option element_id, Option session_id); // Output / app Result source(Option session_id); Result, FfiError> screenshot(Option session_id); Result window_size(Option session_id); Result viewport_rect(Option session_id); Result orientation(Option session_id); Result launch_app(const std::string& bundle_id, const std::vector& arguments, Option environment_json, Option session_id); Result activate_app(const std::string& bundle_id, Option session_id); Result terminate_app(const std::string& bundle_id, Option session_id); Result query_app_state(const std::string& bundle_id, Option session_id); Result background_app(Option seconds, Option session_id); Result is_locked(Option session_id); // RAII / moves ~Wda() noexcept = default; Wda(Wda&&) noexcept = default; Wda& operator=(Wda&&) noexcept = default; Wda(const Wda&) = delete; Wda& operator=(const Wda&) = delete; WdaClientHandle* raw() const noexcept { return handle_.get(); } static Wda adopt(WdaClientHandle* h) noexcept { return Wda(h); } private: explicit Wda(WdaClientHandle* h) noexcept : handle_(h) {} WdaClientPtr handle_{}; }; } // namespace IdeviceFFI