From 0ca48923f56d2a547f1dbb4be26c2a1a391cd859 Mon Sep 17 00:00:00 2001 From: slhx agent Date: Mon, 13 Jul 2026 10:24:36 +0200 Subject: [PATCH] test(browser): use owned process harness --- examples/techdemo/tests/browser_e2e.rs | 46 ++++---------------------- examples/workout/tests/browser_e2e.rs | 45 ++++--------------------- 2 files changed, 14 insertions(+), 77 deletions(-) diff --git a/examples/techdemo/tests/browser_e2e.rs b/examples/techdemo/tests/browser_e2e.rs index 6e54196..7ea3375 100644 --- a/examples/techdemo/tests/browser_e2e.rs +++ b/examples/techdemo/tests/browser_e2e.rs @@ -2,49 +2,28 @@ use hemx_techdemo::ui::control_center::{self as control, launch_work, simulate_p use hemx_test::{ any_root_selector, document_body_selector, handle_button_selector, handle_selector, island_probe_script, island_readout_selector, keyed_selector, nav_link_selector, - scoped_island_readout_selector, target_selector, + scoped_island_readout_selector, target_selector, TestProcess, }; -use std::process::{Child, Command, Stdio}; +use std::process::Command; use std::time::{Duration, Instant}; use thirtyfour::prelude::*; const APP_ADDR: &str = "127.0.0.1:3012"; const WEBDRIVER_ADDR: &str = "127.0.0.1:4445"; - -struct ChildProcess { - child: Child, -} - -impl ChildProcess { - fn spawn(mut command: Command) -> Self { - let child = command - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .expect("spawn child process"); - Self { child } - } -} - -impl Drop for ChildProcess { - fn drop(&mut self) { - let _ = self.child.kill(); - let _ = self.child.wait(); - } -} +const STARTUP_TIMEOUT: Duration = Duration::from_secs(8); #[tokio::test] async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> { // req: examples/001 req: dx/008 req: form/002 req: page_swap/002 req: push/003 let mut app = Command::new(env!("CARGO_BIN_EXE_hemx-techdemo")); app.env("HEMX_TECHDEMO_ADDR", APP_ADDR); - let _app = ChildProcess::spawn(app); - wait_for_tcp(APP_ADDR); + let _app = TestProcess::start(app, "hemx-techdemo", APP_ADDR, STARTUP_TIMEOUT) + .expect("start ready hemx-techdemo"); let mut webdriver = Command::new("geckodriver"); webdriver.arg("--port").arg("4445"); - let _webdriver = ChildProcess::spawn(webdriver); - wait_for_tcp(WEBDRIVER_ADDR); + let _webdriver = TestProcess::start(webdriver, "geckodriver", WEBDRIVER_ADDR, STARTUP_TIMEOUT) + .expect("start ready geckodriver"); let mut caps = DesiredCapabilities::firefox(); caps.set_headless()?; @@ -125,17 +104,6 @@ async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> { result.and(quit) } -fn wait_for_tcp(addr: &str) { - let deadline = Instant::now() + Duration::from_secs(8); - while Instant::now() < deadline { - if std::net::TcpStream::connect(addr).is_ok() { - return; - } - std::thread::sleep(Duration::from_millis(25)); - } - panic!("timed out waiting for {addr}"); -} - async fn insert_probe_island(driver: &WebDriver) -> WebDriverResult<()> { let root = driver.find(By::Css(any_root_selector())).await?; let script = island_probe_script( diff --git a/examples/workout/tests/browser_e2e.rs b/examples/workout/tests/browser_e2e.rs index 39a49e7..b96ae12 100644 --- a/examples/workout/tests/browser_e2e.rs +++ b/examples/workout/tests/browser_e2e.rs @@ -1,44 +1,24 @@ -use std::process::{Child, Command, Stdio}; +use hemx_test::TestProcess; +use std::process::Command; use std::time::{Duration, Instant}; use thirtyfour::prelude::*; const APP_ADDR: &str = "127.0.0.1:3037"; const WEBDRIVER_ADDR: &str = "127.0.0.1:4447"; - -struct ChildProcess { - child: Child, -} - -impl ChildProcess { - fn spawn(mut command: Command) -> Self { - let child = command - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .expect("spawn child process"); - Self { child } - } -} - -impl Drop for ChildProcess { - fn drop(&mut self) { - let _ = self.child.kill(); - let _ = self.child.wait(); - } -} +const STARTUP_TIMEOUT: Duration = Duration::from_secs(8); #[tokio::test] async fn browser_proves_phone_first_workout_flow() -> WebDriverResult<()> { // req: examples/001 req: local/001 req: host/002 let mut app = Command::new(env!("CARGO_BIN_EXE_hemx-workout-example")); app.env("HEMX_WORKOUT_ADDR", APP_ADDR); - let _app = ChildProcess::spawn(app); - wait_for_tcp(APP_ADDR); + let _app = TestProcess::start(app, "hemx-workout-example", APP_ADDR, STARTUP_TIMEOUT) + .expect("start ready hemx-workout-example"); let mut webdriver = Command::new("geckodriver"); webdriver.arg("--port").arg("4447"); - let _webdriver = ChildProcess::spawn(webdriver); - wait_for_tcp(WEBDRIVER_ADDR); + let _webdriver = TestProcess::start(webdriver, "geckodriver", WEBDRIVER_ADDR, STARTUP_TIMEOUT) + .expect("start ready geckodriver"); let mut caps = DesiredCapabilities::firefox(); caps.set_headless()?; @@ -87,17 +67,6 @@ async fn browser_proves_phone_first_workout_flow() -> WebDriverResult<()> { result.and(quit) } -fn wait_for_tcp(addr: &str) { - let deadline = Instant::now() + Duration::from_secs(8); - while Instant::now() < deadline { - if std::net::TcpStream::connect(addr).is_ok() { - return; - } - std::thread::sleep(Duration::from_millis(25)); - } - panic!("timed out waiting for {addr}"); -} - async fn wait_for_runtime(driver: &WebDriver) -> WebDriverResult<()> { let deadline = Instant::now() + Duration::from_secs(8); loop {