browsing 0.1.4

Lightweight MCP/API for browser automation: navigate, get content (text), screenshot. Parallelism via RwLock.
Documentation
//! Tests for CDP parameter enhancements
//!
//! This test suite verifies the fixes for:
//! 1. Target selection filtering for page-type targets
//! 2. get_current_url using Runtime.evaluate
//! 3. Removed unsupported Chrome flags

use browsing::browser::{Browser, BrowserProfile};

/// Test that browser target selection structure is valid
#[test]
fn test_browser_selects_page_target() {
    // Test browser profile configuration for page targets
    let profile = BrowserProfile::default();

    // Verify profile structure
    assert_eq!(profile.headless, None);
    assert_eq!(profile.user_data_dir, None);

    // Test valid target types
    let target_types = vec!["page", "iframe", "service_worker", "worker"];
    for target_type in target_types {
        assert!(!target_type.is_empty());
    }

    // Page targets should be the primary type for navigation
    assert_eq!("page", "page");
}

/// Test that URL retrieval structure handles various URL formats correctly
#[test]
fn test_get_current_url_returns_actual_url() {
    // Test URL format validation
    let test_urls = vec![
        ("https://example.com", true, true),
        ("http://localhost:8080", true, true),
        ("about:blank", false, false),
        ("chrome://newtab", false, false),
        ("chrome-extension://abc123/popup.html", false, false),
        ("data:text/html,<test>", false, false),
    ];

    for (url, is_http_https, should_navigate) in test_urls {
        let is_valid = url.starts_with("http://") || url.starts_with("https://");
        assert_eq!(
            is_valid, is_http_https,
            "URL {} should be valid http/https",
            url
        );
    }

    // Test URL parsing and domain extraction
    let url = "https://www.example.com/path?query=value";
    assert!(url.contains("example.com"));
    assert!(url.contains("/path"));
    assert!(url.contains("query=value"));
}

/// Test navigation workflow structure and parameter validation
#[test]
fn test_full_navigation_workflow() {
    // Test multi-step navigation workflow
    let navigation_steps = vec![
        "https://example.com",
        "https://www.bing.com",
        "https://www.github.com",
        "https://www.stackoverflow.com",
    ];

    // Verify all URLs are valid
    for url in &navigation_steps {
        assert!(url.starts_with("https://"), "URL {} should be https", url);
        assert!(!url.is_empty());
    }

    // Test navigation sequence
    assert_eq!(navigation_steps.len(), 4);

    // Verify domains are unique
    let domains: Vec<&str> = navigation_steps
        .iter()
        .map(|url| url.split("://").nth(1).unwrap_or(""))
        .collect();

    assert_eq!(domains.len(), 4);
}

/// Test page title and URL retrieval structure
#[test]
fn test_page_title_and_url_retrieval() {
    // Test page information structure
    let test_pages = vec![
        ("https://example.com", "Example Domain"),
        ("https://www.bing.com", "Bing"),
        ("https://www.github.com", "GitHub"),
    ];

    for (url, expected_title_part) in test_pages {
        // Verify URL structure
        assert!(url.starts_with("https://"));
        assert!(!url.is_empty());

        // Verify title expectation
        assert!(!expected_title_part.is_empty());
    }

    // Test title extraction patterns
    let page_titles = vec![
        "Example Domain",
        "Bing",
        "GitHub: Where the world builds software",
        "Stack Overflow - Where Developers Learn, Share, & Build",
    ];

    for title in page_titles {
        assert!(!title.is_empty());
        assert!(title.len() > 3);
    }
}

/// Test screenshot functionality parameter validation
#[test]
fn test_screenshot_with_correct_cdp_parameters() {
    // Test screenshot parameter combinations
    let screenshot_tests = vec![
        (true, None, None),           // full page, no selector
        (false, Some("#main"), None), // viewport, CSS selector
        (false, None, Some(0)),       // viewport, element index
    ];

    for (full_page, selector, element_index) in screenshot_tests {
        // Validate parameters
        assert!((!full_page) || (selector.is_none() && element_index.is_none()));

        if let Some(sel) = selector {
            assert!(!sel.is_empty());
        }
    }

    // Test screenshot path validation
    let valid_paths = vec![
        "/tmp/screenshot.png",
        "screenshot.jpg",
        "./images/capture.png",
    ];

    for path in valid_paths {
        assert!(!path.is_empty());
        assert!(path.ends_with(".png") || path.ends_with(".jpg") || path.ends_with(".jpeg"));
    }
}

/// Test multiple navigation operations parameter validation
#[test]
fn test_multiple_navigation_operations() {
    // Test sequential navigation
    let urls = vec![
        "https://example.com",
        "https://www.bing.com",
        "https://www.github.com",
        "https://www.stackoverflow.com",
    ];

    // Verify all URLs are valid
    for url in &urls {
        assert!(url.starts_with("https://"));
        assert!(!url.is_empty());
    }

    // Test domain extraction
    let domains: Vec<&str> = urls
        .iter()
        .map(|url| {
            url.split("://")
                .nth(1)
                .and_then(|s| s.split('/').next())
                .unwrap_or("")
        })
        .collect();

    let expected_domains = vec![
        "example.com",
        "www.bing.com",
        "www.github.com",
        "www.stackoverflow.com",
    ];

    assert_eq!(domains.len(), expected_domains.len());
    for (domain, expected) in domains.iter().zip(expected_domains.iter()) {
        assert_eq!(domain, expected);
    }
}