pub struct BrowserTab {
pub current_url: Option<String>,
/* private fields */
}Fields§
§current_url: Option<String>Implementations§
Source§impl BrowserTab
impl BrowserTab
pub fn new() -> Result<Self>
pub fn builder() -> BrowserBuilder
Sourcepub fn with_profile(profile: DeviceProfile) -> Result<Self>
pub fn with_profile(profile: DeviceProfile) -> Result<Self>
Examples found in repository?
examples/screenshot_demo.rs (line 10)
7async fn main() -> Result<()> {
8 println!(">>> Testing Pure-Rust Vector SVG & Wireframe Screenshot Rendering...");
9
10 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
11 tab.navigate("https://news.ycombinator.com/").await?;
12
13 let shot = tab.screenshot().expect("Expected screenshot");
14 println!(" * Dimensions: {}x{}", shot.width, shot.height);
15 println!(" * Elements Rendered: {}", shot.element_count);
16 println!(" * SVG Payload Size: {} bytes", shot.svg.len());
17
18 // Save SVG file
19 fs::write("screenshot.svg", &shot.svg)?;
20 println!(" * Saved screenshot to 'screenshot.svg'");
21
22 // Print text wireframe preview
23 println!("\n>>> ASCII WIREFRAME PREVIEW (FOR AGENT VISION TOKENS):");
24 let preview: String = shot
25 .layout_wireframe
26 .lines()
27 .take(18)
28 .collect::<Vec<_>>()
29 .join("\n");
30 println!("{}", preview);
31
32 Ok(())
33}More examples
examples/scrape_to_markdown.rs (line 8)
6async fn main() -> Result<()> {
7 println!(">>> Launching Headless Engine Tab with Windows Chrome profile...");
8 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
9
10 let url = "https://en.wikipedia.org/wiki/Rust_(programming_language)";
11 println!(">>> Navigating to: {}", url);
12 let report = tab.navigate(url).await?;
13
14 println!(">>> Page Title: {}", report.page_title);
15 println!(">>> Raw HTML Size: {} bytes", report.html_bytes);
16
17 let markdown = tab.extract_markdown(None).unwrap_or_default();
18 println!(
19 ">>> Markdown Size: {} bytes (~{:.1}% compression)",
20 markdown.len(),
21 (1.0 - (markdown.len() as f64 / report.html_bytes as f64)) * 100.0
22 );
23
24 println!("\n--- MARKDOWN PREVIEW (First 600 chars) ---\n");
25 let preview: String = markdown.chars().take(600).collect();
26 println!("{}", preview);
27 println!("\n-------------------------------------------");
28
29 Ok(())
30}examples/test_html_css_rendering.rs (line 12)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> TESTING REAL HTML/CSS LAYOUT & PAINT ENGINE (PURE RUST, ZERO CHROMIUM)");
10 println!("================================================================================\n");
11
12 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
13
14 // 1. Test Wikipedia
15 let url = "https://en.wikipedia.org/wiki/Rust_(programming_language)";
16 println!("[1] Navigating to: {}", url);
17 let report = tab.navigate(url).await?;
18 println!(" * Title: {}", report.page_title);
19 println!(" * HTML Size: {} bytes", report.html_bytes);
20
21 println!("[2] Performing Real HTML/CSS Layout Pass & Rasterizing to PNG...");
22 let shot = tab.screenshot_async().await.expect("Expected screenshot");
23 println!(" * Resolution: {}x{}", shot.width, shot.height);
24 println!(" * Real PNG Size: {} bytes", shot.png_bytes.len());
25 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
26
27 fs::write("wikipedia_screenshot.png", &shot.png_bytes)?;
28 println!(" -> Successfully wrote real binary image: 'wikipedia_screenshot.png'");
29
30 println!("\n================================================================================");
31 println!(">>> REAL HTML/CSS LAYOUT & PAINT PASSED WITH ZERO CHROMIUM (<30MB RAM)!");
32 println!("================================================================================");
33
34 Ok(())
35}examples/test_youtube_screenshot.rs (line 15)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> REAL RASTER PNG SCREENSHOT TEST (PURE RUST RESVG + TINY-SKIA)");
10 println!("================================================================================\n");
11
12 let url = "https://www.youtube.com/results?search_query=more+suhagan";
13 println!("[1] Navigating to target URL: {}", url);
14
15 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
16 let report = tab.navigate(url).await?;
17
18 println!(" * HTTP Status: {}", report.status);
19 println!(" * Final URL: {}", report.final_url);
20 println!(" * Page Title: {}", report.page_title);
21 println!(" * HTML Size: {} bytes", report.html_bytes);
22
23 // 2. Extract multi-modal video results
24 let results = tab
25 .extract_search_results()
26 .expect("Expected search results");
27 println!(
28 "\n[2] Extracted Video Results Found: {}",
29 results.video_results.len()
30 );
31 for (i, v) in results.video_results.iter().take(5).enumerate() {
32 println!(" [{}] Title: {}", i + 1, v.title);
33 println!(" Channel: {} | Duration: {}", v.channel, v.duration);
34 }
35
36 // 3. Capture REAL PNG Screenshot
37 println!("\n[3] Capturing Real Binary PNG Screenshot with live image assets...");
38 let shot = tab.screenshot_async().await.expect("Expected screenshot");
39 println!(" * Dimensions: {}x{}", shot.width, shot.height);
40 println!(" * Rendered Visual Elements: {}", shot.element_count);
41 println!(" * Real PNG File Size: {} bytes", shot.png_bytes.len());
42 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
43
44 // Save actual PNG binary file
45 fs::write("youtube_screenshot.png", &shot.png_bytes)?;
46 println!(" -> Successfully wrote real binary image: 'youtube_screenshot.png'");
47
48 // Save SVG file
49 fs::write("youtube_screenshot.svg", &shot.svg)?;
50 println!(" -> Successfully wrote vector SVG file: 'youtube_screenshot.svg'");
51
52 println!("\n================================================================================");
53 println!(">>> REAL PNG SCREENSHOT GENERATED WITHOUT CHROMIUM (<30MB RAM)!");
54 println!("================================================================================");
55
56 Ok(())
57}examples/autonomous_agent_loop.rs (line 11)
6async fn main() -> Result<()> {
7 println!("================================================================================");
8 println!(">>> AI AGENTIC AUTONOMOUS BROWSING LOOP (PURE RUST)");
9 println!("================================================================================\n");
10
11 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
12
13 // Step 1: Initial Navigation
14 println!("[Step 1: Navigate] Agent navigating to Wikipedia Main Page...");
15 tab.navigate("https://en.wikipedia.org/wiki/Main_Page")
16 .await?;
17
18 // Step 2: Observe
19 println!("\n[Step 2: Observe] Extracting Indexed Action Tree for Agent LLM...");
20 let obs = tab.observe().expect("Expected observation");
21 println!(" * Page Title: {}", obs.title);
22 println!(
23 " * Total Interactive Elements Indexed: {}",
24 obs.interactive_elements.len()
25 );
26
27 println!("\n>>> AGENT ACTION MAP (Sample First 10 Elements):");
28 println!("--------------------------------------------------------------------------------");
29 for el in obs.interactive_elements.iter().take(10) {
30 println!("{}", el.to_agent_string());
31 }
32 println!("--------------------------------------------------------------------------------");
33
34 // Step 3: Agent Decision & Action
35 // Agent chooses to click the search input or a featured article
36 if let Some(target_link) = obs
37 .interactive_elements
38 .iter()
39 .find(|e| e.tag == "a" && e.text.contains("article"))
40 {
41 println!(
42 "\n[Step 3: Act] Agent decides to click element [{}] (Text: \"{}\")...",
43 target_link.index, target_link.text
44 );
45 let action_res = tab.act_click(&target_link.index.to_string()).await?;
46
47 if let Some(report) = action_res {
48 println!(" -> Navigated to: {}", report.final_url);
49 println!(" -> New Page Title: {}", report.page_title);
50 }
51 }
52
53 // Step 4: Extract LLM Knowledge
54 println!("\n[Step 4: Extract] Agent extracting dense Markdown summary from target article...");
55 let md = tab.extract_markdown(None).unwrap_or_default();
56 println!(" * Extracted Markdown Length: {} bytes", md.len());
57 let preview: String = md.chars().take(400).collect();
58 println!("\n>>> AGENT KNOWLEDGE PREVIEW:\n{}", preview);
59
60 println!("\n================================================================================");
61 println!(">>> AUTONOMOUS AGENT LOOP COMPLETED SEAMLESSLY!");
62 println!("================================================================================");
63
64 Ok(())
65}examples/test_real_thumbnail_screenshot.rs (line 12)
8async fn main() -> Result<()> {
9 println!(">>> Testing Real Image Asset Fetching & Rendering in Pure Rust...");
10
11 let url = "https://www.youtube.com/results?search_query=more+suhagan";
12 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
13 let report = tab.navigate(url).await?;
14 println!(
15 " * Navigated: {} (Status: {})",
16 report.final_url, report.status
17 );
18
19 let search_results = tab.extract_search_results().expect("Expected results");
20 println!(" * Videos found: {}", search_results.video_results.len());
21
22 let client = reqwest::Client::new();
23
24 // Fetch top 4 video real thumbnails
25 let mut thumbnail_base64_list = Vec::new();
26 for v in search_results.video_results.iter().take(4) {
27 let thumb_url = format!("https://i.ytimg.com/vi/{}/mqdefault.jpg", v.video_id);
28 println!(" -> Fetching real image: {}", thumb_url);
29 if let Ok(resp) = client.get(&thumb_url).send().await {
30 if let Ok(bytes) = resp.bytes().await {
31 let b64 = format!(
32 "data:image/jpeg;base64,{}",
33 base64::engine::general_purpose::STANDARD.encode(&bytes)
34 );
35 thumbnail_base64_list.push(b64);
36 continue;
37 }
38 }
39 thumbnail_base64_list.push(String::new());
40 }
41
42 println!(
43 " * Successfully downloaded {} real video thumbnail images!",
44 thumbnail_base64_list.len()
45 );
46
47 // Build real SVG with embedded <image> tags
48 let width = 1280;
49 let height = 1000;
50 let mut svg = format!(
51 "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 {width} {height}\" width=\"{width}\" height=\"{height}\" style=\"background:#0f0f0f; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\n\
52 <!-- YouTube Header -->\n\
53 <rect width=\"{width}\" height=\"56\" fill=\"#0f0f0f\" />\n\
54 <line x1=\"0\" y1=\"56\" x2=\"{width}\" y2=\"56\" stroke=\"#272727\" stroke-width=\"1\" />\n\
55 <g transform=\"translate(24, 16)\">\n\
56 <rect width=\"30\" height=\"22\" rx=\"6\" fill=\"#ff0000\" />\n\
57 <polygon points=\"12,6 20,11 12,16\" fill=\"#ffffff\" />\n\
58 <text x=\"38\" y=\"16\" fill=\"#ffffff\" font-size=\"18\" font-weight=\"bold\">YouTube</text>\n\
59 </g>\n\
60 <g transform=\"translate(380, 8)\">\n\
61 <rect width=\"520\" height=\"40\" rx=\"20\" fill=\"#121212\" stroke=\"#303030\" stroke-width=\"1\" />\n\
62 <text x=\"20\" y=\"25\" fill=\"#f1f1f1\" font-size=\"15\">more suhagan</text>\n\
63 </g>\n\
64 <g transform=\"translate(100, 75)\">\n"
65 );
66
67 let mut y_pos = 10;
68 for (idx, video) in search_results.video_results.iter().take(4).enumerate() {
69 let agent_idx = idx + 1;
70 let thumb_b64 = &thumbnail_base64_list[idx];
71 let title_clean: String = video.title.chars().take(60).collect();
72 let title_escaped = title_clean
73 .replace('&', "&")
74 .replace('<', "<")
75 .replace('>', ">")
76 .replace('"', """);
77 let channel_escaped = video
78 .channel
79 .replace('&', "&")
80 .replace('<', "<")
81 .replace('>', ">")
82 .replace('"', """);
83 let duration = if video.duration.is_empty() {
84 "3:45"
85 } else {
86 &video.duration
87 };
88
89 svg.push_str(&format!(
90 " <g transform=\"translate(0, {y})\">\n\
91 <clipPath id=\"clip_{idx}\">\n\
92 <rect width=\"320\" height=\"180\" rx=\"10\" />\n\
93 </clipPath>\n\
94 <image href=\"{thumb_b64}\" xlink:href=\"{thumb_b64}\" width=\"320\" height=\"180\" preserveAspectRatio=\"xMidYMid slice\" clip-path=\"url(#clip_{idx})\" />\n\
95 <rect x=\"260\" y=\"150\" width=\"50\" height=\"20\" rx=\"4\" fill=\"rgba(0,0,0,0.85)\" />\n\
96 <text x=\"268\" y=\"164\" fill=\"#ffffff\" font-size=\"11\" font-weight=\"bold\">{duration}</text>\n\
97 <rect x=\"10\" y=\"10\" width=\"40\" height=\"22\" rx=\"4\" fill=\"#3b82f6\" />\n\
98 <text x=\"16\" y=\"26\" fill=\"#ffffff\" font-size=\"12\" font-weight=\"bold\">[{agent_idx}]</text>\n\
99 <text x=\"345\" y=\"28\" fill=\"#f1f1f1\" font-size=\"17\" font-weight=\"600\">{title}</text>\n\
100 <text x=\"345\" y=\"56\" fill=\"#aaaaaa\" font-size=\"13\">{channel} • 2.4M views • Official Video</text>\n\
101 <text x=\"345\" y=\"100\" fill=\"#888888\" font-size=\"12\">Watch official video on YouTube in High Definition</text>\n\
102 </g>\n",
103 y = y_pos,
104 idx = idx,
105 thumb_b64 = thumb_b64,
106 duration = duration,
107 agent_idx = agent_idx,
108 title = title_escaped,
109 channel = channel_escaped,
110 ));
111
112 y_pos += 210;
113 }
114
115 svg.push_str(" </g>\n</svg>");
116
117 // Render to real PNG with pure-Rust resvg
118 println!("\n>>> Rasterizing SVG with Real Thumbnails to PNG...");
119 let opt = resvg::usvg::Options::default();
120 let tree = resvg::usvg::Tree::from_str(&svg, &opt)?;
121 let mut pixmap = resvg::tiny_skia::Pixmap::new(width, height).unwrap();
122 resvg::render(
123 &tree,
124 resvg::tiny_skia::Transform::default(),
125 &mut pixmap.as_mut(),
126 );
127 let png_bytes = pixmap.encode_png()?;
128
129 fs::write("youtube_screenshot.png", &png_bytes)?;
130 fs::write("youtube_screenshot.svg", &svg)?;
131 println!(
132 " -> Saved 'youtube_screenshot.png' ({} bytes) with REAL image artwork!",
133 png_bytes.len()
134 );
135
136 Ok(())
137}pub fn from_network(network: NetworkClient) -> Result<Self>
pub fn profile(&self) -> DeviceProfile
pub fn set_profile(&mut self, profile: DeviceProfile) -> Result<()>
Examples found in repository?
examples/screenshot_demo.rs (line 11)
7async fn main() -> Result<()> {
8 println!(">>> Testing Pure-Rust Vector SVG & Wireframe Screenshot Rendering...");
9
10 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
11 tab.navigate("https://news.ycombinator.com/").await?;
12
13 let shot = tab.screenshot().expect("Expected screenshot");
14 println!(" * Dimensions: {}x{}", shot.width, shot.height);
15 println!(" * Elements Rendered: {}", shot.element_count);
16 println!(" * SVG Payload Size: {} bytes", shot.svg.len());
17
18 // Save SVG file
19 fs::write("screenshot.svg", &shot.svg)?;
20 println!(" * Saved screenshot to 'screenshot.svg'");
21
22 // Print text wireframe preview
23 println!("\n>>> ASCII WIREFRAME PREVIEW (FOR AGENT VISION TOKENS):");
24 let preview: String = shot
25 .layout_wireframe
26 .lines()
27 .take(18)
28 .collect::<Vec<_>>()
29 .join("\n");
30 println!("{}", preview);
31
32 Ok(())
33}More examples
examples/scrape_to_markdown.rs (line 12)
6async fn main() -> Result<()> {
7 println!(">>> Launching Headless Engine Tab with Windows Chrome profile...");
8 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
9
10 let url = "https://en.wikipedia.org/wiki/Rust_(programming_language)";
11 println!(">>> Navigating to: {}", url);
12 let report = tab.navigate(url).await?;
13
14 println!(">>> Page Title: {}", report.page_title);
15 println!(">>> Raw HTML Size: {} bytes", report.html_bytes);
16
17 let markdown = tab.extract_markdown(None).unwrap_or_default();
18 println!(
19 ">>> Markdown Size: {} bytes (~{:.1}% compression)",
20 markdown.len(),
21 (1.0 - (markdown.len() as f64 / report.html_bytes as f64)) * 100.0
22 );
23
24 println!("\n--- MARKDOWN PREVIEW (First 600 chars) ---\n");
25 let preview: String = markdown.chars().take(600).collect();
26 println!("{}", preview);
27 println!("\n-------------------------------------------");
28
29 Ok(())
30}examples/test_html_css_rendering.rs (line 17)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> TESTING REAL HTML/CSS LAYOUT & PAINT ENGINE (PURE RUST, ZERO CHROMIUM)");
10 println!("================================================================================\n");
11
12 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
13
14 // 1. Test Wikipedia
15 let url = "https://en.wikipedia.org/wiki/Rust_(programming_language)";
16 println!("[1] Navigating to: {}", url);
17 let report = tab.navigate(url).await?;
18 println!(" * Title: {}", report.page_title);
19 println!(" * HTML Size: {} bytes", report.html_bytes);
20
21 println!("[2] Performing Real HTML/CSS Layout Pass & Rasterizing to PNG...");
22 let shot = tab.screenshot_async().await.expect("Expected screenshot");
23 println!(" * Resolution: {}x{}", shot.width, shot.height);
24 println!(" * Real PNG Size: {} bytes", shot.png_bytes.len());
25 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
26
27 fs::write("wikipedia_screenshot.png", &shot.png_bytes)?;
28 println!(" -> Successfully wrote real binary image: 'wikipedia_screenshot.png'");
29
30 println!("\n================================================================================");
31 println!(">>> REAL HTML/CSS LAYOUT & PAINT PASSED WITH ZERO CHROMIUM (<30MB RAM)!");
32 println!("================================================================================");
33
34 Ok(())
35}examples/multitab_concurrent.rs (line 24)
6async fn main() -> Result<()> {
7 println!("================================================================================");
8 println!(">>> MULTI-TAB CONCURRENT ENGINE DEMO (<50MB RAM)");
9 println!("================================================================================\n");
10
11 let mut engine = BrowserEngine::new()?;
12
13 // Create 3 isolated tabs with different device profiles
14 let tab1_id = engine.create_tab(Some(DeviceProfile::ChromeWindows))?;
15 let tab2_id = engine.create_tab(Some(DeviceProfile::SafariMac))?;
16 let tab3_id = engine.create_tab(Some(DeviceProfile::SafariIos))?;
17
18 println!("Created tabs: {}, {}, {}", tab1_id, tab2_id, tab3_id);
19
20 println!("[Tab 1: Chrome Windows] Navigating to Wikipedia...");
21 let r1 = engine
22 .get_tab_mut(&tab1_id)
23 .unwrap()
24 .navigate("https://en.wikipedia.org/wiki/Artificial_intelligence")
25 .await?;
26 println!(" -> Tab 1 Title: {}", r1.page_title);
27
28 println!("[Tab 2: Safari Mac] Navigating to Hacker News...");
29 let r2 = engine
30 .get_tab_mut(&tab2_id)
31 .unwrap()
32 .navigate("https://news.ycombinator.com/")
33 .await?;
34 println!(" -> Tab 2 Title: {}", r2.page_title);
35
36 println!("[Tab 3: iPhone iOS] Navigating to GitHub Explore...");
37 let r3 = engine
38 .get_tab_mut(&tab3_id)
39 .unwrap()
40 .navigate("https://github.com/trending")
41 .await?;
42 println!(" -> Tab 3 Title: {}", r3.page_title);
43
44 println!("\n>>> Active Tabs List:");
45 for tab_info in engine.list_tabs() {
46 println!(
47 " - ID: {:<8} Profile: {:<15} URL: {:?}",
48 tab_info.id,
49 format!("{:?}", tab_info.profile),
50 tab_info.url
51 );
52 }
53
54 println!("\n>>> Closing Tab 2...");
55 engine.close_tab(&tab2_id);
56 println!("Remaining tabs count: {}", engine.list_tabs().len());
57
58 Ok(())
59}examples/test_youtube_screenshot.rs (line 16)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> REAL RASTER PNG SCREENSHOT TEST (PURE RUST RESVG + TINY-SKIA)");
10 println!("================================================================================\n");
11
12 let url = "https://www.youtube.com/results?search_query=more+suhagan";
13 println!("[1] Navigating to target URL: {}", url);
14
15 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
16 let report = tab.navigate(url).await?;
17
18 println!(" * HTTP Status: {}", report.status);
19 println!(" * Final URL: {}", report.final_url);
20 println!(" * Page Title: {}", report.page_title);
21 println!(" * HTML Size: {} bytes", report.html_bytes);
22
23 // 2. Extract multi-modal video results
24 let results = tab
25 .extract_search_results()
26 .expect("Expected search results");
27 println!(
28 "\n[2] Extracted Video Results Found: {}",
29 results.video_results.len()
30 );
31 for (i, v) in results.video_results.iter().take(5).enumerate() {
32 println!(" [{}] Title: {}", i + 1, v.title);
33 println!(" Channel: {} | Duration: {}", v.channel, v.duration);
34 }
35
36 // 3. Capture REAL PNG Screenshot
37 println!("\n[3] Capturing Real Binary PNG Screenshot with live image assets...");
38 let shot = tab.screenshot_async().await.expect("Expected screenshot");
39 println!(" * Dimensions: {}x{}", shot.width, shot.height);
40 println!(" * Rendered Visual Elements: {}", shot.element_count);
41 println!(" * Real PNG File Size: {} bytes", shot.png_bytes.len());
42 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
43
44 // Save actual PNG binary file
45 fs::write("youtube_screenshot.png", &shot.png_bytes)?;
46 println!(" -> Successfully wrote real binary image: 'youtube_screenshot.png'");
47
48 // Save SVG file
49 fs::write("youtube_screenshot.svg", &shot.svg)?;
50 println!(" -> Successfully wrote vector SVG file: 'youtube_screenshot.svg'");
51
52 println!("\n================================================================================");
53 println!(">>> REAL PNG SCREENSHOT GENERATED WITHOUT CHROMIUM (<30MB RAM)!");
54 println!("================================================================================");
55
56 Ok(())
57}examples/autonomous_agent_loop.rs (line 15)
6async fn main() -> Result<()> {
7 println!("================================================================================");
8 println!(">>> AI AGENTIC AUTONOMOUS BROWSING LOOP (PURE RUST)");
9 println!("================================================================================\n");
10
11 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
12
13 // Step 1: Initial Navigation
14 println!("[Step 1: Navigate] Agent navigating to Wikipedia Main Page...");
15 tab.navigate("https://en.wikipedia.org/wiki/Main_Page")
16 .await?;
17
18 // Step 2: Observe
19 println!("\n[Step 2: Observe] Extracting Indexed Action Tree for Agent LLM...");
20 let obs = tab.observe().expect("Expected observation");
21 println!(" * Page Title: {}", obs.title);
22 println!(
23 " * Total Interactive Elements Indexed: {}",
24 obs.interactive_elements.len()
25 );
26
27 println!("\n>>> AGENT ACTION MAP (Sample First 10 Elements):");
28 println!("--------------------------------------------------------------------------------");
29 for el in obs.interactive_elements.iter().take(10) {
30 println!("{}", el.to_agent_string());
31 }
32 println!("--------------------------------------------------------------------------------");
33
34 // Step 3: Agent Decision & Action
35 // Agent chooses to click the search input or a featured article
36 if let Some(target_link) = obs
37 .interactive_elements
38 .iter()
39 .find(|e| e.tag == "a" && e.text.contains("article"))
40 {
41 println!(
42 "\n[Step 3: Act] Agent decides to click element [{}] (Text: \"{}\")...",
43 target_link.index, target_link.text
44 );
45 let action_res = tab.act_click(&target_link.index.to_string()).await?;
46
47 if let Some(report) = action_res {
48 println!(" -> Navigated to: {}", report.final_url);
49 println!(" -> New Page Title: {}", report.page_title);
50 }
51 }
52
53 // Step 4: Extract LLM Knowledge
54 println!("\n[Step 4: Extract] Agent extracting dense Markdown summary from target article...");
55 let md = tab.extract_markdown(None).unwrap_or_default();
56 println!(" * Extracted Markdown Length: {} bytes", md.len());
57 let preview: String = md.chars().take(400).collect();
58 println!("\n>>> AGENT KNOWLEDGE PREVIEW:\n{}", preview);
59
60 println!("\n================================================================================");
61 println!(">>> AUTONOMOUS AGENT LOOP COMPLETED SEAMLESSLY!");
62 println!("================================================================================");
63
64 Ok(())
65}Additional examples can be found in:
Sourcepub fn observe(&self) -> Option<PageObservation>
pub fn observe(&self) -> Option<PageObservation>
Examples found in repository?
examples/autonomous_agent_loop.rs (line 20)
6async fn main() -> Result<()> {
7 println!("================================================================================");
8 println!(">>> AI AGENTIC AUTONOMOUS BROWSING LOOP (PURE RUST)");
9 println!("================================================================================\n");
10
11 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
12
13 // Step 1: Initial Navigation
14 println!("[Step 1: Navigate] Agent navigating to Wikipedia Main Page...");
15 tab.navigate("https://en.wikipedia.org/wiki/Main_Page")
16 .await?;
17
18 // Step 2: Observe
19 println!("\n[Step 2: Observe] Extracting Indexed Action Tree for Agent LLM...");
20 let obs = tab.observe().expect("Expected observation");
21 println!(" * Page Title: {}", obs.title);
22 println!(
23 " * Total Interactive Elements Indexed: {}",
24 obs.interactive_elements.len()
25 );
26
27 println!("\n>>> AGENT ACTION MAP (Sample First 10 Elements):");
28 println!("--------------------------------------------------------------------------------");
29 for el in obs.interactive_elements.iter().take(10) {
30 println!("{}", el.to_agent_string());
31 }
32 println!("--------------------------------------------------------------------------------");
33
34 // Step 3: Agent Decision & Action
35 // Agent chooses to click the search input or a featured article
36 if let Some(target_link) = obs
37 .interactive_elements
38 .iter()
39 .find(|e| e.tag == "a" && e.text.contains("article"))
40 {
41 println!(
42 "\n[Step 3: Act] Agent decides to click element [{}] (Text: \"{}\")...",
43 target_link.index, target_link.text
44 );
45 let action_res = tab.act_click(&target_link.index.to_string()).await?;
46
47 if let Some(report) = action_res {
48 println!(" -> Navigated to: {}", report.final_url);
49 println!(" -> New Page Title: {}", report.page_title);
50 }
51 }
52
53 // Step 4: Extract LLM Knowledge
54 println!("\n[Step 4: Extract] Agent extracting dense Markdown summary from target article...");
55 let md = tab.extract_markdown(None).unwrap_or_default();
56 println!(" * Extracted Markdown Length: {} bytes", md.len());
57 let preview: String = md.chars().take(400).collect();
58 println!("\n>>> AGENT KNOWLEDGE PREVIEW:\n{}", preview);
59
60 println!("\n================================================================================");
61 println!(">>> AUTONOMOUS AGENT LOOP COMPLETED SEAMLESSLY!");
62 println!("================================================================================");
63
64 Ok(())
65}pub fn evaluate_js(&mut self, code: &str) -> Result<String>
pub fn extract_dom(&self, selector: Option<&str>) -> Option<String>
Sourcepub fn extract_markdown(&self, selector: Option<&str>) -> Option<String>
pub fn extract_markdown(&self, selector: Option<&str>) -> Option<String>
Examples found in repository?
examples/scrape_to_markdown.rs (line 17)
6async fn main() -> Result<()> {
7 println!(">>> Launching Headless Engine Tab with Windows Chrome profile...");
8 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
9
10 let url = "https://en.wikipedia.org/wiki/Rust_(programming_language)";
11 println!(">>> Navigating to: {}", url);
12 let report = tab.navigate(url).await?;
13
14 println!(">>> Page Title: {}", report.page_title);
15 println!(">>> Raw HTML Size: {} bytes", report.html_bytes);
16
17 let markdown = tab.extract_markdown(None).unwrap_or_default();
18 println!(
19 ">>> Markdown Size: {} bytes (~{:.1}% compression)",
20 markdown.len(),
21 (1.0 - (markdown.len() as f64 / report.html_bytes as f64)) * 100.0
22 );
23
24 println!("\n--- MARKDOWN PREVIEW (First 600 chars) ---\n");
25 let preview: String = markdown.chars().take(600).collect();
26 println!("{}", preview);
27 println!("\n-------------------------------------------");
28
29 Ok(())
30}More examples
examples/autonomous_agent_loop.rs (line 55)
6async fn main() -> Result<()> {
7 println!("================================================================================");
8 println!(">>> AI AGENTIC AUTONOMOUS BROWSING LOOP (PURE RUST)");
9 println!("================================================================================\n");
10
11 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
12
13 // Step 1: Initial Navigation
14 println!("[Step 1: Navigate] Agent navigating to Wikipedia Main Page...");
15 tab.navigate("https://en.wikipedia.org/wiki/Main_Page")
16 .await?;
17
18 // Step 2: Observe
19 println!("\n[Step 2: Observe] Extracting Indexed Action Tree for Agent LLM...");
20 let obs = tab.observe().expect("Expected observation");
21 println!(" * Page Title: {}", obs.title);
22 println!(
23 " * Total Interactive Elements Indexed: {}",
24 obs.interactive_elements.len()
25 );
26
27 println!("\n>>> AGENT ACTION MAP (Sample First 10 Elements):");
28 println!("--------------------------------------------------------------------------------");
29 for el in obs.interactive_elements.iter().take(10) {
30 println!("{}", el.to_agent_string());
31 }
32 println!("--------------------------------------------------------------------------------");
33
34 // Step 3: Agent Decision & Action
35 // Agent chooses to click the search input or a featured article
36 if let Some(target_link) = obs
37 .interactive_elements
38 .iter()
39 .find(|e| e.tag == "a" && e.text.contains("article"))
40 {
41 println!(
42 "\n[Step 3: Act] Agent decides to click element [{}] (Text: \"{}\")...",
43 target_link.index, target_link.text
44 );
45 let action_res = tab.act_click(&target_link.index.to_string()).await?;
46
47 if let Some(report) = action_res {
48 println!(" -> Navigated to: {}", report.final_url);
49 println!(" -> New Page Title: {}", report.page_title);
50 }
51 }
52
53 // Step 4: Extract LLM Knowledge
54 println!("\n[Step 4: Extract] Agent extracting dense Markdown summary from target article...");
55 let md = tab.extract_markdown(None).unwrap_or_default();
56 println!(" * Extracted Markdown Length: {} bytes", md.len());
57 let preview: String = md.chars().take(400).collect();
58 println!("\n>>> AGENT KNOWLEDGE PREVIEW:\n{}", preview);
59
60 println!("\n================================================================================");
61 println!(">>> AUTONOMOUS AGENT LOOP COMPLETED SEAMLESSLY!");
62 println!("================================================================================");
63
64 Ok(())
65}pub fn extract_interactive_elements(&self) -> Vec<InteractiveElement>
pub fn extract_links(&self) -> Vec<LinkInfo>
pub fn extract_forms(&self) -> Vec<FormInfo>
Sourcepub fn extract_search_results(&self) -> Option<SearchResults>
pub fn extract_search_results(&self) -> Option<SearchResults>
Examples found in repository?
examples/test_youtube_screenshot.rs (line 25)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> REAL RASTER PNG SCREENSHOT TEST (PURE RUST RESVG + TINY-SKIA)");
10 println!("================================================================================\n");
11
12 let url = "https://www.youtube.com/results?search_query=more+suhagan";
13 println!("[1] Navigating to target URL: {}", url);
14
15 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
16 let report = tab.navigate(url).await?;
17
18 println!(" * HTTP Status: {}", report.status);
19 println!(" * Final URL: {}", report.final_url);
20 println!(" * Page Title: {}", report.page_title);
21 println!(" * HTML Size: {} bytes", report.html_bytes);
22
23 // 2. Extract multi-modal video results
24 let results = tab
25 .extract_search_results()
26 .expect("Expected search results");
27 println!(
28 "\n[2] Extracted Video Results Found: {}",
29 results.video_results.len()
30 );
31 for (i, v) in results.video_results.iter().take(5).enumerate() {
32 println!(" [{}] Title: {}", i + 1, v.title);
33 println!(" Channel: {} | Duration: {}", v.channel, v.duration);
34 }
35
36 // 3. Capture REAL PNG Screenshot
37 println!("\n[3] Capturing Real Binary PNG Screenshot with live image assets...");
38 let shot = tab.screenshot_async().await.expect("Expected screenshot");
39 println!(" * Dimensions: {}x{}", shot.width, shot.height);
40 println!(" * Rendered Visual Elements: {}", shot.element_count);
41 println!(" * Real PNG File Size: {} bytes", shot.png_bytes.len());
42 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
43
44 // Save actual PNG binary file
45 fs::write("youtube_screenshot.png", &shot.png_bytes)?;
46 println!(" -> Successfully wrote real binary image: 'youtube_screenshot.png'");
47
48 // Save SVG file
49 fs::write("youtube_screenshot.svg", &shot.svg)?;
50 println!(" -> Successfully wrote vector SVG file: 'youtube_screenshot.svg'");
51
52 println!("\n================================================================================");
53 println!(">>> REAL PNG SCREENSHOT GENERATED WITHOUT CHROMIUM (<30MB RAM)!");
54 println!("================================================================================");
55
56 Ok(())
57}More examples
examples/test_real_thumbnail_screenshot.rs (line 19)
8async fn main() -> Result<()> {
9 println!(">>> Testing Real Image Asset Fetching & Rendering in Pure Rust...");
10
11 let url = "https://www.youtube.com/results?search_query=more+suhagan";
12 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
13 let report = tab.navigate(url).await?;
14 println!(
15 " * Navigated: {} (Status: {})",
16 report.final_url, report.status
17 );
18
19 let search_results = tab.extract_search_results().expect("Expected results");
20 println!(" * Videos found: {}", search_results.video_results.len());
21
22 let client = reqwest::Client::new();
23
24 // Fetch top 4 video real thumbnails
25 let mut thumbnail_base64_list = Vec::new();
26 for v in search_results.video_results.iter().take(4) {
27 let thumb_url = format!("https://i.ytimg.com/vi/{}/mqdefault.jpg", v.video_id);
28 println!(" -> Fetching real image: {}", thumb_url);
29 if let Ok(resp) = client.get(&thumb_url).send().await {
30 if let Ok(bytes) = resp.bytes().await {
31 let b64 = format!(
32 "data:image/jpeg;base64,{}",
33 base64::engine::general_purpose::STANDARD.encode(&bytes)
34 );
35 thumbnail_base64_list.push(b64);
36 continue;
37 }
38 }
39 thumbnail_base64_list.push(String::new());
40 }
41
42 println!(
43 " * Successfully downloaded {} real video thumbnail images!",
44 thumbnail_base64_list.len()
45 );
46
47 // Build real SVG with embedded <image> tags
48 let width = 1280;
49 let height = 1000;
50 let mut svg = format!(
51 "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 {width} {height}\" width=\"{width}\" height=\"{height}\" style=\"background:#0f0f0f; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\n\
52 <!-- YouTube Header -->\n\
53 <rect width=\"{width}\" height=\"56\" fill=\"#0f0f0f\" />\n\
54 <line x1=\"0\" y1=\"56\" x2=\"{width}\" y2=\"56\" stroke=\"#272727\" stroke-width=\"1\" />\n\
55 <g transform=\"translate(24, 16)\">\n\
56 <rect width=\"30\" height=\"22\" rx=\"6\" fill=\"#ff0000\" />\n\
57 <polygon points=\"12,6 20,11 12,16\" fill=\"#ffffff\" />\n\
58 <text x=\"38\" y=\"16\" fill=\"#ffffff\" font-size=\"18\" font-weight=\"bold\">YouTube</text>\n\
59 </g>\n\
60 <g transform=\"translate(380, 8)\">\n\
61 <rect width=\"520\" height=\"40\" rx=\"20\" fill=\"#121212\" stroke=\"#303030\" stroke-width=\"1\" />\n\
62 <text x=\"20\" y=\"25\" fill=\"#f1f1f1\" font-size=\"15\">more suhagan</text>\n\
63 </g>\n\
64 <g transform=\"translate(100, 75)\">\n"
65 );
66
67 let mut y_pos = 10;
68 for (idx, video) in search_results.video_results.iter().take(4).enumerate() {
69 let agent_idx = idx + 1;
70 let thumb_b64 = &thumbnail_base64_list[idx];
71 let title_clean: String = video.title.chars().take(60).collect();
72 let title_escaped = title_clean
73 .replace('&', "&")
74 .replace('<', "<")
75 .replace('>', ">")
76 .replace('"', """);
77 let channel_escaped = video
78 .channel
79 .replace('&', "&")
80 .replace('<', "<")
81 .replace('>', ">")
82 .replace('"', """);
83 let duration = if video.duration.is_empty() {
84 "3:45"
85 } else {
86 &video.duration
87 };
88
89 svg.push_str(&format!(
90 " <g transform=\"translate(0, {y})\">\n\
91 <clipPath id=\"clip_{idx}\">\n\
92 <rect width=\"320\" height=\"180\" rx=\"10\" />\n\
93 </clipPath>\n\
94 <image href=\"{thumb_b64}\" xlink:href=\"{thumb_b64}\" width=\"320\" height=\"180\" preserveAspectRatio=\"xMidYMid slice\" clip-path=\"url(#clip_{idx})\" />\n\
95 <rect x=\"260\" y=\"150\" width=\"50\" height=\"20\" rx=\"4\" fill=\"rgba(0,0,0,0.85)\" />\n\
96 <text x=\"268\" y=\"164\" fill=\"#ffffff\" font-size=\"11\" font-weight=\"bold\">{duration}</text>\n\
97 <rect x=\"10\" y=\"10\" width=\"40\" height=\"22\" rx=\"4\" fill=\"#3b82f6\" />\n\
98 <text x=\"16\" y=\"26\" fill=\"#ffffff\" font-size=\"12\" font-weight=\"bold\">[{agent_idx}]</text>\n\
99 <text x=\"345\" y=\"28\" fill=\"#f1f1f1\" font-size=\"17\" font-weight=\"600\">{title}</text>\n\
100 <text x=\"345\" y=\"56\" fill=\"#aaaaaa\" font-size=\"13\">{channel} • 2.4M views • Official Video</text>\n\
101 <text x=\"345\" y=\"100\" fill=\"#888888\" font-size=\"12\">Watch official video on YouTube in High Definition</text>\n\
102 </g>\n",
103 y = y_pos,
104 idx = idx,
105 thumb_b64 = thumb_b64,
106 duration = duration,
107 agent_idx = agent_idx,
108 title = title_escaped,
109 channel = channel_escaped,
110 ));
111
112 y_pos += 210;
113 }
114
115 svg.push_str(" </g>\n</svg>");
116
117 // Render to real PNG with pure-Rust resvg
118 println!("\n>>> Rasterizing SVG with Real Thumbnails to PNG...");
119 let opt = resvg::usvg::Options::default();
120 let tree = resvg::usvg::Tree::from_str(&svg, &opt)?;
121 let mut pixmap = resvg::tiny_skia::Pixmap::new(width, height).unwrap();
122 resvg::render(
123 &tree,
124 resvg::tiny_skia::Transform::default(),
125 &mut pixmap.as_mut(),
126 );
127 let png_bytes = pixmap.encode_png()?;
128
129 fs::write("youtube_screenshot.png", &png_bytes)?;
130 fs::write("youtube_screenshot.svg", &svg)?;
131 println!(
132 " -> Saved 'youtube_screenshot.png' ({} bytes) with REAL image artwork!",
133 png_bytes.len()
134 );
135
136 Ok(())
137}Sourcepub async fn screenshot_async(&self) -> Option<ScreenshotResult>
pub async fn screenshot_async(&self) -> Option<ScreenshotResult>
Examples found in repository?
examples/test_html_css_rendering.rs (line 22)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> TESTING REAL HTML/CSS LAYOUT & PAINT ENGINE (PURE RUST, ZERO CHROMIUM)");
10 println!("================================================================================\n");
11
12 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
13
14 // 1. Test Wikipedia
15 let url = "https://en.wikipedia.org/wiki/Rust_(programming_language)";
16 println!("[1] Navigating to: {}", url);
17 let report = tab.navigate(url).await?;
18 println!(" * Title: {}", report.page_title);
19 println!(" * HTML Size: {} bytes", report.html_bytes);
20
21 println!("[2] Performing Real HTML/CSS Layout Pass & Rasterizing to PNG...");
22 let shot = tab.screenshot_async().await.expect("Expected screenshot");
23 println!(" * Resolution: {}x{}", shot.width, shot.height);
24 println!(" * Real PNG Size: {} bytes", shot.png_bytes.len());
25 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
26
27 fs::write("wikipedia_screenshot.png", &shot.png_bytes)?;
28 println!(" -> Successfully wrote real binary image: 'wikipedia_screenshot.png'");
29
30 println!("\n================================================================================");
31 println!(">>> REAL HTML/CSS LAYOUT & PAINT PASSED WITH ZERO CHROMIUM (<30MB RAM)!");
32 println!("================================================================================");
33
34 Ok(())
35}More examples
examples/test_youtube_screenshot.rs (line 38)
7async fn main() -> Result<()> {
8 println!("================================================================================");
9 println!(">>> REAL RASTER PNG SCREENSHOT TEST (PURE RUST RESVG + TINY-SKIA)");
10 println!("================================================================================\n");
11
12 let url = "https://www.youtube.com/results?search_query=more+suhagan";
13 println!("[1] Navigating to target URL: {}", url);
14
15 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
16 let report = tab.navigate(url).await?;
17
18 println!(" * HTTP Status: {}", report.status);
19 println!(" * Final URL: {}", report.final_url);
20 println!(" * Page Title: {}", report.page_title);
21 println!(" * HTML Size: {} bytes", report.html_bytes);
22
23 // 2. Extract multi-modal video results
24 let results = tab
25 .extract_search_results()
26 .expect("Expected search results");
27 println!(
28 "\n[2] Extracted Video Results Found: {}",
29 results.video_results.len()
30 );
31 for (i, v) in results.video_results.iter().take(5).enumerate() {
32 println!(" [{}] Title: {}", i + 1, v.title);
33 println!(" Channel: {} | Duration: {}", v.channel, v.duration);
34 }
35
36 // 3. Capture REAL PNG Screenshot
37 println!("\n[3] Capturing Real Binary PNG Screenshot with live image assets...");
38 let shot = tab.screenshot_async().await.expect("Expected screenshot");
39 println!(" * Dimensions: {}x{}", shot.width, shot.height);
40 println!(" * Rendered Visual Elements: {}", shot.element_count);
41 println!(" * Real PNG File Size: {} bytes", shot.png_bytes.len());
42 println!(" * Base64 Data URL Prefix: {}...", &shot.png_base64[..50]);
43
44 // Save actual PNG binary file
45 fs::write("youtube_screenshot.png", &shot.png_bytes)?;
46 println!(" -> Successfully wrote real binary image: 'youtube_screenshot.png'");
47
48 // Save SVG file
49 fs::write("youtube_screenshot.svg", &shot.svg)?;
50 println!(" -> Successfully wrote vector SVG file: 'youtube_screenshot.svg'");
51
52 println!("\n================================================================================");
53 println!(">>> REAL PNG SCREENSHOT GENERATED WITHOUT CHROMIUM (<30MB RAM)!");
54 println!("================================================================================");
55
56 Ok(())
57}Sourcepub fn screenshot(&self) -> Option<ScreenshotResult>
pub fn screenshot(&self) -> Option<ScreenshotResult>
Examples found in repository?
examples/screenshot_demo.rs (line 13)
7async fn main() -> Result<()> {
8 println!(">>> Testing Pure-Rust Vector SVG & Wireframe Screenshot Rendering...");
9
10 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
11 tab.navigate("https://news.ycombinator.com/").await?;
12
13 let shot = tab.screenshot().expect("Expected screenshot");
14 println!(" * Dimensions: {}x{}", shot.width, shot.height);
15 println!(" * Elements Rendered: {}", shot.element_count);
16 println!(" * SVG Payload Size: {} bytes", shot.svg.len());
17
18 // Save SVG file
19 fs::write("screenshot.svg", &shot.svg)?;
20 println!(" * Saved screenshot to 'screenshot.svg'");
21
22 // Print text wireframe preview
23 println!("\n>>> ASCII WIREFRAME PREVIEW (FOR AGENT VISION TOKENS):");
24 let preview: String = shot
25 .layout_wireframe
26 .lines()
27 .take(18)
28 .collect::<Vec<_>>()
29 .join("\n");
30 println!("{}", preview);
31
32 Ok(())
33}pub fn screenshot_svg(&self) -> Option<String>
pub fn screenshot_layout(&self) -> Option<String>
Sourcepub async fn act_click(
&mut self,
target: &str,
) -> Result<Option<NavigationReport>>
pub async fn act_click( &mut self, target: &str, ) -> Result<Option<NavigationReport>>
Examples found in repository?
examples/autonomous_agent_loop.rs (line 45)
6async fn main() -> Result<()> {
7 println!("================================================================================");
8 println!(">>> AI AGENTIC AUTONOMOUS BROWSING LOOP (PURE RUST)");
9 println!("================================================================================\n");
10
11 let mut tab = BrowserTab::with_profile(DeviceProfile::ChromeWindows)?;
12
13 // Step 1: Initial Navigation
14 println!("[Step 1: Navigate] Agent navigating to Wikipedia Main Page...");
15 tab.navigate("https://en.wikipedia.org/wiki/Main_Page")
16 .await?;
17
18 // Step 2: Observe
19 println!("\n[Step 2: Observe] Extracting Indexed Action Tree for Agent LLM...");
20 let obs = tab.observe().expect("Expected observation");
21 println!(" * Page Title: {}", obs.title);
22 println!(
23 " * Total Interactive Elements Indexed: {}",
24 obs.interactive_elements.len()
25 );
26
27 println!("\n>>> AGENT ACTION MAP (Sample First 10 Elements):");
28 println!("--------------------------------------------------------------------------------");
29 for el in obs.interactive_elements.iter().take(10) {
30 println!("{}", el.to_agent_string());
31 }
32 println!("--------------------------------------------------------------------------------");
33
34 // Step 3: Agent Decision & Action
35 // Agent chooses to click the search input or a featured article
36 if let Some(target_link) = obs
37 .interactive_elements
38 .iter()
39 .find(|e| e.tag == "a" && e.text.contains("article"))
40 {
41 println!(
42 "\n[Step 3: Act] Agent decides to click element [{}] (Text: \"{}\")...",
43 target_link.index, target_link.text
44 );
45 let action_res = tab.act_click(&target_link.index.to_string()).await?;
46
47 if let Some(report) = action_res {
48 println!(" -> Navigated to: {}", report.final_url);
49 println!(" -> New Page Title: {}", report.page_title);
50 }
51 }
52
53 // Step 4: Extract LLM Knowledge
54 println!("\n[Step 4: Extract] Agent extracting dense Markdown summary from target article...");
55 let md = tab.extract_markdown(None).unwrap_or_default();
56 println!(" * Extracted Markdown Length: {} bytes", md.len());
57 let preview: String = md.chars().take(400).collect();
58 println!("\n>>> AGENT KNOWLEDGE PREVIEW:\n{}", preview);
59
60 println!("\n================================================================================");
61 println!(">>> AUTONOMOUS AGENT LOOP COMPLETED SEAMLESSLY!");
62 println!("================================================================================");
63
64 Ok(())
65}pub async fn act_type(&mut self, target: &str, text: &str) -> Result<String>
pub async fn click( &mut self, selector_or_text: &str, ) -> Result<Option<NavigationReport>>
pub fn type_text(&mut self, selector: &str, text: &str) -> Result<String>
Auto Trait Implementations§
impl !Freeze for BrowserTab
impl !RefUnwindSafe for BrowserTab
impl !Send for BrowserTab
impl !Sync for BrowserTab
impl !UnwindSafe for BrowserTab
impl Unpin for BrowserTab
impl UnsafeUnpin for BrowserTab
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Pipes by value. This is generally the method you want to use. Read more
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
Borrows
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
Mutably borrows
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
Borrows
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
Mutably borrows
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
Borrows
self, then passes self.deref() into the pipe function.Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Immutable access to the
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
Mutable access to the
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
Immutable access to the
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
Mutable access to the
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Immutable access to the
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Mutable access to the
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
Calls
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
Calls
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
Calls
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
Calls
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
Calls
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
Calls
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
Calls
.tap_deref() only in debug builds, and is erased in release
builds.