Reduce lib.rs from 7481 to 6557 lines (-12.4%) by extracting: - paths.rs: Session/workspace path utilities (get_todo_path, get_logs_dir, etc.) - streaming_parser.rs: StreamingToolParser for LLM response parsing - utils.rs: Diff parsing and shell escaping utilities - webdriver_session.rs: Unified Safari/Chrome WebDriver abstraction All public APIs preserved via re-exports for backward compatibility. Added 13 new unit tests across extracted modules. All 225 tests pass.
134 lines
4.4 KiB
Rust
134 lines
4.4 KiB
Rust
//! Unified WebDriver session abstraction.
|
|
//!
|
|
//! This module provides a unified interface for browser automation
|
|
//! that can work with either Safari or Chrome WebDriver.
|
|
|
|
use g3_computer_control::{ChromeDriver, SafariDriver, WebDriverController, WebElement};
|
|
|
|
/// Unified WebDriver session that can hold either Safari or Chrome driver.
|
|
pub enum WebDriverSession {
|
|
Safari(SafariDriver),
|
|
Chrome(ChromeDriver),
|
|
}
|
|
|
|
#[async_trait::async_trait]
|
|
impl WebDriverController for WebDriverSession {
|
|
async fn navigate(&mut self, url: &str) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.navigate(url).await,
|
|
WebDriverSession::Chrome(driver) => driver.navigate(url).await,
|
|
}
|
|
}
|
|
|
|
async fn current_url(&self) -> anyhow::Result<String> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.current_url().await,
|
|
WebDriverSession::Chrome(driver) => driver.current_url().await,
|
|
}
|
|
}
|
|
|
|
async fn title(&self) -> anyhow::Result<String> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.title().await,
|
|
WebDriverSession::Chrome(driver) => driver.title().await,
|
|
}
|
|
}
|
|
|
|
async fn find_element(
|
|
&mut self,
|
|
selector: &str,
|
|
) -> anyhow::Result<WebElement> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.find_element(selector).await,
|
|
WebDriverSession::Chrome(driver) => driver.find_element(selector).await,
|
|
}
|
|
}
|
|
|
|
async fn find_elements(
|
|
&mut self,
|
|
selector: &str,
|
|
) -> anyhow::Result<Vec<WebElement>> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.find_elements(selector).await,
|
|
WebDriverSession::Chrome(driver) => driver.find_elements(selector).await,
|
|
}
|
|
}
|
|
|
|
async fn execute_script(
|
|
&mut self,
|
|
script: &str,
|
|
args: Vec<serde_json::Value>,
|
|
) -> anyhow::Result<serde_json::Value> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.execute_script(script, args).await,
|
|
WebDriverSession::Chrome(driver) => driver.execute_script(script, args).await,
|
|
}
|
|
}
|
|
|
|
async fn page_source(&self) -> anyhow::Result<String> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.page_source().await,
|
|
WebDriverSession::Chrome(driver) => driver.page_source().await,
|
|
}
|
|
}
|
|
|
|
async fn screenshot(&mut self, path: &str) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.screenshot(path).await,
|
|
WebDriverSession::Chrome(driver) => driver.screenshot(path).await,
|
|
}
|
|
}
|
|
|
|
async fn close(&mut self) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.close().await,
|
|
WebDriverSession::Chrome(driver) => driver.close().await,
|
|
}
|
|
}
|
|
|
|
async fn quit(self) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.quit().await,
|
|
WebDriverSession::Chrome(driver) => driver.quit().await,
|
|
}
|
|
}
|
|
}
|
|
|
|
// Additional methods for WebDriverSession that aren't part of the WebDriverController trait
|
|
impl WebDriverSession {
|
|
pub async fn back(&mut self) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.back().await,
|
|
WebDriverSession::Chrome(driver) => driver.back().await,
|
|
}
|
|
}
|
|
|
|
pub async fn forward(&mut self) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.forward().await,
|
|
WebDriverSession::Chrome(driver) => driver.forward().await,
|
|
}
|
|
}
|
|
|
|
pub async fn refresh(&mut self) -> anyhow::Result<()> {
|
|
match self {
|
|
WebDriverSession::Safari(driver) => driver.refresh().await,
|
|
WebDriverSession::Chrome(driver) => driver.refresh().await,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_webdriver_session_enum_variants() {
|
|
// This test just verifies the enum structure compiles correctly
|
|
// Actual WebDriver tests would require a running browser
|
|
fn _assert_send<T: Send>() {}
|
|
fn _assert_sync<T: Sync>() {}
|
|
// WebDriverSession should be Send but not necessarily Sync due to internal state
|
|
}
|
|
}
|