Skip to content

Commit 82f7cf7

Browse files
authored
[rust] Use latest browser from cache when browser path is not discovered (#13283)
1 parent e586190 commit 82f7cf7

File tree

3 files changed

+96
-26
lines changed

3 files changed

+96
-26
lines changed

rust/src/files.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::io::{BufReader, Cursor, Read};
3535
use std::path::{Path, PathBuf};
3636
use tar::Archive;
3737
use tempfile::Builder;
38+
use walkdir::{DirEntry, WalkDir};
3839
use zip::ZipArchive;
3940

4041
pub const PARSE_ERROR: &str = "Wrong browser/driver version";
@@ -555,3 +556,36 @@ pub fn find_bytes(buffer: &[u8], bytes: &[u8]) -> Option<usize> {
555556
.windows(bytes.len())
556557
.position(|window| window == bytes)
557558
}
559+
560+
pub fn collect_files_from_cache<F: Fn(&DirEntry) -> bool>(
561+
cache_path: &PathBuf,
562+
filter: F,
563+
) -> Vec<PathBuf> {
564+
WalkDir::new(cache_path)
565+
.sort_by_file_name()
566+
.into_iter()
567+
.filter_map(|entry| entry.ok())
568+
.filter(|entry| filter(entry))
569+
.map(|entry| entry.path().to_owned())
570+
.collect()
571+
}
572+
573+
pub fn find_latest_from_cache<F: Fn(&DirEntry) -> bool>(
574+
cache_path: &PathBuf,
575+
filter: F,
576+
) -> Result<Option<PathBuf>, Error> {
577+
let files_in_cache = collect_files_from_cache(cache_path, filter);
578+
if !files_in_cache.is_empty() {
579+
Ok(Some(files_in_cache.iter().last().unwrap().to_owned()))
580+
} else {
581+
Ok(None)
582+
}
583+
}
584+
585+
pub fn capitalize(s: &str) -> String {
586+
let mut chars = s.chars();
587+
match chars.next() {
588+
None => String::new(),
589+
Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
590+
}
591+
}

rust/src/lib.rs

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ use crate::config::{str_to_os, ManagerConfig};
2121
use crate::downloads::download_to_tmp_folder;
2222
use crate::edge::{EdgeManager, EDGEDRIVER_NAME, EDGE_NAMES, WEBVIEW2_NAME};
2323
use crate::files::{
24-
create_parent_path_if_not_exists, create_path_if_not_exists, default_cache_folder,
25-
get_binary_extension, path_to_string,
24+
capitalize, collect_files_from_cache, create_parent_path_if_not_exists,
25+
create_path_if_not_exists, default_cache_folder, find_latest_from_cache, get_binary_extension,
26+
path_to_string,
2627
};
2728
use crate::files::{parse_version, uncompress, BrowserPath};
2829
use crate::firefox::{FirefoxManager, FIREFOX_NAME, GECKODRIVER_NAME};
@@ -45,7 +46,7 @@ use std::collections::HashMap;
4546
use std::path::{Path, PathBuf};
4647
use std::time::Duration;
4748
use std::{env, fs};
48-
use walkdir::{DirEntry, WalkDir};
49+
use walkdir::DirEntry;
4950

5051
pub mod chrome;
5152
pub mod config;
@@ -842,13 +843,34 @@ pub trait SeleniumManager {
842843
}
843844
}
844845

