Merge pull request #1044 from edx/zoldak/acceptance-grid
Add ability to run against generic selenium grid
This commit is contained in:
@@ -84,12 +84,26 @@ USE_I18N = True
|
||||
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
|
||||
INSTALLED_APPS += ('lettuce.django',)
|
||||
LETTUCE_APPS = ('contentstore',)
|
||||
LETTUCE_SERVER_PORT = choice(PORTS) if SAUCE.get('SAUCE_ENABLED') else randint(1024, 65535)
|
||||
LETTUCE_BROWSER = os.environ.get('LETTUCE_BROWSER', 'chrome')
|
||||
|
||||
# Where to run: local, saucelabs, or grid
|
||||
LETTUCE_SELENIUM_CLIENT = os.environ.get('LETTUCE_SELENIUM_CLIENT', 'local')
|
||||
|
||||
SELENIUM_GRID = {
|
||||
'URL': 'http://127.0.0.1:4444/wd/hub',
|
||||
'BROWSER': LETTUCE_BROWSER,
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# Lastly, see if the developer has any local overrides.
|
||||
try:
|
||||
from .private import * # pylint: disable=F0401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Because an override for where to run will affect which ports to use,
|
||||
# set this up after the local overrides.
|
||||
if LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
LETTUCE_SERVER_PORT = choice(PORTS)
|
||||
else:
|
||||
LETTUCE_SERVER_PORT = randint(1024, 65535)
|
||||
|
||||
@@ -43,18 +43,18 @@ LOGGER.info("Loading the lettuce acceptance testing terrain file...")
|
||||
MAX_VALID_BROWSER_ATTEMPTS = 20
|
||||
|
||||
|
||||
def get_username_and_key():
|
||||
def get_saucelabs_username_and_key():
|
||||
"""
|
||||
Returns the Sauce Labs username and access ID as set by environment variables
|
||||
"""
|
||||
return {"username": settings.SAUCE.get('USERNAME'), "access-key": settings.SAUCE.get('ACCESS_ID')}
|
||||
|
||||
|
||||
def set_job_status(jobid, passed=True):
|
||||
def set_saucelabs_job_status(jobid, passed=True):
|
||||
"""
|
||||
Sets the job status on sauce labs
|
||||
"""
|
||||
config = get_username_and_key()
|
||||
config = get_saucelabs_username_and_key()
|
||||
url = 'http://saucelabs.com/rest/v1/{}/jobs/{}'.format(config['username'], world.jobid)
|
||||
body_content = dumps({"passed": passed})
|
||||
base64string = encodestring('{}:{}'.format(config['username'], config['access-key']))[:-1]
|
||||
@@ -63,7 +63,7 @@ def set_job_status(jobid, passed=True):
|
||||
return result.status_code == 200
|
||||
|
||||
|
||||
def make_desired_capabilities():
|
||||
def make_saucelabs_desired_capabilities():
|
||||
"""
|
||||
Returns a DesiredCapabilities object corresponding to the environment sauce parameters
|
||||
"""
|
||||
@@ -88,9 +88,9 @@ def initial_setup(server):
|
||||
"""
|
||||
Launch the browser once before executing the tests.
|
||||
"""
|
||||
world.absorb(settings.SAUCE.get('SAUCE_ENABLED'), 'SAUCE_ENABLED')
|
||||
world.absorb(settings.LETTUCE_SELENIUM_CLIENT, 'LETTUCE_SELENIUM_CLIENT')
|
||||
|
||||
if not world.SAUCE_ENABLED:
|
||||
if world.LETTUCE_SELENIUM_CLIENT == 'local':
|
||||
browser_driver = getattr(settings, 'LETTUCE_BROWSER', 'chrome')
|
||||
|
||||
# There is an issue with ChromeDriver2 r195627 on Ubuntu
|
||||
@@ -121,15 +121,26 @@ def initial_setup(server):
|
||||
|
||||
world.browser.driver.set_window_size(1280, 1024)
|
||||
|
||||
else:
|
||||
config = get_username_and_key()
|
||||
elif world.LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
config = get_saucelabs_username_and_key()
|
||||
world.browser = Browser(
|
||||
'remote',
|
||||
url="http://{}:{}@ondemand.saucelabs.com:80/wd/hub".format(config['username'], config['access-key']),
|
||||
**make_desired_capabilities()
|
||||
**make_saucelabs_desired_capabilities()
|
||||
)
|
||||
world.browser.driver.implicitly_wait(30)
|
||||
|
||||
elif world.LETTUCE_SELENIUM_CLIENT == 'grid':
|
||||
world.browser = Browser(
|
||||
'remote',
|
||||
url=settings.SELENIUM_GRID.get('URL'),
|
||||
browser=settings.SELENIUM_GRID.get('BROWSER'),
|
||||
)
|
||||
world.browser.driver.implicitly_wait(30)
|
||||
|
||||
else:
|
||||
raise Exception("Unknown selenium client '{}'".format(world.LETTUCE_SELENIUM_CLIENT))
|
||||
|
||||
world.absorb(world.browser.driver.session_id, 'jobid')
|
||||
|
||||
|
||||
@@ -183,6 +194,6 @@ def teardown_browser(total):
|
||||
"""
|
||||
Quit the browser after executing the tests.
|
||||
"""
|
||||
if world.SAUCE_ENABLED:
|
||||
set_job_status(world.jobid, total.scenarios_ran == total.scenarios_passed)
|
||||
if world.LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
set_saucelabs_job_status(world.jobid, total.scenarios_ran == total.scenarios_passed)
|
||||
world.browser.quit()
|
||||
|
||||
@@ -138,9 +138,10 @@ def should_have_link_with_path_and_text(step, path, text):
|
||||
|
||||
@step(r'should( not)? see "(.*)" (?:somewhere|anywhere) (?:in|on) (?:the|this) page')
|
||||
def should_see_in_the_page(step, doesnt_appear, text):
|
||||
multiplier = 1
|
||||
if world.SAUCE_ENABLED:
|
||||
if world.LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
multiplier = 2
|
||||
else:
|
||||
multiplier = 1
|
||||
if doesnt_appear:
|
||||
assert world.browser.is_text_not_present(text, wait_time=5*multiplier)
|
||||
else:
|
||||
|
||||
@@ -36,7 +36,7 @@ SKIP_TESTS=""
|
||||
if [ ! -z ${LETTUCE_BROWSER+x} ]; then
|
||||
SKIP_TESTS="--tag -skip_$LETTUCE_BROWSER"
|
||||
fi
|
||||
if [ ! -z ${SAUCE_ENABLED+x} ]; then
|
||||
if [ "$LETTUCE_SELENIUM_CLIENT" == saucelabs ]; then
|
||||
# SAUCE_INFO is a - seperated string PLATFORM-BROWSER-VERSION-DEVICE
|
||||
# Error checking is done in the setting up of the browser
|
||||
IFS='-' read -a SAUCE <<< "${SAUCE_INFO}"
|
||||
|
||||
@@ -71,23 +71,6 @@ DATABASES = {
|
||||
}
|
||||
}
|
||||
|
||||
# Set up XQueue information so that the lms will send
|
||||
# requests to a mock XQueue server running locally
|
||||
XQUEUE_PORT = choice(PORTS) if SAUCE.get('SAUCE_ENABLED') else randint(1024, 65535)
|
||||
XQUEUE_INTERFACE = {
|
||||
"url": "http://127.0.0.1:%d" % XQUEUE_PORT,
|
||||
"django_auth": {
|
||||
"username": "lms",
|
||||
"password": "***REMOVED***"
|
||||
},
|
||||
"basic_auth": ('anant', 'agarwal'),
|
||||
}
|
||||
|
||||
|
||||
# Set up Video information so that the lms will send
|
||||
# requests to a mock Youtube server running locally
|
||||
VIDEO_PORT = XQUEUE_PORT + 2
|
||||
|
||||
# Forums are disabled in test.py to speed up unit tests, but we do not have
|
||||
# per-test control for acceptance tests
|
||||
MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True
|
||||
@@ -123,12 +106,52 @@ FEEDBACK_SUBMISSION_EMAIL = 'dummy@example.com'
|
||||
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
|
||||
INSTALLED_APPS += ('lettuce.django',)
|
||||
LETTUCE_APPS = ('courseware',)
|
||||
LETTUCE_SERVER_PORT = choice(PORTS) if SAUCE.get('SAUCE_ENABLED') else randint(1024, 65535)
|
||||
LETTUCE_BROWSER = os.environ.get('LETTUCE_BROWSER', 'chrome')
|
||||
|
||||
# Where to run: local, saucelabs, or grid
|
||||
LETTUCE_SELENIUM_CLIENT = os.environ.get('LETTUCE_SELENIUM_CLIENT', 'local')
|
||||
|
||||
SELENIUM_GRID = {
|
||||
'URL': 'http://127.0.0.1:4444/wd/hub',
|
||||
'BROWSER': LETTUCE_BROWSER,
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# Lastly, see if the developer has any local overrides.
|
||||
# See if the developer has any local overrides.
|
||||
try:
|
||||
from .private import * # pylint: disable=F0401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Because an override for where to run will affect which ports to use,
|
||||
# set these up after the local overrides.
|
||||
if LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
LETTUCE_SERVER_PORT = choice(PORTS)
|
||||
PORTS.remove(LETTUCE_SERVER_PORT)
|
||||
else:
|
||||
LETTUCE_SERVER_PORT = randint(1024, 65535)
|
||||
|
||||
# Set up XQueue information so that the lms will send
|
||||
# requests to a mock XQueue server running locally
|
||||
if LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
XQUEUE_PORT = choice(PORTS)
|
||||
PORTS.remove(XQUEUE_PORT)
|
||||
else:
|
||||
XQUEUE_PORT = randint(1024, 65535)
|
||||
|
||||
XQUEUE_INTERFACE = {
|
||||
"url": "http://127.0.0.1:%d" % XQUEUE_PORT,
|
||||
"django_auth": {
|
||||
"username": "lms",
|
||||
"password": "***REMOVED***"
|
||||
},
|
||||
"basic_auth": ('anant', 'agarwal'),
|
||||
}
|
||||
|
||||
# Set up Video information so that the lms will send
|
||||
# requests to a mock Youtube server running locally
|
||||
if LETTUCE_SELENIUM_CLIENT == 'saucelabs':
|
||||
VIDEO_PORT = choice(PORTS)
|
||||
PORTS.remove(VIDEO_PORT)
|
||||
else:
|
||||
VIDEO_PORT = randint(1024, 65535)
|
||||
|
||||
@@ -51,7 +51,6 @@ SAUCE_INFO = ALL_CONFIG.get(os.environ.get('SAUCE_INFO', 'Linux-chrome--'))
|
||||
|
||||
# Information needed to utilize Sauce Labs.
|
||||
SAUCE = {
|
||||
'SAUCE_ENABLED': os.environ.get('SAUCE_ENABLED'),
|
||||
'USERNAME': os.environ.get('SAUCE_USER_NAME'),
|
||||
'ACCESS_ID': os.environ.get('SAUCE_API_KEY'),
|
||||
'PLATFORM': SAUCE_INFO[0],
|
||||
|
||||
Reference in New Issue
Block a user