Skip to content

Update chrome options; update valid proxy input; and add a method #151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions help_docs/method_summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions help_docs/webdriver_installation.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down Expand Up @@ -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
```
Expand Down
1 change: 0 additions & 1 deletion seleniumbase/config/proxy_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

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,
Expand Down
118 changes: 63 additions & 55 deletions seleniumbase/core/browser_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@
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):
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
60 changes: 47 additions & 13 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,12 @@ def get_link_attribute(self, link_text, attribute, hard_fail=True):
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

Expand All @@ -214,15 +214,15 @@ def wait_for_link_text_present(self, link_text,
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
if now_ms >= stop_ms:
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):
Expand Down Expand Up @@ -336,9 +336,9 @@ def click_partial_link_text(self, partial_link_text,
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)
Expand Down Expand Up @@ -405,7 +405,7 @@ def get_attribute(self, selector, attribute, by=By.CSS_SELECTOR,
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):
Expand Down Expand Up @@ -706,6 +706,40 @@ def activate_jquery(self):
# 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:
Expand All @@ -717,10 +751,10 @@ def bring_to_front(self, selector, by=By.CSS_SELECTOR):
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)

Expand Down Expand Up @@ -960,7 +994,7 @@ def convert_to_css_selector(self, selector, by):
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,
Expand Down Expand Up @@ -1081,12 +1115,12 @@ def generate_referral(self, start_page, destination_page):
(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)
Expand Down
2 changes: 1 addition & 1 deletion server_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

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',
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

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',
Expand Down