use crate::error::TransportError;
use crate::transport::Transport;
use crate::types::{Direction, Selector};
use async_trait::async_trait;
use std::collections::HashMap;
use std::sync::Mutex;
pub struct MockTransport {
visibility: Mutex<HashMap<String, bool>>,
calls: Mutex<Vec<String>>,
}
impl MockTransport {
pub fn new() -> Self {
Self {
visibility: Mutex::new(HashMap::new()),
calls: Mutex::new(Vec::new()),
}
}
pub fn set_visible(&self, key: &str, visible: bool) {
self.visibility.lock().unwrap().insert(key.into(), visible);
}
pub fn calls(&self) -> Vec<String> {
self.calls.lock().unwrap().clone()
}
fn selector_key(s: &Selector) -> String {
if let Some(t) = &s.text {
format!("text:{t}")
} else if let Some(id) = &s.id {
format!("id:{id}")
} else {
"unknown".into()
}
}
}
impl Default for MockTransport {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl Transport for MockTransport {
async fn launch_app(&self, app_id: &str, clear_state: bool) -> Result<(), TransportError> {
self.calls
.lock()
.unwrap()
.push(format!("launch_app({app_id},{clear_state})"));
Ok(())
}
async fn is_visible(&self, selector: &Selector) -> Result<bool, TransportError> {
let key = Self::selector_key(selector);
let visible = self
.visibility
.lock()
.unwrap()
.get(&key)
.copied()
.unwrap_or(false);
Ok(visible)
}
async fn tap(&self, selector: &Selector) -> Result<(), TransportError> {
self.calls
.lock()
.unwrap()
.push(format!("tap({})", Self::selector_key(selector)));
Ok(())
}
async fn input_text(&self, text: &str) -> Result<(), TransportError> {
self.calls
.lock()
.unwrap()
.push(format!("input_text({text})"));
Ok(())
}
async fn hide_keyboard(&self) -> Result<(), TransportError> {
self.calls.lock().unwrap().push("hide_keyboard".into());
Ok(())
}
async fn swipe(&self, direction: &Direction) -> Result<(), TransportError> {
self.calls
.lock()
.unwrap()
.push(format!("swipe({direction:?})"));
Ok(())
}
async fn back(&self) -> Result<(), TransportError> {
self.calls.lock().unwrap().push("back".into());
Ok(())
}
async fn wait_for_idle(&self, timeout_ms: u64) -> Result<(), TransportError> {
self.calls
.lock()
.unwrap()
.push(format!("wait_for_idle({timeout_ms})"));
Ok(())
}
async fn take_screenshot(&self, name: &str) -> Result<(), TransportError> {
self.calls
.lock()
.unwrap()
.push(format!("take_screenshot({name})"));
Ok(())
}
}