Update command-line parameters for Chrome control

This commit is contained in:
Michael Mintz 2019-07-14 01:05:47 -04:00
parent b28ac8464b
commit f15546b168
4 changed files with 130 additions and 15 deletions

View File

@ -97,7 +97,8 @@ def _add_chrome_disable_csp_extension(chrome_options):
def _set_chrome_options( def _set_chrome_options(
downloads_path, headless, proxy_string, proxy_auth, downloads_path, headless, proxy_string, proxy_auth,
proxy_user, proxy_pass, user_agent, disable_csp): proxy_user, proxy_pass, user_agent, disable_csp, enable_sync,
user_data_dir, extension_zip, extension_dir):
chrome_options = webdriver.ChromeOptions() chrome_options = webdriver.ChromeOptions()
prefs = { prefs = {
"download.default_directory": downloads_path, "download.default_directory": downloads_path,
@ -108,6 +109,19 @@ def _set_chrome_options(
} }
} }
chrome_options.add_experimental_option("prefs", prefs) chrome_options.add_experimental_option("prefs", prefs)
if enable_sync:
chrome_options.add_experimental_option(
"excludeSwitches", ["disable-sync"])
chrome_options.add_argument("--enable-sync")
if user_data_dir:
abs_path = os.path.abspath(user_data_dir)
chrome_options.add_argument("user-data-dir=%s" % abs_path)
if extension_zip:
abs_path = os.path.abspath(extension_zip)
chrome_options.add_extension(abs_path)
if extension_dir:
abs_path = os.path.abspath(extension_dir)
chrome_options.add_argument("--load-extension=%s" % abs_path)
chrome_options.add_argument("--test-type") chrome_options.add_argument("--test-type")
chrome_options.add_argument("--log-level=3") chrome_options.add_argument("--log-level=3")
chrome_options.add_argument("--no-first-run") chrome_options.add_argument("--no-first-run")
@ -245,7 +259,9 @@ def validate_proxy_string(proxy_string):
def get_driver(browser_name, headless=False, use_grid=False, def get_driver(browser_name, headless=False, use_grid=False,
servername='localhost', port=4444, proxy_string=None, servername='localhost', port=4444, proxy_string=None,
user_agent=None, cap_file=None, disable_csp=None): user_agent=None, cap_file=None, disable_csp=None,
enable_sync=None, user_data_dir=None,
extension_zip=None, extension_dir=None):
proxy_auth = False proxy_auth = False
proxy_user = None proxy_user = None
proxy_pass = None proxy_pass = None
@ -271,19 +287,27 @@ def get_driver(browser_name, headless=False, use_grid=False,
proxy_string = validate_proxy_string(proxy_string) proxy_string = validate_proxy_string(proxy_string)
if proxy_string and proxy_user and proxy_pass: if proxy_string and proxy_user and proxy_pass:
proxy_auth = True proxy_auth = True
if browser_name == "chrome" and user_data_dir and len(user_data_dir) < 3:
raise Exception(
"Name length of Chrome's User Data Directory must be >= 3.")
if use_grid: if use_grid:
return get_remote_driver( return get_remote_driver(
browser_name, headless, servername, port, proxy_string, proxy_auth, browser_name, headless, servername, port,
proxy_user, proxy_pass, user_agent, cap_file, disable_csp) proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
cap_file, disable_csp, enable_sync, user_data_dir,
extension_zip, extension_dir)
else: else:
return get_local_driver( return get_local_driver(
browser_name, headless, proxy_string, proxy_auth, browser_name, headless,
proxy_user, proxy_pass, user_agent, disable_csp) proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
disable_csp, enable_sync, user_data_dir,
extension_zip, extension_dir)
def get_remote_driver( def get_remote_driver(
browser_name, headless, servername, port, proxy_string, proxy_auth, browser_name, headless, servername, port, proxy_string, proxy_auth,
proxy_user, proxy_pass, user_agent, cap_file, disable_csp): proxy_user, proxy_pass, user_agent, cap_file, disable_csp,
enable_sync, user_data_dir, extension_zip, extension_dir):
downloads_path = download_helper.get_downloads_folder() downloads_path = download_helper.get_downloads_folder()
download_helper.reset_downloads_folder() download_helper.reset_downloads_folder()
address = "http://%s:%s/wd/hub" % (servername, port) address = "http://%s:%s/wd/hub" % (servername, port)
@ -293,7 +317,8 @@ def get_remote_driver(
if browser_name == constants.Browser.GOOGLE_CHROME: if browser_name == constants.Browser.GOOGLE_CHROME:
chrome_options = _set_chrome_options( chrome_options = _set_chrome_options(
downloads_path, headless, proxy_string, proxy_auth, downloads_path, headless, proxy_string, proxy_auth,
proxy_user, proxy_pass, user_agent, disable_csp) proxy_user, proxy_pass, user_agent, disable_csp, enable_sync,
user_data_dir, extension_zip, extension_dir)
capabilities = chrome_options.to_capabilities() capabilities = chrome_options.to_capabilities()
for key in desired_caps.keys(): for key in desired_caps.keys():
capabilities[key] = desired_caps[key] capabilities[key] = desired_caps[key]
@ -400,8 +425,10 @@ def get_remote_driver(
def get_local_driver( def get_local_driver(
browser_name, headless, proxy_string, proxy_auth, browser_name, headless,
proxy_user, proxy_pass, user_agent, disable_csp): proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
disable_csp, enable_sync, user_data_dir,
extension_zip, extension_dir):
''' '''
Spins up a new web browser and returns the driver. Spins up a new web browser and returns the driver.
Can also be used to spin up additional browsers for the same test. Can also be used to spin up additional browsers for the same test.
@ -493,8 +520,10 @@ def get_local_driver(
elif browser_name == constants.Browser.GOOGLE_CHROME: elif browser_name == constants.Browser.GOOGLE_CHROME:
try: try:
chrome_options = _set_chrome_options( chrome_options = _set_chrome_options(
downloads_path, headless, proxy_string, proxy_auth, downloads_path, headless,
proxy_user, proxy_pass, user_agent, disable_csp) proxy_string, proxy_auth, proxy_user, proxy_pass, user_agent,
disable_csp, enable_sync, user_data_dir,
extension_zip, extension_dir)
if LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER): if LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER):
make_driver_executable_if_not(LOCAL_CHROMEDRIVER) make_driver_executable_if_not(LOCAL_CHROMEDRIVER)
return webdriver.Chrome( return webdriver.Chrome(

View File

@ -2722,7 +2722,9 @@ class BaseCase(unittest.TestCase):
def get_new_driver(self, browser=None, headless=None, def get_new_driver(self, browser=None, headless=None,
servername=None, port=None, proxy=None, agent=None, servername=None, port=None, proxy=None, agent=None,
switch_to=True, cap_file=None, disable_csp=None): switch_to=True, cap_file=None, disable_csp=None,
enable_sync=None, user_data_dir=None,
extension_zip=None, extension_dir=None):
""" This method spins up an extra browser for tests that require """ This method spins up an extra browser for tests that require
more than one. The first browser is already provided by tests more than one. The first browser is already provided by tests
that import base_case.BaseCase from seleniumbase. If parameters that import base_case.BaseCase from seleniumbase. If parameters
@ -2734,6 +2736,12 @@ class BaseCase(unittest.TestCase):
port - if using a Selenium Grid, set the host port here port - if using a Selenium Grid, set the host port here
proxy - if using a proxy server, specify the "host:port" combo here proxy - if using a proxy server, specify the "host:port" combo here
switch_to - the option to switch to the new driver (default = True) switch_to - the option to switch to the new driver (default = True)
cap_file - the file containing desired capabilities for the browser
disable_csp - an option to disable Chrome's Content Security Policy
enable_sync - the option to enable the "Chrome Sync" feature
user_data_dir - Chrome's User Data Directory to use (Chrome-only)
extension_zip - A Chrome Extension ZIP file to use (Chrome-only)
extension_dir - A Chrome Extension folder to use (Chrome-only)
""" """
if self.browser == "remote" and self.servername == "localhost": if self.browser == "remote" and self.servername == "localhost":
raise Exception('Cannot use "remote" browser driver on localhost!' raise Exception('Cannot use "remote" browser driver on localhost!'
@ -2777,6 +2785,14 @@ class BaseCase(unittest.TestCase):
user_agent = self.user_agent user_agent = self.user_agent
if disable_csp is None: if disable_csp is None:
disable_csp = self.disable_csp disable_csp = self.disable_csp
if enable_sync is None:
enable_sync = self.enable_sync
if user_data_dir is None:
user_data_dir = self.user_data_dir
if extension_zip is None:
extension_zip = self.extension_zip
if extension_dir is None:
extension_dir = self.extension_dir
if self.demo_mode or self.masterqa_mode: if self.demo_mode or self.masterqa_mode:
disable_csp = True disable_csp = True
if cap_file is None: if cap_file is None:
@ -2795,7 +2811,11 @@ class BaseCase(unittest.TestCase):
proxy_string=proxy_string, proxy_string=proxy_string,
user_agent=user_agent, user_agent=user_agent,
cap_file=cap_file, cap_file=cap_file,
disable_csp=disable_csp) disable_csp=disable_csp,
enable_sync=enable_sync,
user_data_dir=user_data_dir,
extension_zip=extension_zip,
extension_dir=extension_dir)
self._drivers_list.append(new_driver) self._drivers_list.append(new_driver)
if switch_to: if switch_to:
self.driver = new_driver self.driver = new_driver
@ -3213,6 +3233,10 @@ class BaseCase(unittest.TestCase):
self.ad_block_on = sb_config.ad_block_on self.ad_block_on = sb_config.ad_block_on
self.verify_delay = sb_config.verify_delay self.verify_delay = sb_config.verify_delay
self.disable_csp = sb_config.disable_csp self.disable_csp = sb_config.disable_csp
self.enable_sync = sb_config.enable_sync
self.user_data_dir = sb_config.user_data_dir
self.extension_zip = sb_config.extension_zip
self.extension_dir = sb_config.extension_dir
self.save_screenshot_after_test = sb_config.save_screenshot self.save_screenshot_after_test = sb_config.save_screenshot
self.visual_baseline = sb_config.visual_baseline self.visual_baseline = sb_config.visual_baseline
self.timeout_multiplier = sb_config.timeout_multiplier self.timeout_multiplier = sb_config.timeout_multiplier
@ -3286,7 +3310,11 @@ class BaseCase(unittest.TestCase):
agent=self.user_agent, agent=self.user_agent,
switch_to=True, switch_to=True,
cap_file=self.cap_file, cap_file=self.cap_file,
disable_csp=self.disable_csp) disable_csp=self.disable_csp,
enable_sync=self.enable_sync,
user_data_dir=self.user_data_dir,
extension_zip=self.extension_zip,
extension_dir=self.extension_dir)
self._default_driver = self.driver self._default_driver = self.driver
def __set_last_page_screenshot(self): def __set_last_page_screenshot(self):

View File

@ -45,6 +45,10 @@ def pytest_addoption(parser):
default=None, default=None,
help="""The file that stores browser desired capabilities help="""The file that stores browser desired capabilities
for BrowserStack or Sauce Labs web drivers.""") for BrowserStack or Sauce Labs web drivers.""")
parser.addoption('--user_data_dir', dest='user_data_dir',
default=None,
help="""The Chrome User Data Directory to use. (Profile)
If the directory doesn't exist, it'll be created.""")
parser.addoption('--with-testing_base', action="store_true", parser.addoption('--with-testing_base', action="store_true",
dest='with_testing_base', dest='with_testing_base',
default=True, default=True,
@ -117,6 +121,18 @@ def pytest_addoption(parser):
help="""Designates the User-Agent for the browser to use. help="""Designates the User-Agent for the browser to use.
Format: A string. Format: A string.
Default: None.""") Default: None.""")
parser.addoption('--extension_zip', action='store',
dest='extension_zip',
default=None,
help="""Designates the Chrome Extension ZIP file to load.
Format: A .zip file containing the Chrome extension.
Default: None.""")
parser.addoption('--extension_dir', action='store',
dest='extension_dir',
default=None,
help="""Designates the Chrome Extension folder to load.
Format: A directory containing the Chrome extension.
Default: None.""")
parser.addoption('--headless', action="store_true", parser.addoption('--headless', action="store_true",
dest='headless', dest='headless',
default=False, default=False,
@ -169,6 +185,10 @@ def pytest_addoption(parser):
libraries for various testing actions. libraries for various testing actions.
Setting this to True (--disable_csp) overrides the Setting this to True (--disable_csp) overrides the
value set in seleniumbase/config/settings.py""") value set in seleniumbase/config/settings.py""")
parser.addoption('--enable_sync', action="store_true",
dest='enable_sync',
default=False,
help="""Using this enables the "Chrome Sync" feature.""")
parser.addoption('--save_screenshot', action='store_true', parser.addoption('--save_screenshot', action='store_true',
dest='save_screenshot', dest='save_screenshot',
default=False, default=False,
@ -198,6 +218,8 @@ def pytest_configure(config):
sb_config.with_selenium = config.getoption('with_selenium') sb_config.with_selenium = config.getoption('with_selenium')
sb_config.user_agent = config.getoption('user_agent') sb_config.user_agent = config.getoption('user_agent')
sb_config.headless = config.getoption('headless') sb_config.headless = config.getoption('headless')
sb_config.extension_zip = config.getoption('extension_zip')
sb_config.extension_dir = config.getoption('extension_dir')
sb_config.with_testing_base = config.getoption('with_testing_base') sb_config.with_testing_base = config.getoption('with_testing_base')
sb_config.with_db_reporting = config.getoption('with_db_reporting') sb_config.with_db_reporting = config.getoption('with_db_reporting')
sb_config.with_s3_logging = config.getoption('with_s3_logging') sb_config.with_s3_logging = config.getoption('with_s3_logging')
@ -208,6 +230,7 @@ def pytest_configure(config):
sb_config.port = config.getoption('port') sb_config.port = config.getoption('port')
sb_config.proxy_string = config.getoption('proxy_string') sb_config.proxy_string = config.getoption('proxy_string')
sb_config.cap_file = config.getoption('cap_file') sb_config.cap_file = config.getoption('cap_file')
sb_config.user_data_dir = config.getoption('user_data_dir')
sb_config.database_env = config.getoption('database_env') sb_config.database_env = config.getoption('database_env')
sb_config.log_path = config.getoption('log_path') sb_config.log_path = config.getoption('log_path')
sb_config.archive_logs = config.getoption('archive_logs') sb_config.archive_logs = config.getoption('archive_logs')
@ -219,6 +242,7 @@ def pytest_configure(config):
sb_config.ad_block_on = config.getoption('ad_block_on') sb_config.ad_block_on = config.getoption('ad_block_on')
sb_config.verify_delay = config.getoption('verify_delay') sb_config.verify_delay = config.getoption('verify_delay')
sb_config.disable_csp = config.getoption('disable_csp') sb_config.disable_csp = config.getoption('disable_csp')
sb_config.enable_sync = config.getoption('enable_sync')
sb_config.save_screenshot = config.getoption('save_screenshot') sb_config.save_screenshot = config.getoption('save_screenshot')
sb_config.visual_baseline = config.getoption('visual_baseline') sb_config.visual_baseline = config.getoption('visual_baseline')
sb_config.timeout_multiplier = config.getoption('timeout_multiplier') sb_config.timeout_multiplier = config.getoption('timeout_multiplier')

View File

@ -16,10 +16,14 @@ class SeleniumBrowser(Plugin):
The following command line options are available to the tests: The following command line options are available to the tests:
self.options.browser -- the browser to use (--browser) self.options.browser -- the browser to use (--browser)
self.options.cap_file -- browser's desired capabilities file (--cap_file)
self.options.user_data_dir -- set Chrome's user data dir (--user_data_dir)
self.options.server -- the server used by the test (--server) self.options.server -- the server used by the test (--server)
self.options.port -- the port used by the test (--port) self.options.port -- the port used by the test (--port)
self.options.proxy -- designates the proxy server:port to use. (--proxy) self.options.proxy -- designates the proxy server:port to use. (--proxy)
self.options.agent -- designates the User Agent for the browser. (--agent) self.options.agent -- designates the User Agent for the browser. (--agent)
self.options.extension_zip -- load a Chrome Extension ZIP (--extension_zip)
self.options.extension_dir -- load a Chrome Extension DIR (--extension_dir)
self.options.headless -- the option to run headlessly (--headless) self.options.headless -- the option to run headlessly (--headless)
self.options.demo_mode -- the option to slow down Selenium (--demo_mode) self.options.demo_mode -- the option to slow down Selenium (--demo_mode)
self.options.demo_sleep -- Selenium action delay in DemoMode (--demo_sleep) self.options.demo_sleep -- Selenium action delay in DemoMode (--demo_sleep)
@ -29,6 +33,7 @@ class SeleniumBrowser(Plugin):
self.options.ad_block -- the option to block some display ads (--ad_block) self.options.ad_block -- the option to block some display ads (--ad_block)
self.options.verify_delay -- delay before MasterQA checks (--verify_delay) self.options.verify_delay -- delay before MasterQA checks (--verify_delay)
self.options.disable_csp -- disable Content Security Policy (--disable_csp) self.options.disable_csp -- disable Content Security Policy (--disable_csp)
self.options.enable_sync -- option to enable "Chrome Sync" (--enable_sync)
self.options.save_screenshot -- save screen after test (--save_screenshot) self.options.save_screenshot -- save screen after test (--save_screenshot)
self.options.visual_baseline -- set the visual baseline (--visual_baseline) self.options.visual_baseline -- set the visual baseline (--visual_baseline)
self.options.timeout_multiplier -- increase defaults (--timeout_multiplier) self.options.timeout_multiplier -- increase defaults (--timeout_multiplier)
@ -58,6 +63,12 @@ class SeleniumBrowser(Plugin):
default=None, default=None,
help="""The file that stores browser desired capabilities help="""The file that stores browser desired capabilities
for BrowserStack or Sauce Labs web drivers.""") for BrowserStack or Sauce Labs web drivers.""")
parser.add_option(
'--user_data_dir', action='store',
dest='user_data_dir',
default=None,
help="""The Chrome User Data Directory to use. (Chrome Profile)
If the directory doesn't exist, it'll be created.""")
parser.add_option( parser.add_option(
'--server', action='store', dest='servername', '--server', action='store', dest='servername',
default='localhost', default='localhost',
@ -84,6 +95,20 @@ class SeleniumBrowser(Plugin):
help="""Designates the User-Agent for the browser to use. help="""Designates the User-Agent for the browser to use.
Format: A string. Format: A string.
Default: None.""") Default: None.""")
parser.add_option(
'--extension_zip', action='store',
dest='extension_zip',
default=None,
help="""Designates the Chrome Extension ZIP file to load.
Format: A .zip file containing the Chrome extension.
Default: None.""")
parser.add_option(
'--extension_dir', action='store',
dest='extension_dir',
default=None,
help="""Designates the Chrome Extension folder to load.
Format: A directory containing the Chrome extension.
Default: None.""")
parser.add_option( parser.add_option(
'--headless', action="store_true", '--headless', action="store_true",
dest='headless', dest='headless',
@ -139,6 +164,11 @@ class SeleniumBrowser(Plugin):
libraries for various testing actions. libraries for various testing actions.
Setting this to True (--disable_csp) overrides the Setting this to True (--disable_csp) overrides the
value set in seleniumbase/config/settings.py""") value set in seleniumbase/config/settings.py""")
parser.add_option(
'--enable_sync', action="store_true",
dest='enable_sync',
default=False,
help="""Using this enables the "Chrome Sync" feature.""")
parser.add_option( parser.add_option(
'--save_screenshot', action="store_true", '--save_screenshot', action="store_true",
dest='save_screenshot', dest='save_screenshot',
@ -174,6 +204,9 @@ class SeleniumBrowser(Plugin):
test.test.headless = self.options.headless test.test.headless = self.options.headless
test.test.servername = self.options.servername test.test.servername = self.options.servername
test.test.port = self.options.port test.test.port = self.options.port
test.test.user_data_dir = self.options.user_data_dir
test.test.extension_zip = self.options.extension_zip
test.test.extension_dir = self.options.extension_dir
test.test.proxy_string = self.options.proxy_string test.test.proxy_string = self.options.proxy_string
test.test.user_agent = self.options.user_agent test.test.user_agent = self.options.user_agent
test.test.demo_mode = self.options.demo_mode test.test.demo_mode = self.options.demo_mode
@ -184,6 +217,7 @@ class SeleniumBrowser(Plugin):
test.test.ad_block_on = self.options.ad_block_on test.test.ad_block_on = self.options.ad_block_on
test.test.verify_delay = self.options.verify_delay # MasterQA test.test.verify_delay = self.options.verify_delay # MasterQA
test.test.disable_csp = self.options.disable_csp test.test.disable_csp = self.options.disable_csp
test.test.enable_sync = self.options.enable_sync
test.test.save_screenshot_after_test = self.options.save_screenshot test.test.save_screenshot_after_test = self.options.save_screenshot
test.test.visual_baseline = self.options.visual_baseline test.test.visual_baseline = self.options.visual_baseline
test.test.timeout_multiplier = self.options.timeout_multiplier test.test.timeout_multiplier = self.options.timeout_multiplier