Skip to content

Commit d3a0cd1

Browse files
committed
webdriver refactor
Signed-off-by: Andrei Gherghescu <[email protected]>
1 parent a31eff6 commit d3a0cd1

File tree

2 files changed

+84
-63
lines changed

2 files changed

+84
-63
lines changed

plotly_static/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,7 @@ mod tests {
13111311
assert!(dst.exists());
13121312
let metadata = std::fs::metadata(&dst).expect("Could not retrieve file metadata");
13131313
let file_size = metadata.len();
1314-
assert!(file_size > 0,);
1314+
assert!(file_size > 900000,);
13151315
// assert!(std::fs::remove_file(dst.as_path()).is_ok());
13161316
}
13171317

plotly_static/src/webdriver.rs

Lines changed: 83 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -208,95 +208,116 @@ impl WebDriver {
208208

209209
fn spawn_process(&self, driver_path: &Option<PathBuf>, port: u32) -> Result<Child> {
210210
let driver_path = driver_path.as_ref().unwrap(); // Safe unwrap since we validated above
211-
let mut command = Command::new(driver_path);
212-
command.arg(format!("--port={port}"));
213-
214-
// Add verbose flag only for chromedriver
215-
#[cfg(feature = "chromedriver")]
216-
command.arg("--verbose");
217-
218-
command
219-
.stdin(Stdio::piped())
220-
.stdout(Stdio::piped())
221-
.stderr(Stdio::piped());
222-
223-
info!(
224-
"Executing command: {:?} {:?}",
225-
command.get_program(),
226-
command.get_args()
227-
);
228211

229-
#[cfg(target_os = "windows")]
230-
{
231-
use std::os::windows::process::CommandExt;
232-
// Try with CREATE_NO_WINDOW for headless operation
233-
command.creation_flags(0x08000000); // CREATE_NO_WINDOW flag
234-
}
212+
let mut command = Self::create_command(driver_path, port);
213+
Self::log_command(&command);
235214

236-
// Try to spawn the process
237215
match command.spawn() {
238216
Ok(child) => Ok(child),
239217
Err(e) => {
218+
#[cfg(not(target_os = "windows"))]
219+
{
220+
Err(self.handle_spawn_error(e, &command, "standard method"))
221+
}
240222
#[cfg(target_os = "windows")]
241223
{
242224
// If CREATE_NO_WINDOW fails, try without any special flags
243225
error!("Failed to spawn with CREATE_NO_WINDOW: {e}");
244226
error!("Trying without special creation flags...");
245227

246-
let mut fallback_command = Command::new(driver_path);
247-
fallback_command.arg(format!("--port={port}"));
248-
249-
#[cfg(feature = "chromedriver")]
250-
fallback_command.arg("--verbose");
251-
252-
fallback_command
253-
.stdin(Stdio::piped())
254-
.stdout(Stdio::piped())
255-
.stderr(Stdio::piped());
228+
let mut fallback_command = Self::standard_command(driver_path, port);
229+
Self::log_command(&fallback_command);
256230

257231
match fallback_command.spawn() {
258232
Ok(child) => {
259233
info!("Successfully spawned WebDriver without special creation flags");
260234
Ok(child)
261235
}
262236
Err(fallback_e) => {
263-
error!("Failed to spawn '{WEBDRIVER_BIN}' with fallback method: {fallback_e}");
264237
error!("Original error: {e}");
265238
error!("Fallback error: {fallback_e}");
266-
error!(
267-
"Command was: {:?} {:?}",
268-
command.get_program(),
269-
command.get_args()
270-
);
271-
error!("Windows: Check if antivirus is blocking the process");
272-
error!("Windows: Check if the binary has proper permissions");
273-
error!(
274-
"WebDriver diagnostics after spawn failure:\n{}",
275-
self.get_diagnostics()
276-
);
277-
Err(anyhow!("Failed to spawn '{WEBDRIVER_BIN}': {}", fallback_e))
239+
Err(self.handle_spawn_error(
240+
fallback_e,
241+
&fallback_command,
242+
"fallback method",
243+
))
278244
}
279245
}
280246
}
281-
282-
#[cfg(not(target_os = "windows"))]
283-
{
284-
error!("Failed to spawn '{WEBDRIVER_BIN}': {e}");
285-
error!(
286-
"Command was: {:?} {:?}",
287-
command.get_program(),
288-
command.get_args()
289-
);
290-
error!(
291-
"WebDriver diagnostics after spawn failure:\n{}",
292-
self.get_diagnostics()
293-
);
294-
Err(anyhow!("Failed to spawn '{WEBDRIVER_BIN}': {}", e))
295-
}
296247
}
297248
}
298249
}
299250

251+
/// Creates a command with standard configuration (no Windows flags)
252+
fn standard_command(driver_path: &PathBuf, port: u32) -> Command {
253+
let mut command = Command::new(driver_path);
254+
command.arg(format!("--port={port}"));
255+
256+
// Add verbose flag only for chromedriver
257+
#[cfg(feature = "chromedriver")]
258+
command.arg("--verbose");
259+
260+
command
261+
.stdin(Stdio::piped())
262+
.stdout(Stdio::piped())
263+
.stderr(Stdio::piped());
264+
265+
command
266+
}
267+
268+
/// Creates a command with Windows-specific flags
269+
#[cfg(target_os = "windows")]
270+
fn create_command(driver_path: &PathBuf, port: u32) -> Command {
271+
use std::os::windows::process::CommandExt;
272+
273+
let mut command = Self::standard_command(driver_path, port);
274+
// Try with CREATE_NO_WINDOW for headless operation
275+
command.creation_flags(0x08000000); // CREATE_NO_WINDOW flag
276+
command
277+
}
278+
279+
#[cfg(not(target_os = "windows"))]
280+
fn create_command(driver_path: &PathBuf, port: u32) -> Command {
281+
Self::standard_command(driver_path, port)
282+
}
283+
284+
/// Logs command execution details
285+
fn log_command(command: &Command) {
286+
info!(
287+
"Executing command: {:?} {:?}",
288+
command.get_program(),
289+
command.get_args()
290+
);
291+
}
292+
293+
/// Handles spawn errors with appropriate logging and diagnostics
294+
fn handle_spawn_error(
295+
&self,
296+
e: std::io::Error,
297+
command: &Command,
298+
attempt: &str,
299+
) -> anyhow::Error {
300+
error!("Failed to spawn '{WEBDRIVER_BIN}' with {attempt}: {e}");
301+
error!(
302+
"Command was: {:?} {:?}",
303+
command.get_program(),
304+
command.get_args()
305+
);
306+
307+
#[cfg(target_os = "windows")]
308+
if attempt == "CREATE_NO_WINDOW" {
309+
error!("Windows: Check if antivirus is blocking the process");
310+
error!("Windows: Check if the binary has proper permissions");
311+
}
312+
313+
error!(
314+
"WebDriver diagnostics after spawn failure:\n{}",
315+
self.get_diagnostics()
316+
);
317+
318+
anyhow!("Failed to spawn '{WEBDRIVER_BIN}': {}", e)
319+
}
320+
300321
fn setup_output_monitoring(&self, child: &mut Child, port: u32) {
301322
// Monitor stderr
302323
if let Some(stderr) = child.stderr.take() {

0 commit comments

Comments
 (0)