use std::{process::Command, error::Error, fs, env, time::Duration, path::Path}; use fantoccini::{ClientBuilder, Locator}; use log::info; use tokio::time; use clap::Parser; static PROFILE_ROOT: &str = "/tmp/geckodriver-dashboard"; /// Simple program to greet a person #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// Input HTML file. #[arg(short, long)] input_path: String, /// Output path for png image. #[arg(short, long)] output_path: String, /// CSS locator to generate screenshot for. #[arg(default_value_t = String::from("#app"))] element_locator: String, } // let's set up the sequence of steps we want the browser to take #[tokio::main] async fn main() -> Result<(), Box> { pretty_env_logger::init(); let args = Args::parse(); let display = ":5"; // env::var("DISPLAY")?; let _xvfb = Command::new("Xvfb") .arg(display).spawn()?; info!("Current directory: {}", env::current_dir()?.display()); fs::create_dir(PROFILE_ROOT).ok(); let _geckodriver = Command::new("geckodriver") .env("MOZ_REMOTE_SETTINGS_DEVTOOLS", "1") .env("DISPLAY", display) .arg("--profile-root").arg("/tmp/geckodriver-dashboard").spawn()?; let c = ClientBuilder::native().connect("http://localhost:4444").await.expect("failed to connect to WebDriver"); loop { let path = fs::canonicalize(&args.input_path)?; info!("Opening {}", path.display()); c.goto(&format!("file://{}", path.display())).await?; let e = c.find(Locator::Css(&args.element_locator)).await?; let img = e.screenshot().await?; let output_path = Path::new(&args.output_path); let tmp_path = output_path.with_extension("png.tmp"); fs::write(&tmp_path, img)?; Command::new("mogrify") .arg("-colorspace") .arg("gray") .arg(tmp_path.as_os_str()) .spawn()?.wait()?; fs::rename(&tmp_path, output_path)?; time::sleep(Duration::from_secs(15)).await; info!("Wrote {}", output_path.display()); } // c.close().await?; // geckodriver.kill()?; // Ok(()) }