Skip to content

Commit 2d13833

Browse files
committed
Add a command-line option to disable the Content Security Policy
1 parent 0d17e9b commit 2d13833

File tree

5 files changed

+56
-20
lines changed

5 files changed

+56
-20
lines changed

seleniumbase/config/settings.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,20 @@
6767
# Messenger notifications appear when reaching assert statements in Demo Mode.
6868
DEFAULT_MESSAGE_DURATION = 2.55
6969

70-
# If True, the Content Security Policy will be disabled on Chrome and Firefox.
70+
# If True, the Content Security Policy will be disabled on Firefox.
7171
# If False, each website's default Content Security Policy will be used.
7272
# (A website's CSP may prevent SeleniumBase from loading custom JavaScript.)
73-
DISABLE_CONTENT_SECURITY_POLICY = True
73+
# If using demo_mode or MasterQA, this value will become True regardless.
74+
# You can also disable the CSP on the command line by using "--disable_csp".
75+
DISABLE_CSP_ON_FIREFOX = True
76+
77+
# If True, the Content Security Policy will be disabled on Chrome.
78+
# If False, each website's default Content Security Policy will be used.
79+
# (A website's CSP may prevent SeleniumBase from loading custom JavaScript.)
80+
# If using demo_mode or MasterQA, this value will become True regardless,
81+
# with the exception of running in headless mode, in which case it'll be False.
82+
# You can also disable the CSP on the command line by using "--disable_csp".
83+
DISABLE_CSP_ON_CHROME = False
7484

7585
# If True, an Exception is raised immediately for invalid proxy string syntax.
7686
# If False, a Warning will appear after the test, with no proxy server used.

seleniumbase/core/browser_launcher.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def _add_chrome_disable_csp_extension(chrome_options):
9595

