browsing 0.1.7

Browser automation: navigate, click, extract, screenshot. Standalone browser control via CDP.
Documentation
# Browsing

**Rust-native browser automation β€” 20+ CDP managers, MCP server, zero AI deps**

| | Data Point |
|---|---|
| **Binary size** | ~2–5 MB release (LTO + strip + `opt-level = "z"`) |
| **Test coverage** | 360+ tests, all passing |
| **CDP domains covered** | Page, Network, Fetch, Emulation, Tracing, Profiler, CSS, DOM, Runtime, Target, ServiceWorker, Input, Browser, Console |
| **Zero** | LLM dependencies, `Box::leak`, recursive async retry |

## πŸ—ΊοΈ Where Does Browsing Fit?

| Tool | Language | Best For | Footprint | CDP Access |
|---|---|---|---|---|
| Selenium | Java/Python | Legacy testing | Heavy WebDriver | Indirect |
| Puppeteer | JavaScript | Chrome scripts | ~50 MB Node | Thin wrapper |
| Playwright | JS/Python | Cross-browser tests | ~200 MB | Batteries-included, opinionated |
| browser-use | Python | LLM agents | Python + AI deps | Hidden behind agent loop |
| **Browsing** | **Rust** | **Fast, embeddable automation** | **~2–5 MB** | **Raw + 20 typed managers** |

Browsing gives you Playwright's feature coverage (dialogs, file choosers, device presets, permissions, HAR, tracing, touch, workers, service workers) in a Rust-native, zero-bloat package with an MCP server for LLM integration.

## 🎯 Key Features

### πŸ—οΈ Architecture
- **Trait-based** β€” `BrowserClient`, `DOMProcessor`, `ActionHandler` for mocking and backends
- **20+ typed managers** β€” Each wraps a CDP domain: Dialog, FileChooser, Permissions, HAR, Interceptor, Performance, Coverage, Tracing, Touch, Worker, ServiceWorker, Viewport (with device presets, color scheme, vision deficiency, locale), Auth, Console, Cookies, PDF
- **Headless by default** β€” 17+ lightweight Chrome flags; `BrowserProfile::default()` runs `--headless=new`
- **Raw CDP access** β€” `Browser::raw_cdp_command()` for anything the managers don't cover
- **Zero AI dependencies** β€” Pure Rust, no LLM lock-in

## πŸ“¦ Installation

### As a Library

```toml
[dependencies]
browsing = "0.1"
tokio = { version = "1.40", features = ["full"] }
```

### As a CLI Tool

```bash
cargo install --path . --bin browsing
```

### As an MCP Server

```bash
cargo build --release --bin browsing-mcp
```

## πŸš€ Quick Start

### 1️⃣ CLI Usage

```bash
# Run a browser automation task (headless by default)
browsing run "Navigate to example.com and extract content" --url https://news.ycombinator.com

# Run with visible browser
browsing run "Navigate to example.com and extract content" --url https://news.ycombinator.com --no-headless

# Launch a headless browser and get CDP URL (headless by default)
browsing launch

# Launch with visible browser
browsing launch --no-headless

# Connect to existing browser
browsing connect ws://localhost:9222/devtools/browser/abc123
```

**πŸ“– [Full CLI Documentation](docs/CLI_USAGE.md)**

### 2️⃣ MCP Server Usage

Configure in Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "browsing": {
      "command": "/path/to/browsing/target/release/browsing-mcp",
      "env": {
        "BROWSER_USE_HEADLESS": "true"
      }
    }
  }
}
```

Then ask Claude:
```
"Navigate to rust-lang.org, get the links, follow the second link, and screenshot the main content area"
```

**πŸ“– [Full MCP Documentation](docs/MCP_USAGE.md)**

### 3️⃣ Library Usage

```rust
use anyhow::Result;
use browsing::Browser;
use browsing::browser::BrowserProfile;

#[tokio::main]
async fn main() -> Result<()> {
    browsing::init();

    let mut browser = Browser::new(BrowserProfile::default());
    browser.start().await?;

    browser.navigate("https://example.com").await?;

    let title = browser.get_current_page_title().await?;
    println!("Title: {}", title);

    let _ = browser.stop().await;
    Ok(())
}
```

**πŸ“– [Full Library Documentation](docs/LIBRARY_USAGE.md)**

### Browser Launch Options

```rust
use browsing::{Browser, BrowserProfile};

