marionette: Separate commands from connection
The `MarionetteConnection` structure provides the low-level interface to communicate with the Marionette server via the TCP socket. In contrast, the `Marionette` structure provides the high-level interface to execute Marionette commands. Separating these will make the code a bit cleaner, in my opinion.dev/ci
parent
3b1be2d01c
commit
8431a33f20
|
@ -37,13 +37,13 @@ type CommandResult = Result<Option<serde_json::Value>, ErrorResponse>;
|
||||||
|
|
||||||
type SenderMap = HashMap<u32, oneshot::Sender<CommandResult>>;
|
type SenderMap = HashMap<u32, oneshot::Sender<CommandResult>>;
|
||||||
|
|
||||||
pub struct Marionette {
|
pub struct MarionetteConnection {
|
||||||
ts: Instant,
|
ts: Instant,
|
||||||
stream: BufWriter<OwnedWriteHalf>,
|
stream: BufWriter<OwnedWriteHalf>,
|
||||||
sender: Arc<Mutex<SenderMap>>,
|
sender: Arc<Mutex<SenderMap>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Marionette {
|
impl MarionetteConnection {
|
||||||
pub async fn connect<A>(addr: A) -> Result<Self, ConnectionError>
|
pub async fn connect<A>(addr: A) -> Result<Self, ConnectionError>
|
||||||
where
|
where
|
||||||
A: ToSocketAddrs,
|
A: ToSocketAddrs,
|
||||||
|
@ -61,39 +61,6 @@ impl Marionette {
|
||||||
Ok(Self { ts, stream, sender })
|
Ok(Self { ts, stream, sender })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_title(&mut self) -> Result<String, CommandError> {
|
|
||||||
let res: GetTitleResponse =
|
|
||||||
self.send_message(Command::GetTitle).await?.unwrap();
|
|
||||||
debug!("Received message: {:?}", res);
|
|
||||||
Ok(res.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn navigate<U>(&mut self, url: U) -> Result<(), CommandError>
|
|
||||||
where
|
|
||||||
U: Into<String>,
|
|
||||||
{
|
|
||||||
let res: Option<serde_json::Value> = self
|
|
||||||
.send_message(Command::Navigate(NavigateParams {
|
|
||||||
url: url.into(),
|
|
||||||
}))
|
|
||||||
.await?;
|
|
||||||
debug!("Received message: {:?}", res);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn new_session(
|
|
||||||
&mut self,
|
|
||||||
) -> Result<NewSessionResponse, CommandError> {
|
|
||||||
let res = self
|
|
||||||
.send_message(Command::NewSession(NewSessionParams {
|
|
||||||
strict_file_interactability: true,
|
|
||||||
}))
|
|
||||||
.await?
|
|
||||||
.unwrap();
|
|
||||||
debug!("Received message: {:?}", res);
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_message<T>(
|
pub async fn send_message<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
command: Command,
|
command: Command,
|
||||||
|
@ -190,3 +157,48 @@ impl Marionette {
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Marionette {
|
||||||
|
conn: MarionetteConnection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Marionette {
|
||||||
|
pub fn new(conn: MarionetteConnection) -> Self {
|
||||||
|
Self { conn }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_title(&mut self) -> Result<String, CommandError> {
|
||||||
|
let res: GetTitleResponse =
|
||||||
|
self.conn.send_message(Command::GetTitle).await?.unwrap();
|
||||||
|
debug!("Received message: {:?}", res);
|
||||||
|
Ok(res.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn navigate<U>(&mut self, url: U) -> Result<(), CommandError>
|
||||||
|
where
|
||||||
|
U: Into<String>,
|
||||||
|
{
|
||||||
|
let res: Option<serde_json::Value> = self
|
||||||
|
.conn
|
||||||
|
.send_message(Command::Navigate(NavigateParams {
|
||||||
|
url: url.into(),
|
||||||
|
}))
|
||||||
|
.await?;
|
||||||
|
debug!("Received message: {:?}", res);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn new_session(
|
||||||
|
&mut self,
|
||||||
|
) -> Result<NewSessionResponse, CommandError> {
|
||||||
|
let res = self
|
||||||
|
.conn
|
||||||
|
.send_message(Command::NewSession(NewSessionParams {
|
||||||
|
strict_file_interactability: true,
|
||||||
|
}))
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
|
debug!("Received message: {:?}", res);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use tracing::{debug, error, info, warn};
|
||||||
use crate::browser::{Browser, BrowserError};
|
use crate::browser::{Browser, BrowserError};
|
||||||
use crate::config::Configuration;
|
use crate::config::Configuration;
|
||||||
use crate::marionette::error::{CommandError, ConnectionError};
|
use crate::marionette::error::{CommandError, ConnectionError};
|
||||||
use crate::marionette::Marionette;
|
use crate::marionette::{Marionette, MarionetteConnection};
|
||||||
use crate::mqtt::{Message, MqttClient, MqttPublisher};
|
use crate::mqtt::{Message, MqttClient, MqttPublisher};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -81,7 +81,8 @@ impl Session {
|
||||||
return Err(SessionError::InvalidState("No active Marionette port".into()));
|
return Err(SessionError::InvalidState("No active Marionette port".into()));
|
||||||
};
|
};
|
||||||
debug!("Connecting to Firefox Marionette on port {}", port);
|
debug!("Connecting to Firefox Marionette on port {}", port);
|
||||||
let mut marionette = Marionette::connect(("127.0.0.1", port)).await?;
|
let conn = MarionetteConnection::connect(("127.0.0.1", port)).await?;
|
||||||
|
let mut marionette = Marionette::new(conn);
|
||||||
info!("Successfully connected to Firefox Marionette");
|
info!("Successfully connected to Firefox Marionette");
|
||||||
let ses = marionette.new_session().await?;
|
let ses = marionette.new_session().await?;
|
||||||
debug!("Started Marionette session {}", ses.session_id);
|
debug!("Started Marionette session {}", ses.session_id);
|
||||||
|
|
Loading…
Reference in New Issue