9696
def _set_chrome_options(
9797
downloads_path, headless, proxy_string, proxy_auth,
98-
proxy_user, proxy_pass, user_agent):
98+
proxy_user, proxy_pass, user_agent, disable_csp):
9999
chrome_options = webdriver.ChromeOptions()
100100
prefs = {
101101
"download.default_directory": downloads_path,
@@ -119,7 +119,7 @@ def _set_chrome_options(
119119
chrome_options.add_argument("--disable-single-click-autofill")
120120
chrome_options.add_argument("--disable-translate")
121121
chrome_options.add_argument("--disable-web-security")
122-
if settings.DISABLE_CONTENT_SECURITY_POLICY and not headless:
122+
if (settings.DISABLE_CSP_ON_CHROME or disable_csp) and not headless:
123123
# Headless Chrome doesn't support extensions, which are required
124124
# for disabling the Content Security Policy on Chrome
125125
chrome_options = _add_chrome_disable_csp_extension(chrome_options)
@@ -131,7 +131,8 @@ def _set_chrome_options(
131131
return chrome_options
132132

133133

134-
def _create_firefox_profile(downloads_path, proxy_string, user_agent):
134+
def _create_firefox_profile(
135+
downloads_path, proxy_string, user_agent, disable_csp):
135136
profile = webdriver.FirefoxProfile()
136137
profile.accept_untrusted_certs = True
137138
profile.set_preference("reader.parse-on-load.enabled", False)
@@ -150,7 +151,7 @@ def _create_firefox_profile(downloads_path, proxy_string, user_agent):
150151
profile.set_preference("general.useragent.override", user_agent)
151152
profile.set_preference(
152153
"security.mixed_content.block_active_content", False)
153-
if settings.DISABLE_CONTENT_SECURITY_POLICY:
154+
if settings.DISABLE_CSP_ON_FIREFOX or disable_csp:
154155
profile.set_preference("security.csp.enable", False)
155156
profile.set_preference(
156157
"browser.download.manager.showAlertOnComplete", False)
@@ -216,7 +217,7 @@ def validate_proxy_string(proxy_string):
216217

217218
def get_driver(browser_name, headless=False, use_grid=False,
218219
servername='localhost', port=4444, proxy_string=None,
219-
user_agent=None, cap_file=None):
220+
user_agent=None, cap_file=None, disable_csp=None):
220221
proxy_auth = False
221222
proxy_user = None
222223
proxy_pass = None
@@ -245,16 +246,16 @@ def get_driver(browser_name, headless=False, use_grid=False,
245246
if use_grid:
246247
return get_remote_driver(
247248
browser_name, headless, servername, port, proxy_string, proxy_auth,
248-
proxy_user, proxy_pass, user_agent, cap_file)
249+
proxy_user, proxy_pass, user_agent, cap_file, disable_csp)
249250
else:
250251
return get_local_driver(
251252
browser_name, headless, proxy_string, proxy_auth,
252-
proxy_user, proxy_pass, user_agent)
253+
proxy_user, proxy_pass, user_agent, disable_csp)
253254

254255

255256
def get_remote_driver(
256257
browser_name, headless, servername, port, proxy_string, proxy_auth,
257-
proxy_user, proxy_pass, user_agent, cap_file):
258+
proxy_user, proxy_pass, user_agent, cap_file, disable_csp):
258259
downloads_path = download_helper.get_downloads_folder()
259260
download_helper.reset_downloads_folder()
260261
address = "http://%s:%s/wd/hub" % (servername, port)
@@ -264,7 +265,7 @@ def get_remote_driver(
264265
if browser_name == constants.Browser.GOOGLE_CHROME:
265266
chrome_options = _set_chrome_options(
266267
downloads_path, headless, proxy_string, proxy_auth,
267-
proxy_user, proxy_pass, user_agent)
268+
proxy_user, proxy_pass, user_agent, disable_csp)
268269
if headless:
269270
if not proxy_auth:
270271
# Headless Chrome doesn't support extensions, which are
@@ -285,7 +286,7 @@ def get_remote_driver(
285286
try:
286287
# Use Geckodriver for Firefox if it's on the PATH
287288
profile = _create_firefox_profile(
288-
downloads_path, proxy_string, user_agent)
289+
downloads_path, proxy_string, user_agent, disable_csp)
289290
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
290291
firefox_capabilities['marionette'] = True
291292
if headless:
@@ -302,7 +303,7 @@ def get_remote_driver(
302303
except WebDriverException:
303304
# Don't use Geckodriver: Only works for old versions of Firefox
304305
profile = _create_firefox_profile(
305-
downloads_path, proxy_string, user_agent)
306+
downloads_path, proxy_string, user_agent, disable_csp)
306307
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
307308
firefox_capabilities['marionette'] = False
308309
if headless:
@@ -382,7 +383,7 @@ def get_remote_driver(
382383

383384
def get_local_driver(
384385
browser_name, headless, proxy_string, proxy_auth,
385-
proxy_user, proxy_pass, user_agent):
386+
proxy_user, proxy_pass, user_agent, disable_csp):
386387
'''
387388
Spins up a new web browser and returns the driver.
388389
Can also be used to spin up additional browsers for the same test.
@@ -395,7 +396,7 @@ def get_local_driver(
395396
try:
396397
# Use Geckodriver for Firefox if it's on the PATH
397398
profile = _create_firefox_profile(
398-
downloads_path, proxy_string, user_agent)
399+
downloads_path, proxy_string, user_agent, disable_csp)
399400
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
400401
firefox_capabilities['marionette'] = True
401402
options = webdriver.FirefoxOptions()
@@ -416,7 +417,7 @@ def get_local_driver(
416417
except WebDriverException:
417418
# Don't use Geckodriver: Only works for old versions of Firefox
418419
profile = _create_firefox_profile(
419-
downloads_path, proxy_string, user_agent)
420+
downloads_path, proxy_string, user_agent, disable_csp)
420421
firefox_capabilities = DesiredCapabilities.FIREFOX.copy()
421422
firefox_capabilities['marionette'] = False
422423
firefox_driver = webdriver.Firefox(
@@ -475,7 +476,7 @@ def get_local_driver(
475476
try:
476477
chrome_options = _set_chrome_options(
477478
downloads_path, headless, proxy_string, proxy_auth,
478-
proxy_user, proxy_pass, user_agent)
479+
proxy_user, proxy_pass, user_agent, disable_csp)
479480
if headless:
480481
# Headless Chrome doesn't support extensions, which are
481482
# required when using a proxy server that has authentication.

seleniumbase/fixtures/base_case.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,7 +2405,7 @@ def save_screenshot(self, name, folder=None):
24052405

24062406
def get_new_driver(self, browser=None, headless=None,
24072407
servername=None, port=None, proxy=None, agent=None,
2408-
switch_to=True, cap_file=None):
2408+
switch_to=True, cap_file=None, disable_csp=None):
24092409
""" This method spins up an extra browser for tests that require
24102410
more than one. The first browser is already provided by tests
24112411
that import base_case.BaseCase from seleniumbase. If parameters
@@ -2473,7 +2473,8 @@ def get_new_driver(self, browser=None, headless=None,
24732473
port=port,
24742474
proxy_string=proxy_string,
24752475
user_agent=user_agent,
2476-
cap_file=cap_file)
2476+
cap_file=cap_file,
2477+
disable_csp=disable_csp)
24772478
self._drivers_list.append(new_driver)
24782479
if switch_to:
24792480
self.driver = new_driver
@@ -2843,6 +2844,7 @@ def setUp(self):
28432844
self.js_checking_on = sb_config.js_checking_on
28442845
self.ad_block_on = sb_config.ad_block_on
28452846
self.verify_delay = sb_config.verify_delay
2847+
self.disable_csp = sb_config.disable_csp
28462848
self.save_screenshot_after_test = sb_config.save_screenshot
28472849
self.timeout_multiplier = sb_config.timeout_multiplier
28482850
self.use_grid = False
@@ -2910,7 +2912,8 @@ def setUp(self):
29102912
proxy=self.proxy_string,
29112913
agent=self.user_agent,
29122914
switch_to=True,
2913-
cap_file=self.cap_file)
2915+
cap_file=self.cap_file,
2916+
disable_csp=self.disable_csp)
29142917
self._default_driver = self.driver
29152918

29162919
def __insert_test_result(self, state, err):

seleniumbase/plugins/pytest_plugin.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ def pytest_addoption(parser):
159159
default=None,
160160
help="""Setting this overrides the default wait time
161161
before each MasterQA verification pop-up.""")
162+
parser.addoption('--disable_csp', action="store_true",
163+
dest='disable_csp',
164+
default=False,
165+
help="""Using this disables the Content Security Policy of
166+
websites, which may interfere with some features of
167+
SeleniumBase, such as loading custom JavaScript
168+
libraries for various testing actions.
169+
Setting this to True (--disable_csp) overrides the
170+
value set in seleniumbase/config/settings.py""")
162171
parser.addoption('--save_screenshot', action='store_true',
163172
dest='save_screenshot',
164173
default=False,
@@ -201,6 +210,7 @@ def pytest_configure(config):
201210
sb_config.js_checking_on = config.getoption('js_checking_on')
202211
sb_config.ad_block_on = config.getoption('ad_block_on')
203212
sb_config.verify_delay = config.getoption('verify_delay')
213+
sb_config.disable_csp = config.getoption('disable_csp')
204214
sb_config.save_screenshot = config.getoption('save_screenshot')
205215
sb_config.timeout_multiplier = config.getoption('timeout_multiplier')
206216

seleniumbase/plugins/selenium_plugin.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class SeleniumBrowser(Plugin):
2828
self.options.js_checking_on -- option to check for js errors (--check_js)
2929
self.options.ad_block -- the option to block some display ads (--ad_block)
3030
self.options.verify_delay -- delay before MasterQA checks (--verify_delay)
31+
self.options.disable_csp -- disable Content Security Policy (--disable_csp)
3132
self.options.save_screenshot -- save screen after test (--save_screenshot)
3233
self.options.timeout_multiplier -- increase defaults (--timeout_multiplier)
3334
"""
@@ -127,6 +128,16 @@ def options(self, parser, env):
127128
dest='verify_delay', default=None,
128129
help="""Setting this overrides the default wait time
129130
before each MasterQA verification pop-up.""")
131+
parser.add_option(
132+
'--disable_csp', action="store_true",
133+
dest='disable_csp',
134+
default=False,
135+
help="""Using this disables the Content Security Policy of
136+
websites, which may interfere with some features of
137+
SeleniumBase, such as loading custom JavaScript
138+
libraries for various testing actions.
139+
Setting this to True (--disable_csp) overrides the
140+
value set in seleniumbase/config/settings.py""")
130141
parser.add_option(
131142
'--save_screenshot', action="store_true",
132143
dest='save_screenshot',
@@ -163,6 +174,7 @@ def beforeTest(self, test):
163174
test.test.js_checking_on = self.options.js_checking_on
164175
test.test.ad_block_on = self.options.ad_block_on
165176
test.test.verify_delay = self.options.verify_delay # MasterQA
177+
test.test.disable_csp = self.options.disable_csp
166178
test.test.save_screenshot_after_test = self.options.save_screenshot
167179
test.test.timeout_multiplier = self.options.timeout_multiplier
168180
test.test.use_grid = False

0 commit comments

Comments
 (0)