Enable PhantomJS for running Selenium tests
This patch enables the PhantomJS webdriver for running the Selenium test suite. Use it with the --selenium-phantomjs command-line switch when executing the selenium and integration suite. Change-Id: I443e6f6d7d1911df500b360f7c22686b417fbeae Blueprint: enable-phantomjs-selenium
This commit is contained in:
parent
ab7d5c3ec5
commit
861f9c2c4a
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,3 +35,4 @@ dist
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
tags
|
||||
ghostdriver.log
|
||||
|
@ -45,6 +45,16 @@ for a Debian OS flavour, or for Fedora/Red Hat flavours:
|
||||
|
||||
$ sudo yum install xorg-x11-server-Xvfb
|
||||
|
||||
If you can't run a virtual display, or would prefer not to, you can use the
|
||||
PhantomJS web driver instead:
|
||||
|
||||
$ ./run_tests.sh --with-selenium --selenium-phantomjs
|
||||
|
||||
If you need to install PhantomJS, you may do so with `npm` like this:
|
||||
|
||||
$ npm -g install phantomjs
|
||||
|
||||
|
||||
Writing tests
|
||||
=============
|
||||
|
||||
|
@ -25,30 +25,33 @@ import subprocess
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# Select the WebDriver to use based on the --selenium-phantomjs switch.
|
||||
# NOTE: Several distributions can't ship Selenium, or the Firefox
|
||||
# component of it, due to its non-free license. So they have to patch
|
||||
# it out of test-requirements.txt Avoid import failure and force not
|
||||
# running selenium tests if we attempt to run selenium tests using the
|
||||
# Firefox driver and it is not available.
|
||||
try:
|
||||
# NOTE: Several distribution can't ship selenium due to its
|
||||
# non-free license. So they have to patch it out of test-requirements.txt
|
||||
# Avoid import failure and force not running selenium tests.
|
||||
# The entire file is encapsulated in the try block because the classes
|
||||
# inherit from the firefox class contained in selenium.webdriver, and
|
||||
# python will throw a NameError if the import is skipped.
|
||||
if os.environ.get('SELENIUM_PHANTOMJS'):
|
||||
from selenium.webdriver import PhantomJS as WebDriver
|
||||
else:
|
||||
from selenium.common import exceptions as selenium_exceptions
|
||||
from selenium.webdriver import firefox
|
||||
|
||||
class FirefoxBinary(firefox.firefox_binary.FirefoxBinary):
|
||||
"""Workarounds selenium firefox issues.
|
||||
|
||||
There is race condition in the way firefox is spawned. The exact cause
|
||||
hasn't been properly diagnosed yet but it's around:
|
||||
There is race condition in the way firefox is spawned. The exact
|
||||
cause hasn't been properly diagnosed yet but it's around:
|
||||
|
||||
- getting a free port from the OS with selenium.webdriver.common.utils
|
||||
free_port(),
|
||||
- getting a free port from the OS with
|
||||
selenium.webdriver.common.utils free_port(),
|
||||
|
||||
- release the port immediately but record it in ff prefs so that ff can
|
||||
listen on that port for the internal http server.
|
||||
- release the port immediately but record it in ff prefs so that ff
|
||||
can listen on that port for the internal http server.
|
||||
|
||||
It has been observed that this leads to hanging processes for 'firefox
|
||||
-silent'.
|
||||
It has been observed that this leads to hanging processes for
|
||||
'firefox -silent'.
|
||||
"""
|
||||
|
||||
def _start_from_profile_path(self, path):
|
||||
@ -61,8 +64,8 @@ try:
|
||||
for cli in self.command_line:
|
||||
command.append(cli)
|
||||
|
||||
# The following exists upstream and is known to create hanging firefoxes,
|
||||
# leading to zombies.
|
||||
# The following exists upstream and is known to create hanging
|
||||
# firefoxes, leading to zombies.
|
||||
# subprocess.Popen(command, stdout=self._log_file,
|
||||
# stderr=subprocess.STDOUT,
|
||||
# env=self._firefox_env).communicate()
|
||||
@ -78,8 +81,8 @@ try:
|
||||
timeout=30, capabilities=None, proxy=None):
|
||||
try:
|
||||
super(WebDriver, self).__init__(
|
||||
firefox_profile, FirefoxBinary(), timeout, capabilities,
|
||||
proxy)
|
||||
firefox_profile, FirefoxBinary(), timeout,
|
||||
capabilities, proxy)
|
||||
except selenium_exceptions.WebDriverException:
|
||||
# If we can't start, cleanup profile
|
||||
shutil.rmtree(self.profile.path)
|
||||
@ -88,8 +91,5 @@ try:
|
||||
raise
|
||||
|
||||
except ImportError as e:
|
||||
# NOTE(saschpe): Several distribution can't ship selenium due to its
|
||||
# non-free license. So they have to patch it out of test-requirements.txt
|
||||
# Avoid import failure and force not running selenium tests.
|
||||
LOG.warning("{0}, force WITH_SELENIUM=False".format(str(e)))
|
||||
os.environ['WITH_SELENIUM'] = ''
|
||||
|
@ -17,7 +17,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
from socket import timeout as socket_timeout # noqa
|
||||
import unittest
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django import http
|
||||
@ -411,6 +413,8 @@ class SeleniumTests(test.SeleniumTestCase):
|
||||
self.assertTrue("ISO" in body.text,
|
||||
"ISO should be selected when the extension is *.iso")
|
||||
|
||||
@unittest.skipIf(os.environ.get('SELENIUM_PHANTOMJS'),
|
||||
"PhantomJS cannot test file upload widgets.")
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',)})
|
||||
def test_modal_create_image_from_file(self):
|
||||
driver = self.selenium
|
||||
@ -471,6 +475,8 @@ class SeleniumTests(test.SeleniumTestCase):
|
||||
self.assertTrue("ISO" in body.text,
|
||||
"ISO should be selected when the extension is *.iso")
|
||||
|
||||
@unittest.skipIf(os.environ.get('SELENIUM_PHANTOMJS'),
|
||||
"PhantomJS cannot test file upload widgets.")
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',)})
|
||||
def test_create_image_from_file(self):
|
||||
driver = self.selenium
|
||||
|
@ -9,6 +9,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import os
|
||||
import time
|
||||
|
||||
from selenium.common import exceptions
|
||||
@ -145,7 +146,14 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement):
|
||||
return result
|
||||
|
||||
|
||||
class WebDriverWrapper(WrapperFindOverride, webdriver.Firefox):
|
||||
# select the active webdriver based on whether we --selenium-phantomjs or not
|
||||
if os.environ.get('SELENIUM_PHANTOMJS'):
|
||||
WebDriver = webdriver.PhantomJS
|
||||
else:
|
||||
WebDriver = webdriver.Firefox
|
||||
|
||||
|
||||
class WebDriverWrapper(WrapperFindOverride, WebDriver):
|
||||
"""Wrapper for webdriver to return WebElementWrapper on find_element."""
|
||||
def __init__(self, logging_prefs=None, capabilities=None, **kwargs):
|
||||
if capabilities is None:
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Selenium tests may now be exercised using the headless PhantomJS driver.
|
@ -33,6 +33,7 @@ function usage {
|
||||
echo " --only-selenium Run only the Selenium unit tests"
|
||||
echo " --with-selenium Run unit tests including Selenium tests"
|
||||
echo " --selenium-headless Run Selenium tests headless"
|
||||
echo " --selenium-phantomjs Run Selenium tests using phantomjs (headless)"
|
||||
echo " --integration Run the integration tests (requires a running "
|
||||
echo " OpenStack environment)"
|
||||
echo " --runserver Run the Django development server for"
|
||||
@ -79,6 +80,7 @@ runserver=0
|
||||
only_selenium=0
|
||||
with_selenium=0
|
||||
selenium_headless=0
|
||||
selenium_phantomjs=0
|
||||
integration=0
|
||||
testopts=""
|
||||
testargs=""
|
||||
@ -121,6 +123,7 @@ function process_option {
|
||||
--only-selenium) only_selenium=1;;
|
||||
--with-selenium) with_selenium=1;;
|
||||
--selenium-headless) selenium_headless=1;;
|
||||
--selenium-phantomjs) selenium_phantomjs=1;;
|
||||
--integration) integration=1;;
|
||||
--docs) just_docs=1;;
|
||||
--runserver) runserver=1;;
|
||||
@ -347,6 +350,10 @@ function run_tests {
|
||||
export SELENIUM_HEADLESS=1
|
||||
fi
|
||||
|
||||
if [ $selenium_phantomjs -eq 1 ]; then
|
||||
export SELENIUM_PHANTOMJS=1
|
||||
fi
|
||||
|
||||
if [ -z "$testargs" ]; then
|
||||
run_tests_all
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user