1717
1818use crate :: config:: ManagerConfig ;
1919use reqwest:: Client ;
20+ use std:: cell:: RefCell ;
2021use std:: collections:: HashMap ;
2122use std:: error:: Error ;
2223use std:: path:: PathBuf ;
2324
24- use crate :: downloads:: read_redirect_from_link;
2525use crate :: files:: { compose_driver_path_in_cache, BrowserPath } ;
2626
27- use crate :: { create_default_http_client, Logger , SeleniumManager } ;
27+ use crate :: { create_default_http_client, parse_version , Logger , SeleniumManager } ;
2828
2929use crate :: metadata:: {
3030 create_driver_metadata, get_driver_version_from_metadata, get_metadata, write_metadata,
3131} ;
32+ use crate :: mirror:: { get_mirror_response, Assets , SeleniumRelease } ;
3233
3334pub const IE_NAMES : & [ & str ] = & [
3435 "iexplorer" ,
@@ -39,7 +40,9 @@ pub const IE_NAMES: &[&str] = &[
3940] ;
4041pub const IEDRIVER_NAME : & str = "IEDriverServer" ;
4142const DRIVER_URL : & str = "https://github.com/SeleniumHQ/selenium/releases/" ;
42- const LATEST_RELEASE : & str = "latest" ;
43+ const IEDRIVER_RELEASE : & str = "IEDriverServer_Win32_" ;
44+
45+ thread_local ! ( static RELEASE_URL : RefCell <String > = RefCell :: new( "" . to_string( ) ) ) ;
4346
4447pub struct IExplorerManager {
4548 pub browser_name : & ' static str ,
@@ -100,29 +103,75 @@ impl SeleniumManager for IExplorerManager {
100103 Ok ( driver_version)
101104 }
102105 _ => {
103- let latest_url = format ! ( "{}{}" , DRIVER_URL , LATEST_RELEASE ) ;
104- let driver_version = read_redirect_from_link ( self . get_http_client ( ) , latest_url) ?;
105-
106- if !browser_version. is_empty ( ) {
107- metadata. drivers . push ( create_driver_metadata (
108- browser_version,
109- self . driver_name ,
110- & driver_version,
111- ) ) ;
112- write_metadata ( & metadata, self . get_logger ( ) ) ;
106+ let selenium_releases = get_mirror_response ( self . get_http_client ( ) ) ?;
107+
108+ let filtered_releases: Vec < SeleniumRelease > = selenium_releases
109+ . into_iter ( )
110+ . filter ( |r| {
111+ r. assets
112+ . iter ( )
113+ . any ( |url| url. browser_download_url . contains ( IEDRIVER_RELEASE ) )
114+ } )
115+ . collect ( ) ;
116+
117+ if !filtered_releases. is_empty ( ) {
118+ let assets = & filtered_releases. get ( 0 ) . unwrap ( ) . assets ;
119+ let driver_releases: Vec < & Assets > = assets
120+ . iter ( )
121+ . filter ( |url| url. browser_download_url . contains ( IEDRIVER_RELEASE ) )
122+ . collect ( ) ;
123+ let driver_url = & driver_releases. last ( ) . unwrap ( ) . browser_download_url ;
124+ RELEASE_URL . with ( |url| {
125+ * url. borrow_mut ( ) = driver_url. to_string ( ) ;
126+ } ) ;
127+
128+ let index_release =
129+ driver_url. rfind ( IEDRIVER_RELEASE ) . unwrap ( ) + IEDRIVER_RELEASE . len ( ) ;
130+ let driver_version =
131+ parse_version ( driver_url. as_str ( ) [ index_release..] . to_string ( ) ) ?;
132+
133+ if !browser_version. is_empty ( ) {
134+ metadata. drivers . push ( create_driver_metadata (
135+ browser_version,
136+ self . driver_name ,
137+ & driver_version,
138+ ) ) ;
139+ write_metadata ( & metadata, self . get_logger ( ) ) ;
140+ }
141+
142+ Ok ( driver_version)
143+ } else {
144+ Err ( format ! ( "{} release not available" , self . get_driver_name( ) ) . into ( ) )
113145 }
114-
115- Ok ( driver_version)
116146 }
117147 }
118148 }
119149
120150 fn get_driver_url ( & self ) -> Result < String , Box < dyn Error > > {
121- let driver_version = self . get_driver_version ( ) ;
122- Ok ( format ! (
123- "{}download/selenium-{}/IEDriverServer_Win32_{}.zip" ,
124- DRIVER_URL , driver_version, driver_version
125- ) )
151+ let mut driver_url = "" . to_string ( ) ;
152+ RELEASE_URL . with ( |url| {
153+ driver_url = url. borrow ( ) . to_string ( ) ;
154+ } ) ;
155+ if driver_url. is_empty ( ) {
156+ let driver_version = self . get_driver_version ( ) ;
157+ let mut release_version = driver_version. to_string ( ) ;
158+ if !driver_version. ends_with ( '0' ) {
159+ // E.g.: version 4.8.1 is shipped within release 4.8.0
160+ let error_message = format ! (
161+ "Wrong {} version: '{}'" ,
162+ self . get_driver_name( ) ,
163+ driver_version
164+ ) ;
165+ let index = release_version. rfind ( '.' ) . ok_or ( error_message) ? + 1 ;
166+ release_version = release_version[ ..index] . to_string ( ) ;
167+ release_version. push ( '0' ) ;
168+ }
169+ driver_url = format ! (
170+ "{}download/selenium-{}/{}{}.zip" ,
171+ DRIVER_URL , release_version, IEDRIVER_RELEASE , driver_version
172+ ) ;
173+ }
174+ Ok ( driver_url)
126175 }
127176
128177 fn get_driver_path_in_cache ( & self ) -> PathBuf {
0 commit comments