// Option 1: Auto-launch headless browser (default)
let profile = BrowserProfile::default(); // headless = true by default
let browser = Browser::new(profile);

// Option 2: Launch with visible browser
let profile = BrowserProfile::default().with_headless(false);
let browser = Browser::new(profile);

// Option 3: Connect to existing browser
let browser = Browser::new(BrowserProfile::default())
    .with_cdp_url("http://localhost:9222".to_string());

// Option 4: Custom browser executable
use browsing::browser::launcher::BrowserLauncher;
let launcher = BrowserLauncher::new(profile)
    .with_executable_path(std::path::PathBuf::from("/path/to/chrome"));
```

## πŸ“š Quick Example

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

#[tokio::main]
async fn main() -> browsing::Result<()> {
    let mut browser = Browser::new(BrowserProfile::default());
    browser.start().await?;

    browser.navigate("https://example.com").await?;

    // Use any manager
    let viewport = browser.viewport_manager()?;
    viewport.preset_device(&browsing::DevicePreset::iphone_15()).await?;

    // Or send raw CDP
    let result = browser
        .raw_cdp_command("Runtime.evaluate", json!({"expression": "1+1"}))
        .await?;

    Ok(())
}
```

**More examples:** See [`examples/`](examples/) β€” device emulation, dialog handling, HAR capture, permissions, touch gestures, raw CDP access.

## πŸ—οΈ Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Browser  β”‚ DOMProcessor β”‚        Tools           β”‚
β”‚ (trait)  β”‚   (trait)    β”‚                        β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚            β”‚                       β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”  β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚ Browser β”‚  β”‚ DomSvc β”‚       β”‚   Handlers     β”‚
β”‚ Session β”‚  β”‚        β”‚       β”‚ (nav, click,   β”‚
β”‚ + 20+   β”‚  β”‚ CDP    β”‚       β”‚  tabs, content)β”‚
β”‚ managersβ”‚  β”‚ HTML   β”‚       β”‚                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for full design.

## πŸ“ Project Structure

