2024-12-24 13:05:54 -03:00
|
|
|
use chromiumoxide::{Browser, Element};
|
2024-12-23 17:36:12 -03:00
|
|
|
use chromiumoxide::page::Page;
|
2024-12-24 13:05:54 -03:00
|
|
|
use chromiumoxide::browser::BrowserConfig;
|
2024-12-23 17:36:12 -03:00
|
|
|
use futures_util::StreamExt;
|
|
|
|
use gb_core::{Error, Result};
|
2024-12-24 13:05:54 -03:00
|
|
|
use std::time::Duration;
|
2024-12-23 17:36:12 -03:00
|
|
|
|
2024-12-22 20:56:52 -03:00
|
|
|
pub struct WebAutomation {
|
2024-12-23 17:36:12 -03:00
|
|
|
browser: Browser,
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl WebAutomation {
|
|
|
|
pub async fn new() -> Result<Self> {
|
2024-12-24 10:09:14 -03:00
|
|
|
let config = BrowserConfig::builder()
|
|
|
|
.build()
|
|
|
|
.map_err(|e| Error::internal(e.to_string()))?;
|
2024-12-24 13:05:54 -03:00
|
|
|
|
|
|
|
let (browser, handler) = Browser::launch(config)
|
2024-12-22 20:56:52 -03:00
|
|
|
.await
|
2024-12-23 17:36:12 -03:00
|
|
|
.map_err(|e| Error::internal(e.to_string()))?;
|
2024-12-24 10:09:14 -03:00
|
|
|
|
2024-12-24 13:05:54 -03:00
|
|
|
// Spawn the handler in the background
|
2024-12-22 20:56:52 -03:00
|
|
|
tokio::spawn(async move {
|
2024-12-24 13:05:54 -03:00
|
|
|
handler.for_each(|_| async {}).await;
|
2024-12-22 20:56:52 -03:00
|
|
|
});
|
|
|
|
|
2024-12-23 17:36:12 -03:00
|
|
|
Ok(Self { browser })
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn new_page(&self) -> Result<Page> {
|
2024-12-24 13:05:54 -03:00
|
|
|
self.browser
|
|
|
|
.new_page("about:blank")
|
2024-12-22 20:56:52 -03:00
|
|
|
.await
|
2024-12-24 10:09:14 -03:00
|
|
|
.map_err(|e| Error::internal(e.to_string()))
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn navigate(&self, page: &Page, url: &str) -> Result<()> {
|
|
|
|
page.goto(url)
|
|
|
|
.await
|
2024-12-24 13:05:54 -03:00
|
|
|
.map_err(|e| Error::internal(e.to_string()))?;
|
|
|
|
Ok(())
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
|
|
|
|
2024-12-24 13:05:54 -03:00
|
|
|
pub async fn take_screenshot(&self, page: &Page) -> Result<Vec<u8>> {
|
|
|
|
let params = chromiumoxide::page::ScreenshotParams::builder().build();
|
|
|
|
|
2024-12-24 10:09:14 -03:00
|
|
|
page.screenshot(params)
|
2024-12-22 20:56:52 -03:00
|
|
|
.await
|
2024-12-24 10:09:14 -03:00
|
|
|
.map_err(|e| Error::internal(e.to_string()))
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
|
|
|
|
2024-12-24 13:05:54 -03:00
|
|
|
pub async fn find_element(&self, page: &Page, selector: &str, timeout: Duration) -> Result<Element> {
|
|
|
|
tokio::time::timeout(
|
|
|
|
timeout,
|
|
|
|
page.find_element(selector)
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.map_err(|_| Error::internal("Timeout waiting for element"))?
|
|
|
|
.map_err(|e| Error::internal(e.to_string()))
|
2024-12-22 20:56:52 -03:00
|
|
|
}
|
2024-12-24 13:05:54 -03:00
|
|
|
}
|