use std::time::Duration;
use computeruse::{AutomationError, Desktop};
#[tokio::main]
async fn main() -> Result<(), AutomationError> {
println!("๐ Element OCR Demo");
println!("==================");
let desktop = Desktop::new(false, false)?;
println!("\n๐ฑ Opening Notepad...");
let notepad = desktop.open_application("notepad")?;
std::thread::sleep(Duration::from_millis(2000));
println!("โจ๏ธ Typing sample text...");
let locator = desktop.locator("role:Document");
let text_area = locator.first(None).await?;
text_area.type_text(
"Hello World!\nThis is a test for OCR functionality.\nLine 3: Special characters @#$%",
false,
)?;
std::thread::sleep(Duration::from_millis(1000));
println!("\n๐ Testing OCR on different elements:");
println!("\n1. OCR on document text area:");
match text_area.ocr().await {
Ok(ocr_text) => {
println!(" โ
OCR Success!");
println!(" ๐ Extracted text: \"{}\"", ocr_text.trim());
println!(" ๐ Length: {} characters", ocr_text.len());
}
Err(e) => {
println!(" โ OCR failed: {e}");
}
}
println!("\n2. Comparison with native text() method:");
match text_area.text(3) {
Ok(native_text) => {
println!(" โ
Native text: \"{}\"", native_text.trim());
println!(" ๐ Length: {} characters", native_text.len());
}
Err(e) => {
println!(" โ Native text failed: {e}");
}
}
println!("\n3. OCR on window title bar:");
let title_locator = desktop.locator("role:TitleBar");
match title_locator.first(None).await {
Ok(title_bar) => match title_bar.ocr().await {
Ok(title_text) => {
println!(" โ
Title OCR Success!");
println!(" ๐ Title text: \"{}\"", title_text.trim());
if title_text.to_lowercase().contains("notepad") {
println!(" ๐ฏ Correctly detected 'Notepad' in title!");
}
}
Err(e) => {
println!(" โ Title OCR failed: {e}");
}
},
Err(e) => {
println!(" โ Could not find title bar: {e}");
}
}
println!("\n4. OCR on menu items:");
let menu_locator = desktop.locator("role:MenuBar");
match menu_locator.first(None).await {
Ok(menu_bar) => {
println!(" ๐ Found menu bar, testing OCR...");
match menu_bar.ocr().await {
Ok(menu_text) => {
println!(" โ
Menu OCR Success!");
println!(" ๐ Menu text: \"{}\"", menu_text.trim());
let menu_lower = menu_text.to_lowercase();
let found_items: Vec<&str> = ["file", "edit", "format", "view", "help"]
.iter()
.filter(|&&item| menu_lower.contains(item))
.copied()
.collect();
if !found_items.is_empty() {
println!(" ๐ฏ Detected menu items: {found_items:?}");
}
}
Err(e) => {
println!(" โ Menu OCR failed: {e}");
}
}
}
Err(e) => {
println!(" โ Could not find menu bar: {e}");
}
}
println!("\n5. Performance comparison:");
let start = std::time::Instant::now();
let _ocr_result = text_area.ocr().await;
let ocr_duration = start.elapsed();
let start = std::time::Instant::now();
let _capture_result = text_area.capture();
let capture_duration = start.elapsed();
println!(" โฑ๏ธ Capture only: {capture_duration:?}");
println!(" โฑ๏ธ OCR (capture + recognition): {ocr_duration:?}");
println!(" ๐ OCR overhead: {:?}", ocr_duration - capture_duration);
println!("\n๐งน Cleaning up...");
notepad.close()?;
println!("\nโ
Element OCR demo completed!");
println!("\n๐ก Key takeaways:");
println!(" โข Use element.ocr() for extracting text from visual elements");
println!(" โข OCR works best on clear, well-rendered text");
println!(" โข Compare with native text() methods when available");
println!(" โข OCR is particularly useful for elements that don't expose text via accessibility APIs");
Ok(())
}