1313# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414# See the License for the specific language governing permissions and
1515# limitations under the License.
16-
16+ import inspect
1717import os
1818import warnings
1919
@@ -50,14 +50,18 @@ def __init__(self, log_dir):
5050 self .log_dir = log_dir
5151
5252 def create_driver (self , browser , desired_capabilities , remote_url ,
53- profile_dir = None ):
53+ profile_dir = None , service_log_path = None ):
5454 creation_method = self ._get_creator_method (browser )
5555 desired_capabilities = self ._parse_capabilities (desired_capabilities , browser )
56+ service_log_path = self ._get_log_path (service_log_path )
57+ if service_log_path :
58+ logger .info ('Browser driver log file created to: %s' % service_log_path )
59+ self ._create_directory (service_log_path )
5660 if (creation_method == self .create_firefox
5761 or creation_method == self .create_headless_firefox ):
5862 return creation_method (desired_capabilities , remote_url ,
59- profile_dir )
60- return creation_method (desired_capabilities , remote_url )
63+ profile_dir , service_log_path )
64+ return creation_method (desired_capabilities , remote_url , service_log_path = service_log_path )
6165
6266 def _get_creator_method (self , browser ):
6367 browser = browser .lower ().replace (' ' , '' )
@@ -93,29 +97,28 @@ def _remote_capabilities_resolver(self, set_capabilities, default_capabilities):
9397 caps ['browserName' ] = default_capabilities ['browserName' ]
9498 return {'desired_capabilities' : caps }
9599
96- def create_chrome (self , desired_capabilities , remote_url , options = None ):
100+ def create_chrome (self , desired_capabilities , remote_url , options = None , service_log_path = None ):
97101 if is_truthy (remote_url ):
98102 defaul_caps = webdriver .DesiredCapabilities .CHROME .copy ()
99103 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
100104 return self ._remote (desired_capabilities , remote_url , options = options )
101- return webdriver .Chrome (options = options , ** desired_capabilities )
105+ return webdriver .Chrome (options = options , service_log_path = service_log_path , ** desired_capabilities )
102106
103- def create_headless_chrome (self , desired_capabilities , remote_url ):
107+ def create_headless_chrome (self , desired_capabilities , remote_url , service_log_path = None ):
104108 options = webdriver .ChromeOptions ()
105109 # Can be changed to options.headless = True when minimum Selenium version is 3.12.0 or greater.
106110 options .set_headless ()
107- return self .create_chrome (desired_capabilities , remote_url , options )
111+ return self .create_chrome (desired_capabilities , remote_url , options , service_log_path )
108112
109- def create_firefox (self , desired_capabilities , remote_url , ff_profile_dir ,
110- options = None ):
113+ def create_firefox (self , desired_capabilities , remote_url , ff_profile_dir , options = None , service_log_path = None ):
111114 profile = self ._get_ff_profile (ff_profile_dir )
112115 if is_truthy (remote_url ):
113116 defaul_caps = webdriver .DesiredCapabilities .FIREFOX .copy ()
114117 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
115118 return self ._remote (desired_capabilities , remote_url ,
116119 profile , options )
117- desired_capabilities . update ( self ._geckodriver_log )
118- return webdriver .Firefox (options = options , firefox_profile = profile ,
120+ service_log_path = service_log_path if service_log_path else self ._geckodriver_log
121+ return webdriver .Firefox (options = options , firefox_profile = profile , service_log_path = service_log_path ,
119122 ** desired_capabilities )
120123
121124 def _get_ff_profile (self , ff_profile_dir ):
@@ -125,36 +128,47 @@ def _get_ff_profile(self, ff_profile_dir):
125128
126129 @property
127130 def _geckodriver_log (self ):
128- return {'log_path' : os .path .join (self .log_dir , 'geckodriver.log' )}
131+ log_file = self ._get_log_path (os .path .join (self .log_dir , 'geckodriver-{index}.log' ))
132+ logger .info ('Firefox driver log is always forced to to: %s' % log_file )
133+ return log_file
129134
130135 def create_headless_firefox (self , desired_capabilities , remote_url ,
131- ff_profile_dir ):
136+ ff_profile_dir , service_log_path = None ):
132137 options = webdriver .FirefoxOptions ()
133138 # Can be changed to options.headless = True when minimum Selenium version is 3.12.0 or greater.
134139 options .set_headless ()
135- return self .create_firefox (desired_capabilities , remote_url ,
136- ff_profile_dir , options )
140+ return self .create_firefox (desired_capabilities , remote_url , ff_profile_dir , options , service_log_path )
137141
138- def create_ie (self , desired_capabilities , remote_url ):
142+ def create_ie (self , desired_capabilities , remote_url , service_log_path = None ):
139143 if is_truthy (remote_url ):
140144 defaul_caps = webdriver .DesiredCapabilities .INTERNETEXPLORER .copy ()
141145 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
142146 return self ._remote (desired_capabilities , remote_url )
147+ if self ._has_service_log_path (webdriver .Ie ):
148+ return webdriver .Ie (service_log_path = service_log_path , ** desired_capabilities )
149+ logger .warn ('This version of Selenium does not support service_log_path argument.' )
143150 return webdriver .Ie (** desired_capabilities )
144151
145- def create_edge (self , desired_capabilities , remote_url ):
152+ def _has_service_log_path (self , web_driver ):
153+ signature = inspect .getargspec (web_driver .__init__ )
154+ return True if 'service_log_path' in signature .args else False
155+
156+ def create_edge (self , desired_capabilities , remote_url , service_log_path = None ):
146157 if is_truthy (remote_url ):
147158 defaul_caps = webdriver .DesiredCapabilities .EDGE .copy ()
148159 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
149160 return self ._remote (desired_capabilities , remote_url )
161+ if self ._has_service_log_path (webdriver .Ie ):
162+ return webdriver .Edge (service_log_path = service_log_path , ** desired_capabilities )
163+ logger .warn ('This version of Selenium does not support service_log_path argument.' )
150164 return webdriver .Edge (** desired_capabilities )
151165
152- def create_opera (self , desired_capabilities , remote_url ):
166+ def create_opera (self , desired_capabilities , remote_url , service_log_path = None ):
153167 if is_truthy (remote_url ):
154168 defaul_caps = webdriver .DesiredCapabilities .OPERA .copy ()
155169 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
156170 return self ._remote (desired_capabilities , remote_url )
157- return webdriver .Opera (** desired_capabilities )
171+ return webdriver .Opera (service_log_path = service_log_path , ** desired_capabilities )
158172
159173 def create_safari (self , desired_capabilities , remote_url ):
160174 if is_truthy (remote_url ):
@@ -163,31 +177,39 @@ def create_safari(self, desired_capabilities, remote_url):
163177 return self ._remote (desired_capabilities , remote_url )
164178 return webdriver .Safari (** desired_capabilities )
165179
166- def create_phantomjs (self , desired_capabilities , remote_url ):
180+ def create_phantomjs (self , desired_capabilities , remote_url , service_log_path = None ):
167181 warnings .warn ('SeleniumLibrary support for PhantomJS has been deprecated, '
168182 'please use headlesschrome or headlessfirefox instead.' )
169183 if is_truthy (remote_url ):
170184 defaul_caps = webdriver .DesiredCapabilities .PHANTOMJS .copy ()
171185 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
172186 return self ._remote (desired_capabilities , remote_url )
173- return webdriver .PhantomJS (** desired_capabilities )
187+ return webdriver .PhantomJS (service_log_path = service_log_path , ** desired_capabilities )
174188
175- def create_htmlunit (self , desired_capabilities , remote_url ):
189+ def create_htmlunit (self , desired_capabilities , remote_url , service_log_path = None ):
190+ if service_log_path :
191+ logger .warn ('Htmlunit does not support service_log_path argument.' )
176192 defaul_caps = webdriver .DesiredCapabilities .HTMLUNIT .copy ()
177193 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
178194 return self ._remote (desired_capabilities , remote_url )
179195
180- def create_htmlunit_with_js (self , desired_capabilities , remote_url ):
196+ def create_htmlunit_with_js (self , desired_capabilities , remote_url , service_log_path = None ):
197+ if service_log_path :
198+ logger .warn ('Htmlunit does not support service_log_path argument.' )
181199 defaul_caps = webdriver .DesiredCapabilities .HTMLUNITWITHJS .copy ()
182200 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
183201 return self ._remote (desired_capabilities , remote_url )
184202
185- def create_android (self , desired_capabilities , remote_url ):
203+ def create_android (self , desired_capabilities , remote_url , service_log_path = None ):
204+ if service_log_path :
205+ logger .warn ('Android does not support service_log_path argument.' )
186206 defaul_caps = webdriver .DesiredCapabilities .ANDROID .copy ()
187207 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
188208 return self ._remote (desired_capabilities , remote_url )
189209
190- def create_iphone (self , desired_capabilities , remote_url ):
210+ def create_iphone (self , desired_capabilities , remote_url , service_log_path = None ):
211+ if service_log_path :
212+ logger .warn ('iPhone does not support service_log_path argument.' )
191213 defaul_caps = webdriver .DesiredCapabilities .IPHONE .copy ()
192214 desired_capabilities = self ._remote_capabilities_resolver (desired_capabilities , defaul_caps )
193215 return self ._remote (desired_capabilities , remote_url )
@@ -199,6 +221,23 @@ def _remote(self, desired_capabilities, remote_url,
199221 browser_profile = profile_dir , options = options ,
200222 ** desired_capabilities )
201223
224+ def _get_log_path (self , log_file ):
225+ if is_noney (log_file ):
226+ return None
227+ index = 1
228+ while True :
229+ formatted = log_file .format (index = index )
230+ path = os .path .join (self .log_dir , formatted )
231+ # filename didn't contain {index} or unique path was found
232+ if formatted == log_file or not os .path .exists (path ):
233+ return path
234+ index += 1
235+
236+ def _create_directory (self , path ):
237+ target_dir = os .path .dirname (path )
238+ if not os .path .exists (target_dir ):
239+ os .makedirs (target_dir )
240+
202241
203242class WebDriverCache (ConnectionCache ):
204243
0 commit comments