|
59 | 59 | //! |
60 | 60 | //! ## Features and Dependencies |
61 | 61 | //! |
62 | | -//! ### Required Features |
| 62 | +//! ### Driver Features |
63 | 63 | //! |
64 | | -//! You must enable one of the following features: |
| 64 | +//! To use static export, enable one of the following features: |
65 | 65 | //! |
66 | 66 | //! - `chromedriver`: Use Chrome/Chromium for rendering |
67 | 67 | //! - `geckodriver`: Use Firefox for rendering |
@@ -294,6 +294,7 @@ use fantoccini::{wd::Capabilities, Client, ClientBuilder}; |
294 | 294 | #[cfg(not(any(test, feature = "debug")))] |
295 | 295 | use log::{debug, error, warn}; |
296 | 296 | use serde::Serialize; |
| 297 | +#[cfg(any(feature = "chromedriver", feature = "geckodriver"))] |
297 | 298 | use serde_json::map::Map as JsonMap; |
298 | 299 | use urlencoding::encode; |
299 | 300 | use webdriver::WebDriver; |
@@ -461,20 +462,24 @@ impl Default for StaticExporterBuilder { |
461 | 462 | offline_mode: false, |
462 | 463 | pdf_export_timeout: 150, |
463 | 464 | webdriver_browser_caps: { |
464 | | - #[cfg(feature = "geckodriver")] |
| 465 | + #[cfg(feature = "chromedriver")] |
465 | 466 | { |
466 | | - crate::webdriver::firefox_default_caps() |
| 467 | + crate::webdriver::chrome_default_caps() |
467 | 468 | .into_iter() |
468 | 469 | .map(|s| s.to_string()) |
469 | 470 | .collect() |
470 | 471 | } |
471 | | - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] |
| 472 | + #[cfg(feature = "geckodriver")] |
472 | 473 | { |
473 | | - crate::webdriver::chrome_default_caps() |
| 474 | + crate::webdriver::firefox_default_caps() |
474 | 475 | .into_iter() |
475 | 476 | .map(|s| s.to_string()) |
476 | 477 | .collect() |
477 | 478 | } |
| 479 | + #[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))] |
| 480 | + { |
| 481 | + Vec::new() |
| 482 | + } |
478 | 483 | }, |
479 | 484 | } |
480 | 485 | } |
@@ -923,6 +928,10 @@ pub struct AsyncStaticExporter { |
923 | 928 | pdf_export_timeout: u32, |
924 | 929 |
|
925 | 930 | /// Browser command-line flags (e.g., "--headless", "--no-sandbox") |
| 931 | + #[cfg_attr( |
| 932 | + not(any(feature = "chromedriver", feature = "geckodriver")), |
| 933 | + allow(dead_code) |
| 934 | + )] |
926 | 935 | webdriver_browser_caps: Vec<String>, |
927 | 936 |
|
928 | 937 | /// Cached WebDriver client for session reuse |
@@ -1117,46 +1126,55 @@ impl AsyncStaticExporter { |
1117 | 1126 | } |
1118 | 1127 |
|
1119 | 1128 | fn build_webdriver_caps(&self) -> Result<Capabilities> { |
1120 | | - // Define browser capabilities (copied to avoid reordering existing code) |
1121 | | - let mut caps = JsonMap::new(); |
1122 | | - let mut browser_opts = JsonMap::new(); |
1123 | | - let browser_args = self.webdriver_browser_caps.clone(); |
1124 | | - |
1125 | | - browser_opts.insert("args".to_string(), serde_json::json!(browser_args)); |
1126 | | - |
1127 | | - // Add Chrome binary capability if BROWSER_PATH is set |
1128 | | - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] |
1129 | | - if let Ok(chrome_path) = std::env::var("BROWSER_PATH") { |
1130 | | - browser_opts.insert("binary".to_string(), serde_json::json!(chrome_path)); |
1131 | | - debug!("Added Chrome binary capability: {chrome_path}"); |
1132 | | - } |
1133 | | - // Add Firefox binary capability if BROWSER_PATH is set |
1134 | | - #[cfg(feature = "geckodriver")] |
1135 | | - if let Ok(firefox_path) = std::env::var("BROWSER_PATH") { |
1136 | | - browser_opts.insert("binary".to_string(), serde_json::json!(firefox_path)); |
1137 | | - debug!("Added Firefox binary capability: {firefox_path}"); |
1138 | | - } |
1139 | | - |
1140 | | - // Add Firefox-specific preferences for CI environments |
1141 | | - #[cfg(feature = "geckodriver")] |
| 1129 | + #[cfg(not(any(feature = "chromedriver", feature = "geckodriver")))] |
1142 | 1130 | { |
1143 | | - let prefs = common::get_firefox_ci_preferences(); |
1144 | | - browser_opts.insert("prefs".to_string(), serde_json::json!(prefs)); |
1145 | | - debug!("Added Firefox preferences for CI compatibility"); |
| 1131 | + Err(anyhow!( |
| 1132 | + "Static image export requires enabling either the 'chromedriver' or 'geckodriver' feature." |
| 1133 | + )) |
1146 | 1134 | } |
| 1135 | + #[cfg(any(feature = "chromedriver", feature = "geckodriver"))] |
| 1136 | + { |
| 1137 | + // Define browser capabilities (copied to avoid reordering existing code) |
| 1138 | + let mut caps = JsonMap::new(); |
| 1139 | + let mut browser_opts = JsonMap::new(); |
| 1140 | + let browser_args = self.webdriver_browser_caps.clone(); |
| 1141 | + |
| 1142 | + browser_opts.insert("args".to_string(), serde_json::json!(browser_args)); |
| 1143 | + |
| 1144 | + // Add Chrome binary capability if BROWSER_PATH is set |
| 1145 | + #[cfg(feature = "chromedriver")] |
| 1146 | + if let Ok(chrome_path) = std::env::var("BROWSER_PATH") { |
| 1147 | + browser_opts.insert("binary".to_string(), serde_json::json!(chrome_path)); |
| 1148 | + debug!("Added Chrome binary capability: {chrome_path}"); |
| 1149 | + } |
| 1150 | + // Add Firefox binary capability if BROWSER_PATH is set |
| 1151 | + #[cfg(feature = "geckodriver")] |
| 1152 | + if let Ok(firefox_path) = std::env::var("BROWSER_PATH") { |
| 1153 | + browser_opts.insert("binary".to_string(), serde_json::json!(firefox_path)); |
| 1154 | + debug!("Added Firefox binary capability: {firefox_path}"); |
| 1155 | + } |
1147 | 1156 |
|
1148 | | - caps.insert( |
1149 | | - "browserName".to_string(), |
1150 | | - serde_json::json!(get_browser_name()), |
1151 | | - ); |
1152 | | - caps.insert( |
1153 | | - get_options_key().to_string(), |
1154 | | - serde_json::json!(browser_opts), |
1155 | | - ); |
| 1157 | + // Add Firefox-specific preferences for CI environments |
| 1158 | + #[cfg(feature = "geckodriver")] |
| 1159 | + { |
| 1160 | + let prefs = common::get_firefox_ci_preferences(); |
| 1161 | + browser_opts.insert("prefs".to_string(), serde_json::json!(prefs)); |
| 1162 | + debug!("Added Firefox preferences for CI compatibility"); |
| 1163 | + } |
| 1164 | + |
| 1165 | + caps.insert( |
| 1166 | + "browserName".to_string(), |
| 1167 | + serde_json::json!(get_browser_name()), |
| 1168 | + ); |
| 1169 | + caps.insert( |
| 1170 | + get_options_key().to_string(), |
| 1171 | + serde_json::json!(browser_opts), |
| 1172 | + ); |
1156 | 1173 |
|
1157 | | - debug!("WebDriver capabilities: {caps:?}"); |
| 1174 | + debug!("WebDriver capabilities: {caps:?}"); |
1158 | 1175 |
|
1159 | | - Ok(caps) |
| 1176 | + Ok(caps) |
| 1177 | + } |
1160 | 1178 | } |
1161 | 1179 |
|
1162 | 1180 | #[cfg(target_os = "windows")] |
@@ -1606,7 +1624,7 @@ mod tests { |
1606 | 1624 | } |
1607 | 1625 |
|
1608 | 1626 | #[test] |
1609 | | - #[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] |
| 1627 | + #[cfg(feature = "chromedriver")] |
1610 | 1628 | // Skip this test for geckodriver as it doesn't support multiple concurrent |
1611 | 1629 | // sessions on the same process as gracefully as chromedriver |
1612 | 1630 | fn test_webdriver_process_reuse() { |
@@ -1671,7 +1689,7 @@ mod tests { |
1671 | 1689 | } |
1672 | 1690 | } |
1673 | 1691 |
|
1674 | | -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] |
| 1692 | +#[cfg(feature = "chromedriver")] |
1675 | 1693 | mod chrome { |
1676 | 1694 | /// Returns the browser name for Chrome WebDriver. |
1677 | 1695 | /// |
@@ -1709,8 +1727,7 @@ mod firefox { |
1709 | 1727 | } |
1710 | 1728 | } |
1711 | 1729 |
|
1712 | | -#[cfg(all(feature = "chromedriver", not(feature = "geckodriver")))] |
| 1730 | +#[cfg(feature = "chromedriver")] |
1713 | 1731 | use chrome::{get_browser_name, get_options_key}; |
1714 | 1732 | #[cfg(feature = "geckodriver")] |
1715 | 1733 | use firefox::{get_browser_name, get_options_key}; |
1716 | | - |
|
0 commit comments