```
browsing/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ agent/              # Agent view types (used by tools layer)
β”‚   β”‚   β”œβ”€β”€ views.rs        # Data types
β”‚   β”‚   └── memory.rs       # Session memory types
β”‚   β”œβ”€β”€ browser/            # Browser management
β”‚   β”‚   β”œβ”€β”€ session.rs      # Browser session (BrowserClient impl)
β”‚   β”‚   β”œβ”€β”€ tab_manager.rs  # Tab operations
β”‚   β”‚   β”œβ”€β”€ navigation.rs   # Navigation operations
β”‚   β”‚   β”œβ”€β”€ screenshot.rs   # Screenshot operations
β”‚   β”‚   β”œβ”€β”€ cdp.rs          # CDP WebSocket client
β”‚   β”‚   β”œβ”€β”€ launcher.rs     # Browser launcher
β”‚   β”‚   β”œβ”€β”€ profile.rs      # Browser configuration
β”‚   β”‚   β”œβ”€β”€ auth.rs         # HTTP auth / proxy / extra headers
β”‚   β”‚   β”œβ”€β”€ console.rs      # Console log capture
β”‚   β”‚   β”œβ”€β”€ cookies.rs      # Cookie management
β”‚   β”‚   β”œβ”€β”€ coverage.rs     # JS/CSS coverage tracking
β”‚   β”‚   β”œβ”€β”€ dialog.rs       # Dialog handling (alert/confirm/prompt)
β”‚   β”‚   β”œβ”€β”€ download.rs     # Download monitoring
β”‚   β”‚   β”œβ”€β”€ filechooser.rs  # File chooser interception
β”‚   β”‚   β”œβ”€β”€ har.rs          # Network traffic HAR capture
β”‚   β”‚   β”œβ”€β”€ interceptor.rs  # Network request interception
β”‚   β”‚   β”œβ”€β”€ pdf.rs          # PDF export
β”‚   β”‚   β”œβ”€β”€ performance.rs  # Performance metrics
β”‚   β”‚   β”œβ”€β”€ permissions.rs  # Browser permissions API
β”‚   β”‚   β”œβ”€β”€ serviceworker.rs # Service worker management
β”‚   β”‚   β”œβ”€β”€ touch.rs        # Touch gesture emulation
β”‚   β”‚   β”œβ”€β”€ tracing.rs      # Chrome tracing / CPU profiling
β”‚   β”‚   β”œβ”€β”€ viewport.rs     # Viewport / device emulation
β”‚   β”‚   β”œβ”€β”€ worker.rs       # Web worker management
β”‚   β”‚   └── views.rs        # Data types
β”‚   β”œβ”€β”€ dom/                # DOM processing
β”‚   β”‚   β”œβ”€β”€ processor.rs    # DOMProcessor trait impl
β”‚   β”‚   β”œβ”€β”€ serializer.rs   # Text serialization
β”‚   β”‚   β”œβ”€β”€ tree_builder.rs # DOM tree construction
β”‚   β”‚   β”œβ”€β”€ cdp_client.rs   # CDP wrapper for DOM
β”‚   β”‚   └── html_converter.rs # HTML to markdown
β”‚   β”œβ”€β”€ tools/              # Action system
β”‚   β”‚   β”œβ”€β”€ service.rs      # Tools registry
β”‚   β”‚   β”œβ”€β”€ handlers/       # Action handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ navigation.rs
β”‚   β”‚   β”‚   β”œβ”€β”€ interaction.rs
β”‚   β”‚   β”‚   β”œβ”€β”€ tabs.rs
β”‚   β”‚   β”‚   β”œβ”€β”€ content.rs
β”‚   β”‚   β”‚   └── advanced.rs
β”‚   β”‚   └── params.rs       # Parameter extraction
β”‚   β”œβ”€β”€ traits/             # Core trait abstractions
β”‚   β”‚   β”œβ”€β”€ browser_client.rs  # BrowserClient trait
β”‚   β”‚   └── dom_processor.rs   # DOMProcessor trait
β”‚   β”œβ”€β”€ actor/              # Low-level interactions
β”‚   β”‚   β”œβ”€β”€ page.rs         # Page operations
β”‚   β”‚   β”œβ”€β”€ element.rs      # Element operations
β”‚   β”‚   β”œβ”€β”€ mouse.rs        # Mouse interactions
β”‚   β”‚   └── keyboard.rs     # Keyboard input
β”‚   β”œβ”€β”€ config.rs           # Configuration
β”‚   β”œβ”€β”€ error.rs            # Error types
β”‚   β”œβ”€β”€ logging.rs          # Logging setup
β”‚   β”œβ”€β”€ metrics.rs          # Metrics collection
β”‚   β”œβ”€β”€ utils.rs            # Utilities
β”‚   └── views.rs            # Shared data types
└── Cargo.toml
```

## πŸ§ͺ Testing

```bash
# Run all tests
cargo test

# Run with output
cargo test -- --nocapture

# Run specific test
cargo test test_browser_navigation

# Run integration tests only
cargo test --test integration
```

### Test Coverage
**360+ tests**, all passing, 0 ignored. Every manager has unit tests. Mock implementations for deterministic testing without real browsers.

| Module | Tests | Focus |
|--------|-------|-------|
| Actor | 29 | Page, Element, Mouse, Keyboard |
| Browser | 154 | All 20+ managers + lifecycle |
| Tools | 67 | Action handlers + registry |
| Traits | 27 | BrowserClient, DOMProcessor mocks |
| Utils | 52 | URL extraction, signals |
| Integration | 115+ | End-to-end workflows |

## ⚠️ Data Retention

Browser data is **never deleted** to prevent accidental loss of real profiles. Temp directories in `/tmp/browser-use-*` are left for inspection; clean them manually.

```bash
rm -rf /tmp/browser-use-*
```

## πŸ”§ Configuration

```rust
use browsing::BrowserProfile;

let profile = BrowserProfile::default();          // headless, lightweight flags
let profile = BrowserProfile::default().with_headless(false); // visible
let profile = BrowserProfile {
    user_data_dir: Some("/path/to/profile".into()),
    ..Default::default()
};
```


## πŸ“– API Documentation

Generate and view API docs:

```bash
cargo doc --open
```