interop/build/web/
webdriver.rs

1use crate::util::RunningProcess;
2use color_eyre::eyre::Result;
3
4pub(crate) async fn setup_webdriver(force: bool) -> Result<()> {
5    let mut spinner = RunningProcess::new("Setting up WebDriver & co...", false);
6
7    let wd_dir = dirs::home_dir().unwrap().join(".webdrivers");
8    let chrome = webdriver_installation::WebdriverKind::Chrome;
9
10    if force {
11        spinner.update("FORCE_WEBDRIVER_INSTALL is set. Forcefully removing webdrivers...");
12        std::fs::remove_dir(&wd_dir)?;
13    }
14
15    if !wd_dir.join(chrome.as_exe_name()).exists() {
16        spinner.update("Chrome WebDriver isn't installed. Installing...");
17        chrome.install_webdriver(&wd_dir, force).await?;
18    }
19
20    spinner.update("Chrome WebDriver installed");
21
22    spinner.success("WebDriver setup [OK]");
23
24    Ok(())
25}
26
27pub(crate) async fn start_webdriver_chrome(addr: &std::net::SocketAddr) -> Result<tokio::process::Child> {
28    let wd_dir = dirs::home_dir().unwrap().join(".webdrivers");
29
30    Ok(tokio::process::Command::new(wd_dir.join("chromedriver"))
31        .arg(format!("--port={}", addr.port()))
32        .stdout(std::process::Stdio::null())
33        .stderr(std::process::Stdio::null())
34        .spawn()?)
35}
36
37pub(crate) async fn setup_browser(
38    client: &std::net::SocketAddr,
39    server: &std::net::SocketAddr,
40    folder: &str,
41) -> Result<fantoccini::Client> {
42    let spinner = RunningProcess::new("Starting Fantoccini remote browser...", false);
43    let mut caps_json = serde_json::json!({
44        "goog:chromeOptions": {
45            "args": [
46                "headless=shell",
47                "disable-dev-shm-usage",
48                "no-sandbox"
49            ]
50        }
51    });
52
53    if let Ok(chrome_path) = std::env::var("CHROME_PATH") {
54        caps_json["goog:chromeOptions"]["binary"] = chrome_path.into();
55    }
56
57    let serde_json::Value::Object(caps) = caps_json else {
58        unreachable!("`serde_json::json!()` did not produce an object when provided an object. Something is broken.")
59    };
60
61    let browser = fantoccini::ClientBuilder::native()
62        .capabilities(caps)
63        .connect(&format!("http://{client}"))
64        .await?;
65    browser.goto(&format!("http://{server}/{folder}/index.html")).await?;
66
67    spinner.success("Browser [OK]");
68    Ok(browser)
69}