Merge pull request #678 from edx/zoldak/acceptance-sauce
Zoldak/acceptance sauce
This commit is contained in:
@@ -11,6 +11,10 @@ from logging import getLogger
|
||||
from django.core.management import call_command
|
||||
from django.conf import settings
|
||||
from selenium.common.exceptions import WebDriverException
|
||||
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||
from requests import put
|
||||
from base64 import encodestring
|
||||
from json import dumps
|
||||
|
||||
# Let the LMS and CMS do their one-time setup
|
||||
# For example, setting up mongo caches
|
||||
@@ -42,43 +46,93 @@ LOGGER.info("Loading the lettuce acceptance testing terrain file...")
|
||||
MAX_VALID_BROWSER_ATTEMPTS = 20
|
||||
|
||||
|
||||
def get_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):
|
||||
"""
|
||||
Sets the job status on sauce labs
|
||||
"""
|
||||
body_content = dumps({"passed": passed})
|
||||
config = get_username_and_key()
|
||||
base64string = encodestring('{}:{}'.format(config['username'], config['access-key']))[:-1]
|
||||
result = put('http://saucelabs.com/rest/v1/{}/jobs/{}'.format(config['username'], world.jobid),
|
||||
data=body_content,
|
||||
headers={"Authorization": "Basic {}".format(base64string)})
|
||||
return result.status_code == 200
|
||||
|
||||
|
||||
def make_desired_capabilities():
|
||||
"""
|
||||
Returns a DesiredCapabilities object corresponding to the environment sauce parameters
|
||||
"""
|
||||
desired_capabilities = settings.SAUCE.get('BROWSER', DesiredCapabilities.CHROME)
|
||||
desired_capabilities['platform'] = settings.SAUCE.get('PLATFORM')
|
||||
desired_capabilities['version'] = settings.SAUCE.get('VERSION')
|
||||
desired_capabilities['device-type'] = settings.SAUCE.get('DEVICE')
|
||||
desired_capabilities['name'] = settings.SAUCE.get('SESSION')
|
||||
desired_capabilities['build'] = settings.SAUCE.get('BUILD')
|
||||
desired_capabilities['video-upload-on-pass'] = False
|
||||
desired_capabilities['sauce-advisor'] = False
|
||||
desired_capabilities['record-screenshots'] = False
|
||||
desired_capabilities['selenium-version'] = "2.34.0"
|
||||
desired_capabilities['max-duration'] = 3600
|
||||
desired_capabilities['public'] = 'public restricted'
|
||||
return desired_capabilities
|
||||
|
||||
|
||||
@before.harvest
|
||||
def initial_setup(server):
|
||||
"""
|
||||
Launch the browser once before executing the tests.
|
||||
"""
|
||||
browser_driver = getattr(settings, 'LETTUCE_BROWSER', 'chrome')
|
||||
world.absorb(settings.SAUCE.get('SAUCE_ENABLED'), 'SAUCE_ENABLED')
|
||||
|
||||
# There is an issue with ChromeDriver2 r195627 on Ubuntu
|
||||
# in which we sometimes get an invalid browser session.
|
||||
# This is a work-around to ensure that we get a valid session.
|
||||
success = False
|
||||
num_attempts = 0
|
||||
while (not success) and num_attempts < MAX_VALID_BROWSER_ATTEMPTS:
|
||||
if not world.SAUCE_ENABLED:
|
||||
browser_driver = getattr(settings, 'LETTUCE_BROWSER', 'chrome')
|
||||
|
||||
# Get a browser session
|
||||
world.browser = Browser(browser_driver)
|
||||
# There is an issue with ChromeDriver2 r195627 on Ubuntu
|
||||
# in which we sometimes get an invalid browser session.
|
||||
# This is a work-around to ensure that we get a valid session.
|
||||
success = False
|
||||
num_attempts = 0
|
||||
while (not success) and num_attempts < MAX_VALID_BROWSER_ATTEMPTS:
|
||||
world.browser = Browser(browser_driver)
|
||||
|
||||
# Try to visit the main page
|
||||
# If the browser session is invalid, this will
|
||||
# raise a WebDriverException
|
||||
try:
|
||||
world.visit('/')
|
||||
# Try to visit the main page
|
||||
# If the browser session is invalid, this will
|
||||
# raise a WebDriverException
|
||||
try:
|
||||
world.visit('/')
|
||||
|
||||
except WebDriverException:
|
||||
world.browser.quit()
|
||||
num_attempts += 1
|
||||
except WebDriverException:
|
||||
world.browser.quit()
|
||||
num_attempts += 1
|
||||
|
||||
else:
|
||||
success = True
|
||||
else:
|
||||
success = True
|
||||
|
||||
# If we were unable to get a valid session within the limit of attempts,
|
||||
# then we cannot run the tests.
|
||||
if not success:
|
||||
raise IOError("Could not acquire valid {driver} browser session.".format(driver=browser_driver))
|
||||
# If we were unable to get a valid session within the limit of attempts,
|
||||
# then we cannot run the tests.
|
||||
if not success:
|
||||
raise IOError("Could not acquire valid {driver} browser session.".format(driver=browser_driver))
|
||||
|
||||
# Set the browser size to 1280x1024
|
||||
world.browser.driver.set_window_size(1280, 1024)
|
||||
world.browser.driver.set_window_size(1280, 1024)
|
||||
|
||||
else:
|
||||
config = get_username_and_key()
|
||||
world.browser = Browser(
|
||||
'remote',
|
||||
url="http://{}:{}@ondemand.saucelabs.com:80/wd/hub".format(config['username'], config['access-key']),
|
||||
**make_desired_capabilities()
|
||||
)
|
||||
world.browser.driver.implicitly_wait(30)
|
||||
|
||||
world.absorb(world.browser.driver.session_id, 'jobid')
|
||||
|
||||
|
||||
@before.each_scenario
|
||||
@@ -97,7 +151,6 @@ def clear_data(scenario):
|
||||
world.spew('scenario_dict')
|
||||
|
||||
|
||||
|
||||
@after.each_scenario
|
||||
def reset_databases(scenario):
|
||||
'''
|
||||
@@ -128,4 +181,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)
|
||||
world.browser.quit()
|
||||
|
||||
@@ -99,7 +99,7 @@ def i_am_logged_in_user(step):
|
||||
|
||||
@step('I am not logged in$')
|
||||
def i_am_not_logged_in(step):
|
||||
world.browser.cookies.delete()
|
||||
world.visit('logout')
|
||||
|
||||
|
||||
@step('I am staff for course "([^"]*)"$')
|
||||
@@ -138,10 +138,13 @@ 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:
|
||||
multiplier = 2
|
||||
if doesnt_appear:
|
||||
assert world.browser.is_text_not_present(text, wait_time=5)
|
||||
assert world.browser.is_text_not_present(text, wait_time=5*multiplier)
|
||||
else:
|
||||
assert world.browser.is_text_present(text, wait_time=5)
|
||||
assert world.browser.is_text_present(text, wait_time=5*multiplier)
|
||||
|
||||
|
||||
@step('I am logged in$')
|
||||
@@ -150,7 +153,7 @@ def i_am_logged_in(step):
|
||||
world.log_in(username='robot', password='test')
|
||||
world.browser.visit(django_url('/'))
|
||||
# You should not see the login link
|
||||
assert_equals(world.browser.find_by_css('a#login'), [])
|
||||
assert world.is_css_not_present('a#login')
|
||||
|
||||
|
||||
@step(u'I am an edX user$')
|
||||
|
||||
Reference in New Issue
Block a user