Skip to content

Commit bd0824b

Browse files
authored
Merge pull request #233 from seleniumbase/proxy-with-auth-edge-case
Handle an edge case when using a proxy server with auth
2 parents 979db7b + 6fd1e93 commit bd0824b

File tree

4 files changed

+29
-17
lines changed

4 files changed

+29
-17
lines changed

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ unittest2
99
selenium==3.14.1
1010
requests==2.20.0
1111
urllib3==1.24
12-
pytest>=3.9.2
12+
pytest>=3.9.3
1313
pytest-cov>=2.6.0
1414
pytest-html>=1.19.0
1515
pytest-rerunfailures>=4.2
16-
pytest-xdist>=1.23.2
16+
pytest-xdist>=1.24.0
1717
parameterized==0.6.1
1818
beautifulsoup4>=4.6.0
1919
pyotp>=2.2.6

seleniumbase/core/browser_launcher.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import random
23
import re
34
import sys
45
import threading
@@ -15,6 +16,7 @@
1516
from seleniumbase import drivers # webdriver storage folder for SeleniumBase
1617
DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__))
1718
PROXY_ZIP_PATH = proxy_helper.PROXY_ZIP_PATH
19+
PROXY_ZIP_PATH_2 = proxy_helper.PROXY_ZIP_PATH_2
1820
PLATFORM = sys.platform
1921
IS_WINDOWS = False
2022
LOCAL_CHROMEDRIVER = None
@@ -57,22 +59,24 @@ def _add_chrome_proxy_extension(
5759
chrome_options, proxy_string, proxy_user, proxy_pass):
5860
""" Implementation of https://stackoverflow.com/a/35293284 for
5961
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. """
62+
(Run Selenium on a proxy server that requires authentication.) """
6463
if not "".join(sys.argv) == "-c":
6564
# Single-threaded
6665
proxy_helper.create_proxy_zip(proxy_string, proxy_user, proxy_pass)
6766
else:
6867
# Pytest multi-threaded test
6968
lock = threading.Lock()
7069
with lock:
70+
time.sleep(random.uniform(0.02, 0.15))
7171
if not os.path.exists(PROXY_ZIP_PATH):
7272
proxy_helper.create_proxy_zip(
7373
proxy_string, proxy_user, proxy_pass)
74-
time.sleep(0.3)
75-
chrome_options.add_extension(PROXY_ZIP_PATH)
74+
time.sleep(random.uniform(0.1, 0.2))
75+
proxy_zip = PROXY_ZIP_PATH
76+
if not os.path.exists(PROXY_ZIP_PATH):
77+
# Handle "Permission denied" on the default proxy.zip path
78+
proxy_zip = PROXY_ZIP_PATH_2
79+
chrome_options.add_extension(proxy_zip)
7680
return chrome_options
7781

7882

@@ -102,7 +106,6 @@ def _set_chrome_options(
102106
if proxy_auth:
103107
chrome_options = _add_chrome_proxy_extension(
104108
chrome_options, proxy_string, proxy_user, proxy_pass)
105-
chrome_options.add_extension(DRIVER_DIR + "/proxy.zip")
106109
chrome_options.add_argument('--proxy-server=%s' % proxy_string)
107110
return chrome_options
108111

@@ -209,9 +212,6 @@ def get_driver(browser_name, headless=False, use_grid=False,
209212
"either Chrome or Firefox may be used.)")
210213
proxy_string = validate_proxy_string(proxy_string)
211214
if proxy_string and proxy_user and proxy_pass:
212-
if not os.path.exists(PROXY_ZIP_PATH):
213-
proxy_helper.create_proxy_zip(
214-
proxy_string, proxy_user, proxy_pass)
215215
proxy_auth = True
216216
if use_grid:
217217
return get_remote_driver(

seleniumbase/core/proxy_helper.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import os
22
import threading
33
import zipfile
4+
from seleniumbase.fixtures import constants
45
from seleniumbase import drivers
56
DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__))
67
PROXY_ZIP_PATH = "%s/%s" % (DRIVER_DIR, "proxy.zip")
8+
DOWNLOADS_DIR = constants.Files.DOWNLOADS_FOLDER
9+
PROXY_ZIP_PATH_2 = "%s/%s" % (DOWNLOADS_DIR, "proxy.zip")
710

811

912
def create_proxy_zip(proxy_string, proxy_user, proxy_pass):
@@ -15,7 +18,6 @@ def create_proxy_zip(proxy_string, proxy_user, proxy_pass):
1518
"""
1619
proxy_host = proxy_string.split(':')[0]
1720
proxy_port = proxy_string.split(':')[1]
18-
proxy_zip = DRIVER_DIR + '/proxy.zip'
1921
background_js = (
2022
"""var config = {\n"""
2123
""" mode: "fixed_servers",\n"""
@@ -64,7 +66,15 @@ def create_proxy_zip(proxy_string, proxy_user, proxy_pass):
6466
'''}''')
6567
lock = threading.RLock() # Support multi-threaded test runs with Pytest
6668
with lock:
67-
zf = zipfile.ZipFile(proxy_zip, mode='w')
69+
try:
70+
zf = zipfile.ZipFile(PROXY_ZIP_PATH, mode='w')
71+
except IOError:
72+
# Handle "Permission denied" on the default proxy.zip path
73+
abs_path = os.path.abspath('.')
74+
downloads_path = os.path.join(abs_path, DOWNLOADS_DIR)
75+
if not os.path.exists(downloads_path):
76+
os.mkdir(downloads_path)
77+
zf = zipfile.ZipFile(PROXY_ZIP_PATH_2, mode='w')
6878
zf.writestr("background.js", background_js)
6979
zf.writestr("manifest.json", manifest_json)
7080
zf.close()
@@ -78,5 +88,7 @@ def remove_proxy_zip_if_present():
7888
try:
7989
if os.path.exists(PROXY_ZIP_PATH):
8090
os.remove(PROXY_ZIP_PATH)
91+
elif os.path.exists(PROXY_ZIP_PATH_2):
92+
os.remove(PROXY_ZIP_PATH_2)
8193
except Exception:
8294
pass

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
setup(
1919
name='seleniumbase',
20-
version='1.16.15',
20+
version='1.16.16',
2121
description='All-In-One Test Automation Framework',
2222
long_description=long_description,
2323
long_description_content_type='text/markdown',
@@ -61,11 +61,11 @@
6161
'selenium==3.14.1',
6262
'requests==2.20.0', # Changing this may effect "urllib3"
6363
'urllib3==1.24', # Keep this lib in sync with "requests"
64-
'pytest>=3.9.2',
64+
'pytest>=3.9.3',
6565
'pytest-cov>=2.6.0',
6666
'pytest-html>=1.19.0',
6767
'pytest-rerunfailures>=4.2',
68-
'pytest-xdist>=1.23.2',
68+
'pytest-xdist>=1.24.0',
6969
'parameterized==0.6.1',
7070
'beautifulsoup4>=4.6.0', # Keep at >=4.6.0 while using bs4
7171
'pyotp>=2.2.6',

0 commit comments

Comments
 (0)