846+
fn is_browser(&self, entry: &DirEntry) -> bool {
847+
if MACOS.is(self.get_os()) && !self.is_firefox() {
848+
let entry_path = path_to_string(entry.path());
849+
self.is_in_cache(entry, &capitalize(self.get_browser_name()))
850+
&& entry_path.contains(".app/Contents/MacOS")
851+
&& !entry_path.contains("Framework")
852+
} else {
853+
self.is_in_cache(entry, &self.get_browser_name_with_extension())
854+
}
855+
}
856+
845857
fn is_driver(&self, entry: &DirEntry) -> bool {
858+
self.is_in_cache(entry, &self.get_driver_name_with_extension())
859+
}
860+
861+
fn is_in_cache(&self, entry: &DirEntry, file_name: &str) -> bool {
846862
let is_file = entry.path().is_file();
847863

848-
let is_driver = entry
864+
let is_file_name = entry
849865
.file_name()
850866
.to_str()
851-
.map(|s| s.contains(&self.get_driver_name_with_extension()))
867+
.map(|s| {
868+
if MACOS.is(self.get_os()) && !self.is_firefox() {
869+
s.contains(file_name)
870+
} else {
871+
s.ends_with(file_name)
872+
}
873+
})
852874
.unwrap_or(false);
853875

854876
let match_os = entry
@@ -857,7 +879,7 @@ pub trait SeleniumManager {
857879
.map(|s| s.contains(self.get_platform_label()))
858880
.unwrap_or(false);
859881

860-
is_file && is_driver && match_os
882+
is_file && is_file_name && match_os
861883
}
862884

863885
fn is_driver_and_matches_browser_version(&self, entry: &DirEntry) -> bool {
@@ -876,14 +898,34 @@ pub trait SeleniumManager {
876898
self.is_driver(entry) && match_driver_version
877899
}
878900

901+
fn get_browser_path_or_latest_from_cache(&self) -> String {
902+
let mut browser_path = self.get_browser_path().to_string();
903+
if browser_path.is_empty() {
904+
let best_browser_from_cache = &self
905+
.find_best_browser_from_cache()
906+
.unwrap_or_default()
907+
.unwrap_or_default();
908+
if best_browser_from_cache.exists() {
909+
self.get_logger().warn(format!(
910+
"There was an error managing {}; using browser found in the cache",
911+
self.get_browser_name()
912+
));
913+
browser_path = path_to_string(best_browser_from_cache);
914+
}
915+
}
916+
browser_path
917+
}
918+
919+
fn find_best_browser_from_cache(&self) -> Result<Option<PathBuf>, Error> {
920+
let cache_path = self.get_cache_path()?.unwrap_or_default();
921+
find_latest_from_cache(&cache_path, |entry| self.is_browser(entry))
922+
}
923+
879924
fn find_best_driver_from_cache(&self) -> Result<Option<PathBuf>, Error> {
880925
let cache_path = self.get_cache_path()?.unwrap_or_default();
881-
let drivers_in_cache_matching_version: Vec<PathBuf> = WalkDir::new(&cache_path)
882-
.into_iter()
883-
.filter_map(|entry| entry.ok())
884-
.filter(|entry| self.is_driver_and_matches_browser_version(entry))
885-
.map(|entry| entry.path().to_owned())
886-
.collect();
926+
let drivers_in_cache_matching_version = collect_files_from_cache(&cache_path, |entry| {
927+
self.is_driver_and_matches_browser_version(entry)
928+
});
887929

888930
// First we look for drivers in cache that matches browser version (should work for Chrome and Edge)
889931
if !drivers_in_cache_matching_version.is_empty() {
@@ -896,17 +938,7 @@ pub trait SeleniumManager {
896938
))
897939
} else {
898940
// If not available, we look for the latest available driver in the cache
899-
let drivers_in_cache: Vec<PathBuf> = WalkDir::new(&cache_path)
900-
.into_iter()
901-
.filter_map(|entry| entry.ok())
902-
.filter(|entry| self.is_driver(entry))
903-
.map(|entry| entry.path().to_owned())
904-
.collect();
905-
if !drivers_in_cache.is_empty() {
906-
Ok(Some(drivers_in_cache.iter().last().unwrap().to_owned()))
907-
} else {
908-
Ok(None)
909-
}
941+
find_latest_from_cache(&cache_path, |entry| self.is_driver(entry))
910942
}
911943
}
912944

rust/src/main.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,11 @@ fn main() {
211211
.and_then(|_| selenium_manager.setup())
212212
.map(|driver_path| {
213213
let log = selenium_manager.get_logger();
214-
log_driver_and_browser_path(log, &driver_path, selenium_manager.get_browser_path());
214+
log_driver_and_browser_path(
215+
log,
216+
&driver_path,
217+
&selenium_manager.get_browser_path_or_latest_from_cache(),
218+
);
215219
flush_and_exit(OK, log, None);
216220
})
217221
.unwrap_or_else(|err| {
@@ -221,13 +225,13 @@ fn main() {
221225
{
222226
log.warn(format!(
223227
"There was an error managing {} ({}); using driver found in the cache",
224-
selenium_manager.get_browser_name(),
228+
selenium_manager.get_driver_name(),
225229
err
226230
));
227231
log_driver_and_browser_path(
228232
log,
229233
&best_driver_from_cache,
230-
selenium_manager.get_browser_path(),
234+
&selenium_manager.get_browser_path_or_latest_from_cache(),
231235
);
232236
flush_and_exit(OK, log, Some(err));
233237
} else if selenium_manager.is_offline() {

0 commit comments

Comments
 (0)