browsing 0.1.7

Browser automation: navigate, click, extract, screenshot. Standalone browser control via CDP.
Documentation
//! Comprehensive showcase of browser automation capabilities
//!
//! This example demonstrates:
//! - Browser automation with multiple tabs
//! - DOM extraction and processing
//! - Screenshot capture
//! - Custom action handlers
//! - Error handling and recovery
//!
//! Usage:
//!   cargo run --example comprehensive_showcase
//!
//! Requirements:
//!   - Chrome/Chromium browser installed

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};

/// Custom action handler for demonstration
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");

    // 1. Create browser profile
    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");

    // 2. Navigate to a page
    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);

    // 3. Execute JavaScript
    println!("Step 3: Executing JavaScript...");
    let page = browser.get_page()?;
    let result = page.evaluate("document.title").await?;
    println!("   JS result: {}\n", result);

    // 4. Page content extraction
    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);

    // 5. Tab management
    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());

    // Switch back to first tab
    if let Some(first_tab) = tabs_before.first() {
        browser.switch_to_tab(&first_tab.target_id).await?;
        println!("   Switched back to first tab\n");
    }

    // 6. Screenshot
    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);
        }
    }

    // 7. Custom actions
    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(())
}