178 lines
6.6 KiB
Python
178 lines
6.6 KiB
Python
#pylint: disable=C0111
|
|
#pylint: disable=W0621
|
|
|
|
from lettuce import world, step
|
|
from nose.tools import assert_true, assert_in, assert_equal # pylint: disable=E0611
|
|
from common import create_studio_user, add_course_author, log_into_studio
|
|
|
|
|
|
@step(u'I am in Studio editing a new unit$')
|
|
def add_unit(step):
|
|
world.clear_courses()
|
|
course = world.CourseFactory.create()
|
|
section = world.ItemFactory.create(parent_location=course.location)
|
|
world.ItemFactory.create(
|
|
parent_location=section.location,
|
|
category='sequential',
|
|
display_name='Subsection One',)
|
|
user = create_studio_user(is_staff=False)
|
|
add_course_author(user, course)
|
|
log_into_studio()
|
|
world.wait_for_requirejs([
|
|
"jquery", "gettext", "js/models/course", "coffee/src/models/module",
|
|
"coffee/src/views/unit", "jquery.ui",
|
|
])
|
|
world.wait_for_mathjax()
|
|
css_selectors = [
|
|
'a.course-link', 'div.section-item a.expand-collapse-icon',
|
|
'a.new-unit-item',
|
|
]
|
|
for selector in css_selectors:
|
|
world.css_click(selector)
|
|
|
|
|
|
@step(u'I add this type of single step component:$')
|
|
def add_a_single_step_component(step):
|
|
world.wait_for_xmodule()
|
|
for step_hash in step.hashes:
|
|
component = step_hash['Component']
|
|
assert_in(component, ['Discussion', 'Video'])
|
|
css_selector = 'a[data-type="{}"]'.format(component.lower())
|
|
world.css_click(css_selector)
|
|
|
|
# In the current implementation, all the "new component"
|
|
# buttons are handled by one BackBone.js view.
|
|
# If we click two buttons at super-human speed,
|
|
# the view will miss the second click while it's
|
|
# processing the first.
|
|
# To account for this, we wait for each component
|
|
# to be created before clicking the next component.
|
|
world.wait_for_visible('section.xmodule_{}Module'.format(component))
|
|
|
|
|
|
@step(u'I see this type of single step component:$')
|
|
def see_a_single_step_component(step):
|
|
for step_hash in step.hashes:
|
|
component = step_hash['Component']
|
|
assert_in(component, ['Discussion', 'Video'])
|
|
component_css = 'section.xmodule_{}Module'.format(component)
|
|
assert_true(world.is_css_present(component_css),
|
|
"{} couldn't be found".format(component))
|
|
|
|
|
|
@step(u'I add this type of( Advanced)? (HTML|Problem) component:$')
|
|
def add_a_multi_step_component(step, is_advanced, category):
|
|
def click_advanced():
|
|
css = 'ul.problem-type-tabs a[href="#tab2"]'
|
|
world.css_click(css)
|
|
my_css = 'ul.problem-type-tabs li.ui-state-active a[href="#tab2"]'
|
|
assert(world.css_find(my_css))
|
|
|
|
def find_matching_link():
|
|
"""
|
|
Find the link with the specified text. There should be one and only one.
|
|
"""
|
|
# The tab shows links for the given category
|
|
links = world.css_find('div.new-component-{} a'.format(category))
|
|
|
|
# Find the link whose text matches what you're looking for
|
|
matched_links = [link for link in links if link.text == step_hash['Component']]
|
|
|
|
# There should be one and only one
|
|
assert_equal(len(matched_links), 1)
|
|
return matched_links[0]
|
|
|
|
def click_link():
|
|
link.click()
|
|
|
|
world.wait_for_xmodule()
|
|
category = category.lower()
|
|
for step_hash in step.hashes:
|
|
css_selector = 'a[data-type="{}"]'.format(category)
|
|
world.css_click(css_selector)
|
|
world.wait_for_invisible(css_selector)
|
|
|
|
if is_advanced:
|
|
# Sometimes this click does not work if you go too fast.
|
|
world.retry_on_exception(click_advanced, max_attempts=5, ignored_exceptions=AssertionError)
|
|
|
|
# Retry this in case the list is empty because you tried too fast.
|
|
link = world.retry_on_exception(func=find_matching_link, ignored_exceptions=AssertionError)
|
|
|
|
# Wait for the link to be clickable. If you go too fast it is not.
|
|
world.retry_on_exception(click_link)
|
|
|
|
|
|
@step(u'I see (HTML|Problem) components in this order:')
|
|
def see_a_multi_step_component(step, category):
|
|
|
|
# Wait for all components to finish rendering
|
|
selector = 'li.component section.xmodule_display'
|
|
world.wait_for(lambda _: len(world.css_find(selector)) == len(step.hashes))
|
|
|
|
for idx, step_hash in enumerate(step.hashes):
|
|
|
|
if category == 'HTML':
|
|
html_matcher = {
|
|
'Text':
|
|
'\n \n',
|
|
'Announcement':
|
|
'<p> Words of encouragement! This is a short note that most students will read. </p>',
|
|
'E-text Written in LaTeX':
|
|
'<h2>Example: E-text page</h2>',
|
|
}
|
|
actual_html = world.css_html(selector, index=idx)
|
|
assert_in(html_matcher[step_hash['Component']], actual_html)
|
|
else:
|
|
actual_text = world.css_text(selector, index=idx)
|
|
assert_in(step_hash['Component'].upper(), actual_text)
|
|
|
|
|
|
@step(u'I add a "([^"]*)" "([^"]*)" component$')
|
|
def add_component_category(step, component, category):
|
|
assert category in ('single step', 'HTML', 'Problem', 'Advanced Problem')
|
|
given_string = 'I add this type of {} component:'.format(category)
|
|
step.given('{}\n{}\n{}'.format(given_string, '|Component|', '|{}|'.format(component)))
|
|
|
|
|
|
@step(u'I delete all components$')
|
|
def delete_all_components(step):
|
|
world.wait_for_xmodule()
|
|
delete_btn_css = 'a.delete-button'
|
|
prompt_css = 'div#prompt-warning'
|
|
btn_css = '{} a.button.action-primary'.format(prompt_css)
|
|
saving_mini_css = 'div#page-notification .wrapper-notification-mini'
|
|
count = len(world.css_find('ol.components li.component'))
|
|
for _ in range(int(count)):
|
|
world.css_click(delete_btn_css)
|
|
assert_true(
|
|
world.is_css_present('{}.is-shown'.format(prompt_css)),
|
|
msg='Waiting for the confirmation prompt to be shown')
|
|
|
|
# Pressing the button via css was not working reliably for the last component
|
|
# when run in Chrome.
|
|
if world.browser.driver_name is 'Chrome':
|
|
world.browser.execute_script("$('{}').click()".format(btn_css))
|
|
else:
|
|
world.css_click(btn_css)
|
|
|
|
# Wait for the saving notification to pop up then disappear
|
|
if world.is_css_present('{}.is-shown'.format(saving_mini_css)):
|
|
world.css_find('{}.is-hiding'.format(saving_mini_css))
|
|
|
|
|
|
@step(u'I see no components')
|
|
def see_no_components(steps):
|
|
assert world.is_css_not_present('li.component')
|
|
|
|
|
|
@step(u'I delete a component')
|
|
def delete_one_component(step):
|
|
world.css_click('a.delete-button')
|
|
|
|
|
|
@step(u'I edit and save a component')
|
|
def edit_and_save_component(step):
|
|
world.css_click('.edit-button')
|
|
world.css_click('.save-button')
|