1
1
import os
2
2
import re
3
3
import sys
4
+ import threading
5
+ import time
4
6
import warnings
5
7
from selenium import webdriver
6
8
from selenium .common .exceptions import WebDriverException
7
9
from selenium .webdriver .common .desired_capabilities import DesiredCapabilities
8
10
from seleniumbase .config import proxy_list
9
11
from seleniumbase .core import download_helper
12
+ from seleniumbase .core import proxy_helper
10
13
from seleniumbase .fixtures import constants
11
14
from seleniumbase .fixtures import page_utils
12
15
from seleniumbase import drivers # webdriver storage folder for SeleniumBase
13
16
DRIVER_DIR = os .path .dirname (os .path .realpath (drivers .__file__ ))
17
+ PROXY_ZIP_PATH = proxy_helper .PROXY_ZIP_PATH
14
18
PLATFORM = sys .platform
15
19
IS_WINDOWS = False
16
20
LOCAL_CHROMEDRIVER = None
@@ -49,7 +53,31 @@ def make_driver_executable_if_not(driver_path):
49
53
make_executable (driver_path )
50
54
51
55
52
- def _set_chrome_options (downloads_path , proxy_string ):
56
+ def _add_chrome_proxy_extension (
57
+ chrome_options , proxy_string , proxy_user , proxy_pass ):
58
+ """ Implementation of https://stackoverflow.com/a/35293284 for
59
+ https://stackoverflow.com/questions/12848327/
60
+ (Run Selenium on a proxy server that requires authentication.)
61
+ The retry_on_exception is only needed for multithreaded runs
62
+ because proxy.zip is a common file shared between all tests
63
+ in a single run. """
64
+ if not "" .join (sys .argv ) == "-c" :
65
+ # Single-threaded
66
+ proxy_helper .create_proxy_zip (proxy_string , proxy_user , proxy_pass )
67
+ else :
68
+ # Pytest multi-threaded test
69
+ lock = threading .Lock ()
70
+ with lock :
71
+ if not os .path .exists (PROXY_ZIP_PATH ):
72
+ proxy_helper .create_proxy_zip (
73
+ proxy_string , proxy_user , proxy_pass )
74
+ time .sleep (0.3 )
75
+ chrome_options .add_extension (PROXY_ZIP_PATH )
76
+ return chrome_options
77
+
78
+
79
+ def _set_chrome_options (
80
+ downloads_path , proxy_string , proxy_auth , proxy_user , proxy_pass ):
53
81
chrome_options = webdriver .ChromeOptions ()
54
82
prefs = {
55
83
"download.default_directory" : downloads_path ,
@@ -71,6 +99,10 @@ def _set_chrome_options(downloads_path, proxy_string):
71
99
chrome_options .add_argument ("--disable-translate" )
72
100
chrome_options .add_argument ("--disable-web-security" )
73
101
if proxy_string :
102
+ if proxy_auth :
103
+ chrome_options = _add_chrome_proxy_extension (
104
+ chrome_options , proxy_string , proxy_user , proxy_pass )
105
+ chrome_options .add_extension (DRIVER_DIR + "/proxy.zip" )
74
106
chrome_options .add_argument ('--proxy-server=%s' % proxy_string )
75
107
if "win32" in sys .platform or "win64" in sys .platform :
76
108
chrome_options .add_argument ("--log-level=3" )
@@ -155,22 +187,55 @@ def validate_proxy_string(proxy_string):
155
187
156
188
def get_driver (browser_name , headless = False , use_grid = False ,
157
189
servername = 'localhost' , port = 4444 , proxy_string = None ):
190
+ proxy_auth = False
191
+ proxy_user = None
192
+ proxy_pass = None
158
193
if proxy_string :
194
+ username_and_password = None
195
+ if "@" in proxy_string :
196
+ # Format => username:password@hostname:port
197
+ try :
198
+ username_and_password = proxy_string .split ('@' )[0 ]
199
+ proxy_string = proxy_string .split ('@' )[1 ]
200
+ proxy_user = username_and_password .split (':' )[0 ]
201
+ proxy_pass = username_and_password .split (':' )[1 ]
202
+ except Exception :
203
+ raise Exception (
204
+ 'The format for using a proxy server with authentication '
205
+ 'is: "username:password@hostname:port". If using a proxy '
206
+ 'server without auth, the format is: "hostname:port".' )
207
+ if browser_name != constants .Browser .GOOGLE_CHROME :
208
+ raise Exception (
209
+ "Chrome is required when using a proxy server that has "
210
+ "authentication! (If using a proxy server without auth, "
211
+ "either Chrome or Firefox may be used.)" )
159
212
proxy_string = validate_proxy_string (proxy_string )
213
+ if proxy_string and proxy_user and proxy_pass :
214
+ if not os .path .exists (PROXY_ZIP_PATH ):
215
+ proxy_helper .create_proxy_zip (
216
+ proxy_string , proxy_user , proxy_pass )
217
+ proxy_auth = True
160
218
if use_grid :
161
219
return get_remote_driver (
162
- browser_name , headless , servername , port , proxy_string )
220
+ browser_name , headless , servername , port , proxy_string , proxy_auth ,
221
+ proxy_user , proxy_pass )
163
222
else :
164
- return get_local_driver (browser_name , headless , proxy_string )
223
+ return get_local_driver (
224
+ browser_name , headless , proxy_string , proxy_auth ,
225
+ proxy_user , proxy_pass )
165
226
166
227
167
- def get_remote_driver (browser_name , headless , servername , port , proxy_string ):
228
+ def get_remote_driver (
229
+ browser_name , headless , servername , port , proxy_string , proxy_auth ,
230
+ proxy_user , proxy_pass ):
168
231
downloads_path = download_helper .get_downloads_folder ()
169
232
download_helper .reset_downloads_folder ()
170
233
address = "http://%s:%s/wd/hub" % (servername , port )
171
234
172
235
if browser_name == constants .Browser .GOOGLE_CHROME :
173
- chrome_options = _set_chrome_options (downloads_path , proxy_string )
236
+ chrome_options = _set_chrome_options (
237
+ downloads_path , proxy_string , proxy_auth ,
238
+ proxy_user , proxy_pass )
174
239
if headless :
175
240
chrome_options .add_argument ("--headless" )
176
241
chrome_options .add_argument ("--disable-gpu" )
@@ -237,7 +302,9 @@ def get_remote_driver(browser_name, headless, servername, port, proxy_string):
237
302
webdriver .DesiredCapabilities .PHANTOMJS ))
238
303
239
304
240
- def get_local_driver (browser_name , headless , proxy_string ):
305
+ def get_local_driver (
306
+ browser_name , headless , proxy_string , proxy_auth ,
307
+ proxy_user , proxy_pass ):
241
308
'''
242
309
Spins up a new web browser and returns the driver.
243
310
Can also be used to spin up additional browsers for the same test.
@@ -326,7 +393,9 @@ def get_local_driver(browser_name, headless, proxy_string):
326
393
return webdriver .PhantomJS ()
327
394
elif browser_name == constants .Browser .GOOGLE_CHROME :
328
395
try :
329
- chrome_options = _set_chrome_options (downloads_path , proxy_string )
396
+ chrome_options = _set_chrome_options (
397
+ downloads_path , proxy_string , proxy_auth ,
398
+ proxy_user , proxy_pass )
330
399
if headless :
331
400
chrome_options .add_argument ("--headless" )
332
401
chrome_options .add_argument ("--disable-gpu" )
0 commit comments