Merge pull request #151 from seleniumbase/update-chrome-options-and-proxy

Update chrome options; update valid proxy input; and add a method
This commit is contained in:
Michael Mintz 2018-03-21 02:58:04 -04:00 committed by GitHub
commit ce7b83ad97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 76 deletions

View File

@ -85,6 +85,9 @@ self.maximize_window()
self.activate_jquery()
self.get_property_value(selector, property, by=By.CSS_SELECTOR,
timeout=settings.SMALL_TIMEOUT)
self.bring_to_front(selector, by=By.CSS_SELECTOR)
self.highlight(selector, by=By.CSS_SELECTOR, loops=4, scroll=True)

View File

@ -1,9 +1,9 @@
## Installing Google Chromedriver, Firefox Geckodriver, and other drivers
To run automation on various web browsers, you'll need to download a driver file for each one and place it on your System **[PATH](http://java.com/en/download/help/path.xml)**. On a Mac, ``/usr/local/bin`` is a good spot. On Windows, make sure you set the System Path under Environment Variables to include the location where you placed the driver files:
To run automation on various web browsers, you'll need to download a driver file for each one and place it on your System **[PATH](http://java.com/en/download/help/path.xml)**. On a Mac, ``/usr/local/bin`` is a good spot. On Windows, make sure you set the System Path under Environment Variables to include the location where you placed the driver files. You may want to download newer versions of drivers as they become available.
* For Chrome, get [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) on your System Path. (**[Version 2.37](https://chromedriver.storage.googleapis.com/index.html?path=2.37/) or above is recommended!**)
* For Chrome, get [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) on your System Path.
* For Firefox, get [Geckodriver](https://github.com/mozilla/geckodriver/releases) on your System Path.
@ -34,15 +34,15 @@ brew upgrade geckodriver
Linux:
```bash
wget http://chromedriver.storage.googleapis.com/2.36/chromedriver_linux64.zip
wget http://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/local/bin/
chmod +x /usr/local/bin/chromedriver
```
```bash
wget https://github.com/mozilla/geckodriver/releases/download/v0.19.1/geckodriver-v0.19.1-linux64.tar.gz
tar xvfz geckodriver-v0.19.1-linux64.tar.gz
wget https://github.com/mozilla/geckodriver/releases/download/v0.20.0/geckodriver-v0.20.0-linux64.tar.gz
tar xvfz geckodriver-v0.20.0-linux64.tar.gz
mv geckodriver /usr/local/bin/
chmod +x /usr/local/bin/geckodriver
```

View File

@ -19,7 +19,6 @@ you can try finding one from one of following sites:
PROXY_LIST = {
# "example1": "35.196.26.166:3128", # (Example) - set your own proxy here
# "example2": "208.95.62.81:3128", # (Example) - set your own proxy here
"proxy1": None,
"proxy2": None,
"proxy3": None,

View File

@ -7,6 +7,38 @@ from seleniumbase.config import settings
from seleniumbase.config import proxy_list
from seleniumbase.core import download_helper
from seleniumbase.fixtures import constants
from seleniumbase.fixtures import page_utils
def _set_chrome_options(downloads_path, proxy_string):
chrome_options = webdriver.ChromeOptions()
prefs = {
"download.default_directory": downloads_path,
"credentials_enable_service": False,
"profile": {
"password_manager_enabled": False
}
}
chrome_options.add_experimental_option("prefs", prefs)
chrome_options.add_argument("--test-type")
chrome_options.add_argument("--no-first-run")
chrome_options.add_argument("--ignore-certificate-errors")
chrome_options.add_argument("--allow-file-access-from-files")
chrome_options.add_argument("--allow-insecure-localhost")
chrome_options.add_argument("--allow-running-insecure-content")
chrome_options.add_argument("--disable-infobars")
chrome_options.add_argument("--disable-save-password-bubble")
chrome_options.add_argument("--disable-single-click-autofill")
chrome_options.add_argument("--disable-translate")
chrome_options.add_argument("--disable-web-security")
if proxy_string:
chrome_options.add_argument('--proxy-server=%s' % proxy_string)
if settings.START_CHROME_IN_FULL_SCREEN_MODE:
# Run Chrome in full screen mode on WINDOWS
chrome_options.add_argument("--start-maximized")
# Run Chrome in full screen mode on MAC/Linux
chrome_options.add_argument("--kiosk")
return chrome_options
def _create_firefox_profile(downloads_path, proxy_string):
@ -42,8 +74,8 @@ def _create_firefox_profile(downloads_path, proxy_string):
def display_proxy_warning(proxy_string):
message = ('\n\nWARNING: Proxy String ["%s"] is NOT in the expected '
'"ip_address:port" format, (OR the key does not exist '
'in proxy_list.PROXY_LIST). '
'"ip_address:port" or "server:port" format, '
'(OR the key does not exist in proxy_list.PROXY_LIST). '
'*** DEFAULTING to NOT USING a Proxy Server! ***'
% proxy_string)
warnings.simplefilter('always', Warning) # See Warnings
@ -56,10 +88,24 @@ def validate_proxy_string(proxy_string):
proxy_string = proxy_list.PROXY_LIST[proxy_string]
if not proxy_string:
return None
valid = re.match('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$', proxy_string)
if valid:
proxy_string = valid.group()
valid = False
val_ip = re.match('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$', proxy_string)
if not val_ip:
if proxy_string.startswith('http://'):
proxy_string = proxy_string.split('http://')[1]
elif proxy_string.startswith('https://'):
proxy_string = proxy_string.split('https://')[1]
elif '://' in proxy_string:
proxy_string = proxy_string.split('://')[1]
chunks = proxy_string.split(':')
if len(chunks) == 2:
if re.match('^\d+$', chunks[1]):
if page_utils.is_valid_url('http://' + proxy_string):
valid = True
else:
proxy_string = val_ip.group()
valid = True
if not valid:
display_proxy_warning(proxy_string)
proxy_string = None
return proxy_string
@ -82,33 +128,14 @@ def get_remote_driver(browser_name, headless, servername, port, proxy_string):
address = "http://%s:%s/wd/hub" % (servername, port)
if browser_name == constants.Browser.GOOGLE_CHROME:
chrome_options = webdriver.ChromeOptions()
prefs = {
"download.default_directory": downloads_path,
"credentials_enable_service": False,
"profile": {
"password_manager_enabled": False
}
}
chrome_options.add_experimental_option("prefs", prefs)
chrome_options.add_argument("--allow-file-access-from-files")
chrome_options.add_argument("--allow-running-insecure-content")
chrome_options.add_argument("--disable-infobars")
chrome_options = _set_chrome_options(downloads_path, proxy_string)
if headless:
chrome_options.add_argument("--headless")
if proxy_string:
chrome_options.add_argument('--proxy-server=%s' % proxy_string)
if settings.START_CHROME_IN_FULL_SCREEN_MODE:
# Run Chrome in full screen mode on WINDOWS
chrome_options.add_argument("--start-maximized")
# Run Chrome in full screen mode on MAC/Linux
chrome_options.add_argument("--kiosk")
capabilities = chrome_options.to_capabilities()
return webdriver.Remote(
command_executor=address,
desired_capabilities=capabilities)
if browser_name == constants.Browser.FIREFOX:
elif browser_name == constants.Browser.FIREFOX:
try:
# Use Geckodriver for Firefox if it's on the PATH
profile = _create_firefox_profile(downloads_path, proxy_string)
@ -136,23 +163,22 @@ def get_remote_driver(browser_name, headless, servername, port, proxy_string):
command_executor=address,
desired_capabilities=capabilities,
browser_profile=profile)
if browser_name == constants.Browser.INTERNET_EXPLORER:
elif browser_name == constants.Browser.INTERNET_EXPLORER:
return webdriver.Remote(
command_executor=address,
desired_capabilities=(
webdriver.DesiredCapabilities.INTERNETEXPLORER))
if browser_name == constants.Browser.EDGE:
elif browser_name == constants.Browser.EDGE:
return webdriver.Remote(
command_executor=address,
desired_capabilities=(
webdriver.DesiredCapabilities.EDGE))
if browser_name == constants.Browser.SAFARI:
elif browser_name == constants.Browser.SAFARI:
return webdriver.Remote(
command_executor=address,
desired_capabilities=(
webdriver.DesiredCapabilities.SAFARI))
if browser_name == constants.Browser.PHANTOM_JS:
elif browser_name == constants.Browser.PHANTOM_JS:
with warnings.catch_warnings():
# Ignore "PhantomJS has been deprecated" UserWarning
warnings.simplefilter("ignore", category=UserWarning)
@ -195,40 +221,22 @@ def get_local_driver(browser_name, headless, proxy_string):
if headless:
raise Exception(e)
return webdriver.Firefox()
if browser_name == constants.Browser.INTERNET_EXPLORER:
elif browser_name == constants.Browser.INTERNET_EXPLORER:
return webdriver.Ie()
if browser_name == constants.Browser.EDGE:
elif browser_name == constants.Browser.EDGE:
return webdriver.Edge()
if browser_name == constants.Browser.SAFARI:
elif browser_name == constants.Browser.SAFARI:
return webdriver.Safari()
if browser_name == constants.Browser.PHANTOM_JS:
elif browser_name == constants.Browser.PHANTOM_JS:
with warnings.catch_warnings():
# Ignore "PhantomJS has been deprecated" UserWarning
warnings.simplefilter("ignore", category=UserWarning)
return webdriver.PhantomJS()
if browser_name == constants.Browser.GOOGLE_CHROME:
elif browser_name == constants.Browser.GOOGLE_CHROME:
try:
chrome_options = webdriver.ChromeOptions()
prefs = {
"download.default_directory": downloads_path,
"credentials_enable_service": False,
"profile": {
"password_manager_enabled": False
}
}
chrome_options.add_experimental_option("prefs", prefs)
chrome_options.add_argument("--allow-file-access-from-files")
chrome_options.add_argument("--allow-running-insecure-content")
chrome_options.add_argument("--disable-infobars")
chrome_options = _set_chrome_options(downloads_path, proxy_string)
if headless:
chrome_options.add_argument("--headless")
if proxy_string:
chrome_options.add_argument('--proxy-server=%s' % proxy_string)
if settings.START_CHROME_IN_FULL_SCREEN_MODE:
# Run Chrome in full screen mode on WINDOWS
chrome_options.add_argument("--start-maximized")
# Run Chrome in full screen mode on MAC/Linux
chrome_options.add_argument("--kiosk")
return webdriver.Chrome(options=chrome_options)
except Exception as e:
if headless:

View File

@ -198,12 +198,12 @@ class BaseCase(unittest.TestCase):
return attribute_value
if hard_fail:
raise Exception(
'Unable to find attribute [%s] from link text [%s]!'
'Unable to find attribute {%s} from link text {%s}!'
% (attribute, link_text))
else:
return None
if hard_fail:
raise Exception("Link text [%s] was not found!" % link_text)
raise Exception("Link text {%s} was not found!" % link_text)
else:
return None
@ -214,7 +214,7 @@ class BaseCase(unittest.TestCase):
for x in range(int(timeout * 5)):
try:
if not self.is_link_text_present(link_text):
raise Exception("Link text [%s] not found!" % link_text)
raise Exception("Link text {%s} not found!" % link_text)
return
except Exception:
now_ms = time.time() * 1000.0
@ -222,7 +222,7 @@ class BaseCase(unittest.TestCase):
break
time.sleep(0.2)
raise Exception(
"Link text [%s] was not present after %s seconds!" % (
"Link text {%s} was not present after %s seconds!" % (
link_text, timeout))
def click_link_text(self, link_text, timeout=settings.SMALL_TIMEOUT):
@ -336,9 +336,9 @@ class BaseCase(unittest.TestCase):
return
raise Exception(
'Could not parse link from partial link_text '
'[%s]' % partial_link_text)
'{%s}' % partial_link_text)
raise Exception(
"Partial link text [%s] was not found!" % partial_link_text)
"Partial link text {%s} was not found!" % partial_link_text)
# Not using phantomjs
element = self.wait_for_partial_link_text(
partial_link_text, timeout=timeout)
@ -405,7 +405,7 @@ class BaseCase(unittest.TestCase):
if attribute_value is not None:
return attribute_value
else:
raise Exception("Element [%s] has no attribute [%s]!" % (
raise Exception("Element {%s} has no attribute {%s}!" % (
selector, attribute))
def refresh_page(self):
@ -706,6 +706,40 @@ class BaseCase(unittest.TestCase):
# Since jQuery still isn't activating, give up and raise an exception
raise Exception("Exception: WebDriver could not activate jQuery!")
def get_property_value(self, selector, property, by=By.CSS_SELECTOR,
timeout=settings.SMALL_TIMEOUT):
""" Returns the property value of a page element's computed style.
Example:
opacity = self.get_property_value("html body a", "opacity")
self.assertTrue(float(opacity) > 0, "Element not visible!") """
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self._get_new_timeout(timeout)
if page_utils.is_xpath_selector(selector):
by = By.XPATH
if page_utils.is_link_text_selector(selector):
selector = page_utils.get_link_text_from_selector(selector)
by = By.LINK_TEXT
self.wait_for_ready_state_complete()
page_actions.wait_for_element_present(
self.driver, selector, by, timeout)
try:
selector = self.convert_to_css_selector(selector, by=by)
except Exception:
# Don't run action if can't convert to CSS_Selector for JavaScript
raise Exception(
"Exception: Could not convert {%s}(by=%s) to CSS_SELECTOR!" % (
selector, by))
selector = self.jq_format(selector)
script = ("""var $elm = document.querySelector('%s');
$val = window.getComputedStyle($elm).getPropertyValue('%s');
return $val;"""
% (selector, property))
value = self.execute_script(script)
if value is not None:
return value
else:
return "" # Return an empty string if the property doesn't exist
def bring_to_front(self, selector, by=By.CSS_SELECTOR):
""" Updates the Z-index of a page element to bring it into view.
Useful when getting a WebDriverException, such as the one below:
@ -717,10 +751,10 @@ class BaseCase(unittest.TestCase):
try:
selector = self.convert_to_css_selector(selector, by=by)
except Exception:
# Don't perform action if can't convert to CSS_SELECTOR for jQuery
# Don't run action if can't convert to CSS_Selector for JavaScript
return
script = ("""document.querySelector('%s').style.zIndex = "1";"""
selector = self.jq_format(selector)
script = ("""document.querySelector('%s').style.zIndex = "100";"""
% selector)
self.execute_script(script)
@ -960,7 +994,7 @@ class BaseCase(unittest.TestCase):
return 'a:contains("%s")' % selector
else:
raise Exception(
"Exception: Could not convert [%s](by=%s) to CSS_SELECTOR!" % (
"Exception: Could not convert {%s}(by=%s) to CSS_SELECTOR!" % (
selector, by))
def set_value(self, selector, new_value, by=By.CSS_SELECTOR,
@ -1081,12 +1115,12 @@ class BaseCase(unittest.TestCase):
(This generates real traffic for testing analytics software.) """
if not page_utils.is_valid_url(destination_page):
raise Exception(
"Exception: destination_page [%s] is not a valid URL!"
"Exception: destination_page {%s} is not a valid URL!"
% destination_page)
if start_page:
if not page_utils.is_valid_url(start_page):
raise Exception(
"Exception: start_page [%s] is not a valid URL! "
"Exception: start_page {%s} is not a valid URL! "
"(Use an empty string or None to start from current page.)"
% start_page)
self.open(start_page)

View File

@ -7,7 +7,7 @@ from setuptools import setup, find_packages # noqa
setup(
name='seleniumbase',
version='1.7.4',
version='1.7.5',
description='Web Automation & Testing Framework - http://seleniumbase.com',
long_description='Web Automation and Testing Framework - seleniumbase.com',
platforms='Mac * Windows * Linux * Docker',

View File

@ -7,7 +7,7 @@ from setuptools import setup, find_packages # noqa
setup(
name='seleniumbase',
version='1.7.4',
version='1.7.5',
description='Web Automation & Testing Framework - http://seleniumbase.com',
long_description='Web Automation and Testing Framework - seleniumbase.com',
platforms='Mac * Windows * Linux * Docker',