wasm_bench 0.2.0

benchmarker for in browser wasm
#![feature(exit_status_error)]

use std::fs;
use std::time::Duration;

use owo_colors::OwoColorize;
use thirtyfour::prelude::*;
use tokio::process::{Child, Command};
use tokio::time::sleep;

const HTML: &str = "
<head>
    <link data-trunk rel='rust' href='Cargo.toml' />
</head>
<body></body>
";

async fn serve_project() -> (tempfile::TempDir, tempfile::NamedTempFile, Child) {
    let out = tempfile::TempDir::new().unwrap();
    let html_file = tempfile::NamedTempFile::new_in(".").unwrap();
    fs::write(html_file.path(), HTML).unwrap();

    println!(
        "{} Building using Trunk outputting in {}",
        "[1/5]".bright_black(),
        out.path().as_os_str().to_string_lossy().blue(),
    );

    Command::new("trunk")
        .arg("build")
        .arg(html_file.path())
        .arg("--dist")
        .arg(out.path())
        .arg("--release")
        .status()
        .await
        .unwrap()
        .exit_ok()
        .unwrap();

    println!("{} Serving trunk page", "[2/5]".bright_black(),);
    let child = Command::new("trunk")
        .arg("serve")
        .arg(html_file.path())
        .arg("--dist")
        .arg(out.path())
        .arg("--port")
        .arg("8888")
        .arg("--ignore")
        .arg(".")
        .arg("--release")
        .kill_on_drop(true)
        .spawn()
        .unwrap();
    sleep(Duration::from_secs(1)).await;

    (out, html_file, child)
}

fn start_chromedriver() -> Child {
    Command::new("chromedriver")
        .arg("--port=3794")
        .kill_on_drop(true)
        .spawn()
        .unwrap()
}

async fn run_and_get_dom() {
    println!("{} Spawning Chrome", "[3/5]".bright_black(),);
    let mut chrome = start_chromedriver();
    sleep(Duration::from_secs(1)).await;

    let mut caps = DesiredCapabilities::chrome();
    //caps.set_headless().unwrap();

    println!("{} Connecting to chrome", "[4/5]".bright_black(),);
    let driver = WebDriver::new("http://localhost:3794", caps).await.unwrap();

    println!("{} Running benchmarks", "[5/5]".bright_black(),);

    driver.goto("http://localhost:8888").await.unwrap();

    let mut i = 0;
    let mut conseq_fail = 0;
    loop {
        if let Ok(result_node) = driver.find(By::Id(format!("wasm_bench_result_{i}"))).await {
            conseq_fail = 0;
            let result = result_node.text().await.unwrap();
            println!("{result}");
            i += 1;
        } else if driver.find(By::Id("wasm_bench_done")).await.is_ok() && conseq_fail >= 10 {
            break;
        } else {
            sleep(Duration::from_millis(100)).await;
            conseq_fail += 1;

            if conseq_fail > 10 * 5 * 4 {
                println!("Benchmark running for 20s, likely paniced, closing.");
                break;
            }
        }
    }

    driver.close_window().await.unwrap();
    chrome.kill().await.unwrap();
    chrome.wait().await.unwrap();
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let (_dist, _html_file, mut server) = serve_project().await;
    run_and_get_dom().await;

    server.kill().await.unwrap();
    server.wait().await.unwrap();
}