use std::env; use which::which; // collection of parameters that may speed up the chromium perf on headless #[allow(unused)] fn speed_params() -> Vec<&'static str> { let params = ["--disable-canvas-aa", // Disable antialiasing on 2d canvas "--disable-2d-canvas-clip-aa", // Disable antialiasing on 2d canvas clips "--disable-gl-drawing-for-tests", // BEST OPTION EVER! Disables GL drawing operations which produce pixel output. With this the GL output will not be correct but tests will run faster. "--disable-dev-shm-usage", // ??? "--no-zygote", // wtf does that mean ? "--use-gl=swiftshader", // better cpu usage with --use-gl=desktop rather than --use-gl=swiftshader, still needs more testing. "--enable-webgl", "--hide-scrollbars", "--mute-audio", "--no-first-run", "--disable-infobars", "--disable-breakpad", "--window-size=1280,1024", // see defaultViewport "--no-sandbox", // meh but better resource comsuption "--disable-setuid-sandbox", "--ignore-certificate-errors", "--disable-extensions", "--disable-gpu", "--no-sandbox"]; Vec::from(params) } #[allow(unused)] pub fn headless_params(log: bool) -> Vec { let binding = std::env::temp_dir(); let dir = binding.to_str().unwrap(); let mut params = speed_params(); let data_dir = String::from("--user-data-dir=") + dir; let mut p = vec!("--headless", "--remote-debugging-port=9222"); p.push(data_dir.as_str()); if cfg!(target_os = "windows") { p.push(" --no-sandbox"); p.push("--disable-gpu"); } if log { p.push("--enable-logging --v=0"); } else { p.push("--disable-logging"); } params.append(&mut p); params.into_iter().map(|s| {String::from(s)} ).collect() } #[allow(unused)] pub fn system_chrome() -> Option<(String, Vec)> { if cfg!(target_os = "unix") || cfg!(target_os = "linux") { for browser in vec!("chromium-chrome", "google-chrome").into_iter() { if which(&browser).is_ok() { return Some((String::from(browser), Vec::new())); } } } if cfg!(target_os = "macos") { // it has not been need for result, change if not found let result = which("google-chrome"); return match(result) { Ok(path) => Some((path.to_str().unwrap().to_string(), Vec::new())), Err(_) => Some((String::from(r#"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"#), Vec::new())) } } if cfg!(target_os = "windows") { // Chrome installer wont update the PATH so we do an educated guess... let mut path = env::var("PATH").expect("PATH is not set!"); if ! path.contains("chrome") { let path = format!("{};{}", r#"C:\Program Files (x86)\Google\Chrome\Application"#, path); env::set_var("PATH", path); } let result = which("chrome").expect("Tests requires that chrome is installed!"); return Some(( result.to_str().unwrap().to_string(), Vec::new())); } None } #[allow(unused)] pub fn kill_headless() -> bool { let cmd = if cfg!(target_os = "windows") { ("powershell.exe", vec!("-command", r#""Get-CimInstance -ClassName Win32_Process -Filter 'CommandLine LIKE ''%--headless%'' | %{Stop-Process -Id $_.ProcessId}""#)) } else if cfg!(target_os = "macos") { //("pkill", vec!(r#"-f \"(chrome)?(--headless)\""#)) ("pkill", vec!("-f", r#"Google Chrome.*headless"#)) } else { if(which("chromium-chrome").is_ok()) { ("pkill", vec!("-f", r#"chromium.*headless"#)) } else { ("pkill", vec!("-f", r#"chrome.*headless"#)) } }; let output = std::process::Command::new(cmd.0) .args(&cmd.1) .output(); match output { Ok(out) => { if !out.status.success() { if out.status.code().unwrap() != 1 { println!("kill headless status: {}", out.status); let cout = std::str::from_utf8(&out.stdout); let cerr = std::str::from_utf8(&out.stderr); println!("headless kill: out: {}\n err: {} call {} {}", cout.unwrap_or("???"), cerr.unwrap_or("???"), cmd.0, cmd.1.join(" ")); return false; } } else { println!("UI killed ok"); } true // here we get handle to spawned UI - not used now as exit is done nicely }, Err(e) => { eprintln!("Kill error: {}", e); false } } }