use async_trait::async_trait;
use browsing::agent::views::ActionResult;
use browsing::browser::{Browser, BrowserProfile};
use browsing::error::Result;
use browsing::tools::views::{ActionContext, ActionHandler, ActionParams};
struct CustomGreetingHandler;
#[async_trait]
impl ActionHandler for CustomGreetingHandler {
async fn execute(
&self,
params: &ActionParams,
_context: &mut ActionContext<'_>,
) -> Result<ActionResult> {
let name = params.get_required_str("name").unwrap_or("World");
let greeting = format!("Hello, {}! This is a custom action.", name);
println!("Custom action executed: {}", greeting);
Ok(ActionResult {
extracted_content: Some(greeting),
success: Some(true),
..Default::default()
})
}
}
#[tokio::main]
async fn main() -> Result<()> {
println!("Browser Automation Comprehensive Showcase\n");
println!("This example demonstrates the key capabilities:");
println!(" - Browser automation");
println!(" - Multi-tab management");
println!(" - Content extraction");
println!(" - Custom actions");
println!(" - Error handling\n");
println!("Step 1: Creating browser profile...");
let headless = std::env::var("BROWSER_USE_HEADLESS")
.ok()
.and_then(|v| v.parse::<bool>().ok())
.unwrap_or(false);
let profile = BrowserProfile {
headless: Some(headless),
proxy: None,
..Default::default()
};
println!(
" Mode: {}",
if headless {
"headless (background)"
} else {
"visible"
}
);
let mut browser = Browser::new(profile);
println!(" Starting browser...");
browser.start().await?;
println!(" Browser started\n");
println!("Step 2: Navigating to example.com...");
browser.navigate("https://example.com").await?;
let url = browser.get_current_url().await?;
let title = browser.get_current_page_title().await?;
println!(" Navigated to: {}", url);
println!(" Page title: {}\n", title);
println!("Step 3: Executing JavaScript...");
let page = browser.get_page()?;
let result = page.evaluate("document.title").await?;
println!(" JS result: {}\n", result);
println!("Step 4: Extracting page content...");
let body_text = page.evaluate("document.body.innerText").await?;
let preview = if body_text.len() > 200 {
format!("{}...", &body_text[..200])
} else {
body_text
};
println!(" Content extracted ({} chars preview):\n {}\n", preview.len(), preview);
println!("Step 5: Tab management...");
use browsing::traits::BrowserClient;
let tabs_before = browser.get_tabs().await?;
println!(" Tabs before: {}", tabs_before.len());
let new_tab = browser.create_tab(Some("https://example.org")).await?;
println!(" Created new tab: {}", new_tab);
let tabs_after = browser.get_tabs().await?;
println!(" Tabs after: {}\n", tabs_after.len());
if let Some(first_tab) = tabs_before.first() {
browser.switch_to_tab(&first_tab.target_id).await?;
println!(" Switched back to first tab\n");
}
println!("Step 6: Taking screenshot...");
match browser.take_screenshot(None, false, None, None).await {
Ok(screenshot) => {
println!(" Screenshot captured ({} bytes)\n", screenshot.len());
}
Err(e) => {
println!(" Screenshot failed: {}\n", e);
}
}
println!("Step 7: Custom actions...");
use browsing::tools::Tools;
let mut tools = Tools::default();
tools.register_custom_action(
"greet".to_string(),
"Send a greeting".to_string(),
None,
CustomGreetingHandler,
);
println!(" Registered custom action: greet\n");
println!("Showcase completed successfully!");
println!("\nNext steps:");
println!(" - Try navigating to different URLs");
println!(" - Use Tools::new() to customize available actions");
println!(" - Explore the API documentation: cargo doc --open");
let _ = browser.stop().await;
Ok(())
}