Commit f1dd81a6 by JonahStanley

Refactored LMS so all potential stale element exceptions are avoided

parent 8b0e7c57
......@@ -10,6 +10,7 @@ from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from lettuce.django import django_url
from nose.tools import assert_true
@world.absorb
......@@ -142,14 +143,44 @@ def id_click(elem_id):
@world.absorb
def css_fill(css_selector, text):
assert is_css_present(css_selector), "{} is not present".format(css_selector)
world.browser.find_by_css(css_selector).first.fill(text)
def css_fill(css_selector, text, index=0, max_attempts=5):
assert is_css_present(css_selector)
attempt = 0
result = False
while attempt < max_attempts:
try:
world.browser.find_by_css(css_selector)[index].fill(text)
result = True
break
except WebDriverException:
# Occasionally, MathJax or other JavaScript can cover up
# an element temporarily.
# If this happens, wait a second, then try again
world.wait(1)
attempt += 1
except:
attempt += 1
assert_true(result, 'Filling {} did not work as expected'.format(css_selector))
@world.absorb
def click_link(partial_text):
world.browser.find_link_by_partial_text(partial_text).first.click()
def click_link(partial_text, index=0, max_attempts=5):
attempt = 0
result = False
while attempt < max_attempts:
try:
world.browser.find_link_by_partial_text(partial_text)[index].click()
result = True
break
except WebDriverException:
# Occasionally, MathJax or other JavaScript can cover up
# an element temporarily.
# If this happens, wait a second, then try again
world.wait(1)
attempt += 1
except:
attempt += 1
assert_true(result, 'Clicking {} did not work as expected'.format(partial_text))
@world.absorb
......@@ -168,6 +199,21 @@ def css_text(css_selector, index=0):
@world.absorb
def css_value(css_selector, index=0):
# Wait for the css selector to appear
if world.is_css_present(css_selector):
try:
return world.browser.find_by_css(css_selector)[index].value
except StaleElementReferenceException:
# The DOM was still redrawing. Wait a second and try again.
world.wait(1)
return world.browser.find_by_css(css_selector)[index].value
else:
return ""
@world.absorb
def css_html(css_selector, index=0, max_attempts=5):
"""
Returns the HTML of a css_selector and will retry if there is a StaleElementReferenceException
......@@ -179,26 +225,30 @@ def css_html(css_selector, index=0, max_attempts=5):
return world.browser.find_by_css(css_selector)[index].html
except:
attempt += 1
return ''
assert_true(attempt < max_attempts, 'Ran out of attempts to access {}'.format(css_selector))
@world.absorb
def css_has_class(css_selector, class_name, index=0, max_attempts=5):
attempt = 0
found = False
while attempt < max_attempts and not found:
while attempt < max_attempts:
try:
return world.css_find(css_selector)[index].has_class(class_name)
found = True
except:
attempt += 1
return False
assert_true(attempt < max_attempts, 'Ran out of attempts to access {}'.format(css_selector))
@world.absorb
def css_visible(css_selector):
assert is_css_present(css_selector), "{} is not present".format(css_selector)
return world.browser.find_by_css(css_selector).visible
def css_visible(css_selector, index=0, max_attempts=5):
assert is_css_present(css_selector)
attempt = 0
while attempt < max_attempts:
try:
return world.browser.find_by_css(css_selector)[index].visible
except:
attempt += 1
assert_true(attempt < max_attempts, 'Ran out of attempts to access {}'.format(css_selector))
@world.absorb
......
......@@ -3,6 +3,7 @@
from lettuce import step, world
from django.contrib.auth.models import User
from nose.tools import assert_true
@step('I am an unactivated user$')
......@@ -19,8 +20,15 @@ def i_am_an_activated_user(step):
def i_submit_my_credentials_on_the_login_form(step):
fill_in_the_login_form('email', 'robot@edx.org')
fill_in_the_login_form('password', 'test')
login_form = world.browser.find_by_css('form#login-form')
login_form.find_by_name('submit').click()
attempt = 0
while attempt < 5:
try:
login_form = world.browser.find_by_css('form#login-form')
login_form.find_by_name('submit').click()
break
except:
attempt += 1
assert_true(attempt < 5, 'Login form could not be clicked')
@step(u'I should see the login error message "([^"]*)"$')
......@@ -49,6 +57,13 @@ def user_is_an_activated_user(uname):
def fill_in_the_login_form(field, value):
login_form = world.browser.find_by_css('form#login-form')
form_field = login_form.find_by_name(field)
form_field.fill(value)
attempt = 0
while attempt < 5:
try:
login_form = world.browser.find_by_css('form#login-form')
form_field = login_form.find_by_name(field)
form_field.fill(value)
break
except:
attempt += 1
assert_true(attempt < 5, 'Login form could not be filled')
......@@ -121,7 +121,7 @@ def reset_problem(_step):
def press_the_button_with_label(_step, buttonname):
button_css = 'button span.show-label'
elem = world.css_find(button_css).first
assert_equal(elem.text, buttonname)
world.css_has_text(button_css, elem)
world.css_click(button_css)
......
......@@ -19,6 +19,7 @@ from capa.tests.response_xml_factory import OptionResponseXMLFactory, \
StringResponseXMLFactory, NumericalResponseXMLFactory, \
FormulaResponseXMLFactory, CustomResponseXMLFactory, \
CodeResponseXMLFactory
from nose.tools import assert_true
# Factories from capa.tests.response_xml_factory that we will use
......@@ -312,14 +313,20 @@ def assert_checked(problem_type, choices):
all_choices = ['choice_0', 'choice_1', 'choice_2', 'choice_3']
for this_choice in all_choices:
element = world.css_find(inputfield(problem_type, choice=this_choice))
if this_choice in choices:
assert element.checked
else:
assert not element.checked
attempt = 0
while attempt < 5:
try:
element = world.css_find(inputfield(problem_type, choice=this_choice))
if this_choice in choices:
assert element.checked
else:
assert not element.checked
break
except:
attempt += 1
assert_true(attempt < 5, "Could not access {}".format(element))
def assert_textfield(problem_type, expected_text, input_num=1):
element = world.css_find(inputfield(problem_type, input_num=input_num))
assert element.value == expected_text
element_value = world.css_value(inputfield(problem_type, input_num=input_num))
assert element_value == expected_text
......@@ -11,10 +11,7 @@ def i_register_for_the_course(_step, course):
cleaned_name = TEST_COURSE_NAME.replace(' ', '_')
url = django_url('courses/%s/%s/%s/about' % (TEST_COURSE_ORG, course, cleaned_name))
world.browser.visit(url)
intro_section = world.browser.find_by_css('section.intro')
register_link = intro_section.find_by_css('a.register')
register_link.click()
world.css_click('section.intro a.register')
assert world.is_css_present('section.container.dashboard')
......
......@@ -6,20 +6,38 @@ from lettuce import world, step
@step('I fill in "([^"]*)" on the registration form with "([^"]*)"$')
def when_i_fill_in_field_on_the_registration_form_with_value(step, field, value):
register_form = world.browser.find_by_css('form#register-form')
form_field = register_form.find_by_name(field)
form_field.fill(value)
attempt = 0
while attempt < 5:
try:
register_form = world.browser.find_by_css('form#register-form')
form_field = register_form.find_by_name(field)
form_field.fill(value)
break
except:
attempt += 1
@step('I submit the registration form$')
def i_press_the_button_on_the_registration_form(step):
register_form = world.browser.find_by_css('form#register-form')
register_form.find_by_name('submit').click()
attempt = 0
while attempt < 5:
try:
register_form = world.browser.find_by_css('form#register-form')
register_form.find_by_name('submit').click()
break
except:
attempt += 1
@step('I check the checkbox named "([^"]*)"$')
def i_check_checkbox(step, checkbox):
world.browser.find_by_name(checkbox).check()
attempt = 0
while attempt < 5:
try:
world.browser.find_by_name(checkbox).check()
break
except:
attempt += 1
@step('I should see "([^"]*)" in the dashboard banner$')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment