Merge pull request #18739 from edx/jmbowman/TE-2525

TE-2525 Finish removing nose.tools usage
This commit is contained in:
Jeremy Bowman
2018-08-09 15:56:28 -04:00
committed by GitHub
17 changed files with 178 additions and 122 deletions

View File

@@ -1,4 +1,5 @@
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
import os
@@ -6,9 +7,9 @@ from logging import getLogger
from django.conf import settings
from lettuce import step, world
from nose.tools import assert_in, assert_true
from selenium.webdriver.common.keys import Keys
from openedx.core.lib.tests.tools import assert_in # pylint: disable=no-name-in-module
from student import auth
from student.models import get_user
from student.roles import CourseInstructorRole, CourseStaffRole, GlobalStaff
@@ -78,7 +79,7 @@ def i_have_populated_a_new_course(_step):
@step('(I select|s?he selects) the new course')
def select_new_course(_step, whom):
def select_new_course(_step, _whom):
course_link_css = 'a.course-link'
world.css_click(course_link_css)
@@ -103,7 +104,7 @@ def i_change_field_to_value(_step, field, value):
field_css = '#%s' % '-'.join([s.lower() for s in field.split()])
ele = world.css_find(field_css).first
ele.fill(value)
ele._element.send_keys(Keys.ENTER)
ele._element.send_keys(Keys.ENTER) # pylint: disable=protected-access
@step('I reset the database')
@@ -121,7 +122,7 @@ def reset_the_db(_step):
@step('I see a confirmation that my changes have been saved')
def i_see_a_confirmation(step):
def i_see_a_confirmation(_step):
confirmation_css = '#alert-confirmation'
assert world.is_css_present(confirmation_css)
@@ -199,12 +200,12 @@ def create_a_course():
course_link_css = 'a.course-link'
world.css_click(course_link_css)
course_title_css = 'span.course-title'
assert_true(world.is_css_present(course_title_css))
assert world.is_css_present(course_title_css)
def add_section():
world.css_click('.outline .button-new')
assert_true(world.is_css_present('.outline-section .xblock-field-value'))
assert world.is_css_present('.outline-section .xblock-field-value')
def set_date_and_time(date_css, desired_date, time_css, desired_time, key=None):
@@ -268,14 +269,14 @@ def edit_new_unit(step):
@step('the save notification button is disabled')
def save_button_disabled(step):
def save_button_disabled(_step):
button_css = '.action-save'
disabled = 'is-disabled'
assert world.css_has_class(button_css, disabled)
@step('the "([^"]*)" button is disabled')
def button_disabled(step, value):
def button_disabled(_step, value):
button_css = 'input[value="%s"]' % value
assert world.css_has_class(button_css, 'is-disabled')
@@ -312,12 +313,12 @@ def confirm_studio_prompt():
@step('I confirm the prompt')
def confirm_the_prompt(step):
def confirm_the_prompt(_step):
confirm_studio_prompt()
@step(u'I am shown a prompt$')
def i_am_shown_a_notification(step):
def i_am_shown_a_notification(_step):
assert world.is_css_present('.wrapper-prompt')
@@ -342,7 +343,7 @@ def get_codemirror_value(index=0, find_prefix="$"):
def attach_file(filename, sub_path):
path = os.path.join(TEST_ROOT, sub_path, filename)
world.browser.execute_script("$('input.file-input').css('display', 'block')")
assert_true(os.path.exists(path))
assert os.path.exists(path)
world.browser.attach_file('file', os.path.abspath(path))
@@ -377,7 +378,7 @@ def other_user_login(step, name):
login_form.find_by_name('password').fill("test")
login_form.find_by_name('submit').click()
world.retry_on_exception(fill_login_form)
assert_true(world.is_css_present('.new-course-button'))
assert world.is_css_present('.new-course-button')
world.scenario_dict['USER'] = get_user(name + '@edx.org')

View File

@@ -1,4 +1,5 @@
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
# Lettuce formats proposed definitions for unimplemented steps with the
@@ -6,7 +7,7 @@
# pylint: disable=unused-argument
from lettuce import step, world
from nose.tools import assert_equal, assert_in, assert_true
from openedx.core.lib.tests.tools import assert_equal, assert_in, assert_true # pylint: disable=no-name-in-module
DISPLAY_NAME = "Display Name"
@@ -110,7 +111,7 @@ def delete_components(step, number):
# Pressing the button via css was not working reliably for the last component
# when run in Chrome.
if world.browser.driver_name is 'Chrome':
if world.browser.driver_name == 'Chrome':
world.browser.execute_script("$('{}').click()".format(btn_css))
else:
world.css_click(btn_css)

View File

@@ -1,11 +1,12 @@
# disable missing docstring
# pylint: disable=missing-docstring
# pylint: disable=no-member
from lettuce import world
from nose.tools import assert_equal, assert_in
from selenium.webdriver.common.keys import Keys
from common import type_in_codemirror
from openedx.core.lib.tests.tools import assert_equal, assert_in # pylint: disable=no-name-in-module
from terrain.steps import reload_the_page
@@ -121,7 +122,7 @@ def edit_component_and_select_settings():
def ensure_settings_visible():
# Select the 'settings' tab if there is one (it isn't displayed if it is the only option)
settings_button = world.browser.find_by_css('.settings-button')
if len(settings_button) > 0:
if settings_button:
world.css_click('.settings-button')
@@ -146,7 +147,7 @@ def select_editor_tab(tab_name):
world.wait_for_ajax_complete()
def enter_xml_in_advanced_problem(step, text):
def enter_xml_in_advanced_problem(_step, text):
"""
Edits an advanced problem (assumes only on page),
types the provided XML, and saves the component.

View File

@@ -1,9 +1,9 @@
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
from django.conf import settings
from lettuce import step, world
from nose.tools import assert_false, assert_true
from selenium.webdriver.common.keys import Keys
from cms.djangoapps.contentstore.features.common import type_in_codemirror
@@ -26,7 +26,7 @@ DEFAULT_TIME = "00:00"
############### ACTIONS ####################
@step('I select Schedule and Details$')
def test_i_select_schedule_and_details(step):
def test_i_select_schedule_and_details(_step):
world.click_course_settings()
link_css = 'li.nav-course-settings-schedule a'
world.css_click(link_css)
@@ -43,7 +43,7 @@ def test_i_have_set_course_dates(step):
@step('And I set course dates$')
def test_and_i_set_course_dates(step):
def test_and_i_set_course_dates(_step):
set_date_or_time(COURSE_START_DATE_CSS, '12/20/2013')
set_date_or_time(COURSE_END_DATE_CSS, '12/26/2013')
set_date_or_time(ENROLLMENT_START_DATE_CSS, '12/1/2013')
@@ -54,14 +54,14 @@ def test_and_i_set_course_dates(step):
@step('And I clear all the dates except start$')
def test_and_i_clear_all_the_dates_except_start(step):
def test_and_i_clear_all_the_dates_except_start(_step):
set_date_or_time(COURSE_END_DATE_CSS, '')
set_date_or_time(ENROLLMENT_START_DATE_CSS, '')
set_date_or_time(ENROLLMENT_END_DATE_CSS, '')
@step('Then I see cleared dates$')
def test_then_i_see_cleared_dates(step):
def test_then_i_see_cleared_dates(_step):
verify_date_or_time(COURSE_END_DATE_CSS, '')
verify_date_or_time(ENROLLMENT_START_DATE_CSS, '')
verify_date_or_time(ENROLLMENT_END_DATE_CSS, '')
@@ -76,19 +76,19 @@ def test_then_i_see_cleared_dates(step):
@step('I clear the course start date$')
def test_i_clear_the_course_start_date(step):
def test_i_clear_the_course_start_date(_step):
set_date_or_time(COURSE_START_DATE_CSS, '')
@step('I receive a warning about course start date$')
def test_i_receive_a_warning_about_course_start_date(step):
assert_true(world.css_has_text('.message-error', 'The course must have an assigned start date.'))
assert_true('error' in world.css_find(COURSE_START_DATE_CSS).first._element.get_attribute('class'))
assert_true('error' in world.css_find(COURSE_START_TIME_CSS).first._element.get_attribute('class'))
def test_i_receive_a_warning_about_course_start_date(_step):
assert world.css_has_text('.message-error', 'The course must have an assigned start date.')
assert 'error' in world.css_find(COURSE_START_DATE_CSS).first._element.get_attribute('class') # pylint: disable=protected-access
assert 'error' in world.css_find(COURSE_START_TIME_CSS).first._element.get_attribute('class') # pylint: disable=protected-access
@step('the previously set start date is shown$')
def test_the_previously_set_start_date_is_shown(step):
def test_the_previously_set_start_date_is_shown(_step):
verify_date_or_time(COURSE_START_DATE_CSS, '12/20/2013')
verify_date_or_time(COURSE_START_TIME_CSS, DUMMY_TIME)
@@ -101,26 +101,26 @@ def test_i_have_tried_to_clear_the_course_start(step):
@step('I have entered a new course start date$')
def test_i_have_entered_a_new_course_start_date(step):
def test_i_have_entered_a_new_course_start_date(_step):
set_date_or_time(COURSE_START_DATE_CSS, '12/22/2013')
@step('The warning about course start date goes away$')
def test_the_warning_about_course_start_date_goes_away(step):
def test_the_warning_about_course_start_date_goes_away(_step):
assert world.is_css_not_present('.message-error')
assert_false('error' in world.css_find(COURSE_START_DATE_CSS).first._element.get_attribute('class'))
assert_false('error' in world.css_find(COURSE_START_TIME_CSS).first._element.get_attribute('class'))
assert 'error' not in world.css_find(COURSE_START_DATE_CSS).first._element.get_attribute('class') # pylint: disable=protected-access
assert 'error' not in world.css_find(COURSE_START_TIME_CSS).first._element.get_attribute('class') # pylint: disable=protected-access
@step('my new course start date is shown$')
def new_course_start_date_is_shown(step):
def new_course_start_date_is_shown(_step):
verify_date_or_time(COURSE_START_DATE_CSS, '12/22/2013')
# Time should have stayed from before attempt to clear date.
verify_date_or_time(COURSE_START_TIME_CSS, DUMMY_TIME)
@step('I change fields$')
def test_i_change_fields(step):
def test_i_change_fields(_step):
set_date_or_time(COURSE_START_DATE_CSS, '7/7/7777')
set_date_or_time(COURSE_END_DATE_CSS, '7/7/7777')
set_date_or_time(ENROLLMENT_START_DATE_CSS, '7/7/7777')
@@ -140,7 +140,7 @@ def set_date_or_time(css, date_or_time):
world.css_fill(css, date_or_time)
e = world.css_find(css).first
# hit Enter to apply the changes
e._element.send_keys(Keys.ENTER)
e._element.send_keys(Keys.ENTER) # pylint: disable=protected-access
def verify_date_or_time(css, date_or_time):
@@ -149,7 +149,7 @@ def verify_date_or_time(css, date_or_time):
"""
# We need to wait for JavaScript to fill in the field, so we use
# css_has_value(), which first checks that the field is not blank
assert_true(world.css_has_value(css, date_or_time))
assert world.css_has_value(css, date_or_time)
@step('I do not see the changes')

View File

@@ -1,31 +1,32 @@
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
from lettuce import step, world
from nose.tools import assert_equal, assert_in, assert_not_equal
from selenium.common.exceptions import InvalidElementStateException
from common import *
from contentstore.utils import reverse_course_url
from openedx.core.lib.tests.tools import assert_equal, assert_in, assert_not_equal # pylint: disable=no-name-in-module
from terrain.steps import reload_the_page
@step(u'I am viewing the grading settings')
def view_grading_settings(step):
def view_grading_settings(_step):
world.click_course_settings()
link_css = 'li.nav-course-settings-grading a'
world.css_click(link_css)
@step(u'I add "([^"]*)" new grade')
def add_grade(step, many):
def add_grade(_step, many):
grade_css = '.new-grade-button'
for __ in range(int(many)):
world.css_click(grade_css)
@step(u'I delete a grade')
def delete_grade(step):
def delete_grade(_step):
#grade_css = 'li.grade-specific-bar > a.remove-button'
#range_css = '.grade-specific-bar'
#world.css_find(range_css)[1].mouseover()
@@ -34,21 +35,21 @@ def delete_grade(step):
@step(u'I see I now have "([^"]*)" grades$')
def view_grade_slider(step, how_many):
def view_grade_slider(_step, how_many):
grade_slider_css = '.grade-specific-bar'
all_grades = world.css_find(grade_slider_css)
assert_equal(len(all_grades), int(how_many))
@step(u'I move a grading section')
def move_grade_slider(step):
def move_grade_slider(_step):
moveable_css = '.ui-resizable-e'
f = world.css_find(moveable_css).first
f.action_chains.drag_and_drop_by_offset(f._element, 100, 0).perform()
f.action_chains.drag_and_drop_by_offset(f._element, 100, 0).perform() # pylint: disable=protected-access
@step(u'I see that the grade range has changed')
def confirm_change(step):
def confirm_change(_step):
range_css = '.range'
all_ranges = world.css_find(range_css)
for i in range(len(all_ranges)):
@@ -56,18 +57,18 @@ def confirm_change(step):
@step(u'I change assignment type "([^"]*)" to "([^"]*)"$')
def change_assignment_name(step, old_name, new_name):
def change_assignment_name(_step, old_name, new_name):
name_id = '#course-grading-assignment-name'
index = get_type_index(old_name)
f = world.css_find(name_id)[index]
assert_not_equal(index, -1)
for __ in xrange(len(old_name)):
f._element.send_keys(Keys.END, Keys.BACK_SPACE)
f._element.send_keys(new_name)
f._element.send_keys(Keys.END, Keys.BACK_SPACE) # pylint: disable=protected-access
f._element.send_keys(new_name) # pylint: disable=protected-access
@step(u'I go back to the main course page')
def main_course_page(step):
def main_course_page(_step):
main_page_link = reverse_course_url('course_handler', world.scenario_dict['COURSE'].id)
world.visit(main_page_link)
@@ -75,7 +76,7 @@ def main_course_page(step):
@step(u'I do( not)? see the assignment name "([^"]*)"$')
def see_assignment_name(step, do_not, name):
def see_assignment_name(_step, _do_not, _name):
# TODO: rewrite this once grading has been added back to the course outline
pass
# assignment_menu_css = 'ul.menu > li > a'
@@ -94,32 +95,32 @@ def see_assignment_name(step, do_not, name):
@step(u'I delete the assignment type "([^"]*)"$')
def delete_assignment_type(step, to_delete):
def delete_assignment_type(_step, to_delete):
delete_css = '.remove-grading-data'
world.css_click(delete_css, index=get_type_index(to_delete))
@step(u'I add a new assignment type "([^"]*)"$')
def add_assignment_type(step, new_name):
def add_assignment_type(_step, new_name):
add_button_css = '.add-grading-data'
world.css_click(add_button_css)
name_id = '#course-grading-assignment-name'
new_assignment = world.css_find(name_id)[-1]
new_assignment._element.send_keys(new_name)
new_assignment._element.send_keys(new_name) # pylint: disable=protected-access
@step(u'I set the assignment weight to "([^"]*)"$')
def set_weight(step, weight):
def set_weight(_step, weight):
weight_id = '#course-grading-assignment-gradeweight'
weight_field = world.css_find(weight_id)[-1]
old_weight = world.css_value(weight_id, -1)
for __ in range(len(old_weight)):
weight_field._element.send_keys(Keys.END, Keys.BACK_SPACE)
weight_field._element.send_keys(weight)
weight_field._element.send_keys(Keys.END, Keys.BACK_SPACE) # pylint: disable=protected-access
weight_field._element.send_keys(weight) # pylint: disable=protected-access
@step(u'the assignment weight is displayed as "([^"]*)"$')
def verify_weight(step, weight):
def verify_weight(_step, weight):
weight_id = '#course-grading-assignment-gradeweight'
assert_equal(world.css_value(weight_id, -1), weight)
@@ -182,7 +183,7 @@ def i_change_grace_period(_step, grace_period):
# this to happen, then we can end up with
# an invalid value (e.g. "00:0048:00")
# which prevents us from saving.
assert_true(world.css_has_value(grace_period_css, "00:00"))
assert world.css_has_value(grace_period_css, "00:00")
# Set the new grace period
ele.value = grace_period

View File

@@ -1,12 +1,13 @@
# disable missing docstring
# pylint: disable=missing-docstring
# pylint: disable=no-member
from collections import OrderedDict
from lettuce import step, world
from nose.tools import assert_equal, assert_false, assert_in, assert_true
from common import get_codemirror_value, type_in_codemirror
from openedx.core.lib.tests.tools import assert_equal, assert_in # pylint: disable=no-name-in-module
CODEMIRROR_SELECTOR_PREFIX = "$('iframe').contents().find"
@@ -32,7 +33,7 @@ def i_created_raw_html(step):
@step('I see the HTML component settings$')
def i_see_only_the_html_display_name(step):
def i_see_only_the_html_display_name(_step):
world.verify_all_setting_entries(
[
['Display Name', "Text", False],
@@ -53,12 +54,12 @@ def i_created_etext_in_latex(step):
@step('I edit the page$')
def i_click_on_edit_icon(step):
def i_click_on_edit_icon(_step):
world.edit_component()
@step('I add an image with static link "(.*)" via the Image Plugin Icon$')
def i_click_on_image_plugin_icon(step, path):
def i_click_on_image_plugin_icon(_step, path):
use_plugin(
'.mce-i-image',
lambda: world.css_fill('.mce-textbox', path, 0)
@@ -66,7 +67,7 @@ def i_click_on_image_plugin_icon(step, path):
@step('the link is shown as "(.*)" in the Image Plugin$')
def check_link_in_image_plugin(step, path):
def check_link_in_image_plugin(_step, path):
use_plugin(
'.mce-i-image',
lambda: assert_equal(path, world.css_find('.mce-textbox')[0].value)
@@ -74,7 +75,7 @@ def check_link_in_image_plugin(step, path):
@step('I add a link with static link "(.*)" via the Link Plugin Icon$')
def i_click_on_link_plugin_icon(step, path):
def i_click_on_link_plugin_icon(_step, path):
def fill_in_link_fields():
world.css_fill('.mce-textbox', path, 0)
world.css_fill('.mce-textbox', 'picture', 1)
@@ -83,7 +84,7 @@ def i_click_on_link_plugin_icon(step, path):
@step('the link is shown as "(.*)" in the Link Plugin$')
def check_link_in_link_plugin(step, path):
def check_link_in_link_plugin(_step, path):
# Ensure caret position is within the link just created.
script = """
var editor = tinyMCE.activeEditor;
@@ -98,25 +99,25 @@ def check_link_in_link_plugin(step, path):
@step('type "(.*)" in the code editor and press OK$')
def type_in_codemirror_plugin(step, text):
def type_in_codemirror_plugin(_step, text):
# Verify that raw code editor is not visible.
assert_true(world.css_has_class('.CodeMirror', 'is-inactive'))
assert world.css_has_class('.CodeMirror', 'is-inactive')
# Verify that TinyMCE editor is present
assert_true(world.is_css_present('.tiny-mce'))
assert world.is_css_present('.tiny-mce')
use_code_editor(
lambda: type_in_codemirror(0, text, CODEMIRROR_SELECTOR_PREFIX)
)
@step('and the code editor displays "(.*)"$')
def verify_code_editor_text(step, text):
def verify_code_editor_text(_step, text):
use_code_editor(
lambda: assert_equal(text, get_codemirror_value(0, CODEMIRROR_SELECTOR_PREFIX))
)
@step('I save the page$')
def i_click_on_save(step):
def i_click_on_save(_step):
world.save_component()
@@ -131,7 +132,7 @@ def check_raw_editor_text(step):
@step('the src link is rewritten to the asset link "(.*)"$')
def image_static_link_is_rewritten(step, path):
def image_static_link_is_rewritten(_step, path):
# Find the TinyMCE iframe within the main window
with world.browser.get_iframe('mce_0_ifr') as tinymce:
image = tinymce.find_by_tag('img').first
@@ -139,7 +140,7 @@ def image_static_link_is_rewritten(step, path):
@step('the href link is rewritten to the asset link "(.*)"$')
def link_static_link_is_rewritten(step, path):
def link_static_link_is_rewritten(_step, path):
# Find the TinyMCE iframe within the main window
with world.browser.get_iframe('mce_0_ifr') as tinymce:
link = tinymce.find_by_tag('a').first
@@ -147,7 +148,7 @@ def link_static_link_is_rewritten(step, path):
@step('the expected toolbar buttons are displayed$')
def check_toolbar_buttons(step):
def check_toolbar_buttons(_step):
dropdowns = world.css_find('.mce-listbox')
assert_equal(2, len(dropdowns))
@@ -184,12 +185,12 @@ def check_toolbar_buttons(step):
assert_equal(len(expected_buttons), len(buttons))
for index, button in enumerate(expected_buttons):
class_names = buttons[index]._element.get_attribute('class')
class_names = buttons[index]._element.get_attribute('class') # pylint: disable=protected-access
assert_equal("mce-ico mce-i-" + button, class_names)
@step('I set the text to "(.*)" and I select the text$')
def set_text_and_select(step, text):
def set_text_and_select(_step, text):
script = """
var editor = tinyMCE.activeEditor;
editor.setContent(arguments[0]);
@@ -199,35 +200,35 @@ def set_text_and_select(step, text):
@step('I select the code toolbar button$')
def select_code_button(step):
def select_code_button(_step):
# This is our custom "code style" button. It uses an image instead of a class.
world.css_click(".mce-i-none")
@step('type "(.*)" into the Raw Editor$')
def type_in_raw_editor(step, text):
def type_in_raw_editor(_step, text):
# Verify that CodeMirror editor is not hidden
assert_false(world.css_has_class('.CodeMirror', 'is-inactive'))
assert not world.css_has_class('.CodeMirror', 'is-inactive')
# Verify that TinyMCE Editor is not present
assert_true(world.is_css_not_present('.tiny-mce'))
assert world.is_css_not_present('.tiny-mce')
type_in_codemirror(0, text)
@step('I edit the component and select the (Raw|Visual) Editor$')
def select_editor(step, editor):
def select_editor(_step, editor):
world.edit_component_and_select_settings()
world.browser.select('Editor', editor)
@step('I click font selection dropdown')
def click_font_dropdown(step):
def click_font_dropdown(_step):
dropdowns = [drop for drop in world.css_find('.mce-listbox') if drop.text == 'Font Family']
assert_equal(len(dropdowns), 1)
dropdowns[0].click()
@step('I should see a list of available fonts')
def font_selector_dropdown_is_shown(step):
def font_selector_dropdown_is_shown(_step):
font_panel = get_fonts_list_panel(world)
expected_fonts = list(CUSTOM_FONTS.keys()) + list(TINYMCE_FONTS.keys())
actual_fonts = [font.strip() for font in font_panel.text.split('\n')]
@@ -244,7 +245,7 @@ def default_options_sets_expected_font_family(step): # pylint: disable=unused-a
@step('all standard tinyMCE fonts should be available')
def check_standard_tinyMCE_fonts(step):
def check_standard_tinyMCE_fonts(_step):
fonts = get_available_fonts(get_fonts_list_panel(world))
for label, expected_fonts in TINYMCE_FONTS.items():
for expected_font in expected_fonts:
@@ -318,4 +319,4 @@ def get_font_family(font_span):
# get_attribute('style').replace('font-family: ', '').replace(';', '') is equivalent to
# value_of_css_property('font-family'). However, for reason unknown value_of_css_property fails tests in CI
# while works as expected in local development environment
return font_span._element.get_attribute('style').replace('font-family: ', '').replace(';', '')
return font_span._element.get_attribute('style').replace('font-family: ', '').replace(';', '') # pylint: disable=protected-access

View File

@@ -4,7 +4,7 @@
# pylint: disable=no-member
from lettuce import step, world
from nose.tools import assert_equal, assert_in
from openedx.core.lib.tests.tools import assert_equal, assert_in # pylint: disable=no-name-in-module
CSS_FOR_TAB_ELEMENT = "li[data-tab-id='{0}'] input.toggle-checkbox"

View File

@@ -1,14 +1,15 @@
# disable missing docstring
# pylint: disable=missing-docstring
# pylint: disable=no-member
import json
from lettuce import step, world
from nose.tools import assert_equal, assert_true
from openedx.core.lib.tests.tools import assert_equal, assert_true # pylint: disable=no-name-in-module
from advanced_settings import ADVANCED_MODULES_KEY, change_value
from common import open_new_course, type_in_codemirror
from course_import import import_file
from cms.djangoapps.contentstore.features.advanced_settings import ADVANCED_MODULES_KEY, change_value
from cms.djangoapps.contentstore.features.common import open_new_course, type_in_codemirror
from cms.djangoapps.contentstore.features.course_import import import_file
DISPLAY_NAME = "Display Name"
MAXIMUM_ATTEMPTS = "Maximum Attempts"
@@ -57,7 +58,7 @@ def i_create_new_common_problem(step):
@step('when I mouseover on "(.*)"')
def i_mouseover_on_html_component(step, element_class):
def i_mouseover_on_html_component(_step, element_class):
action_css = '.{}'.format(element_class)
world.trigger_event(action_css, event='mouseover')
@@ -96,7 +97,7 @@ def i_edit_and_select_settings(_step):
@step('I see the advanced settings and their expected values$')
def i_see_advanced_settings_with_values(step):
def i_see_advanced_settings_with_values(_step):
world.verify_all_setting_entries(
[
[DISPLAY_NAME, "Blank Common Problem", True],
@@ -126,7 +127,7 @@ def my_display_name_change_is_persisted_on_save(step):
@step('the problem display name is "(.*)"$')
def verify_problem_display_name(step, name):
def verify_problem_display_name(_step, name):
"""
name is uppercased because the heading styles are uppercase in css
"""
@@ -277,7 +278,7 @@ def edit_latex_source(_step):
@step('my change to the High Level Source is persisted')
def high_level_source_persisted(_step):
def verify_text(driver):
def verify_text(_driver):
css_sel = '.problem div>span'
return world.css_text(css_sel) == 'hi'
@@ -291,7 +292,7 @@ def high_level_source_in_editor(_step):
@step(u'I have an empty course')
def i_have_empty_course(step):
def i_have_empty_course(_step):
open_new_course()
@@ -370,7 +371,8 @@ def verify_modified_display_name_with_special_chars():
def verify_modified_display_name_with_html():
world.verify_setting_entry(world.get_setting_entry(DISPLAY_NAME), DISPLAY_NAME, "<script>alert('test')</script>", True)
world.verify_setting_entry(world.get_setting_entry(DISPLAY_NAME),
DISPLAY_NAME, "<script>alert('test')</script>", True)
def verify_unset_display_name():

View File

@@ -1,12 +1,11 @@
# pylint: disable=missing-docstring
# pylint: disable=redefined-outer-name
# pylint: disable=no-member
from lettuce import step, world
from nose.tools import assert_false, assert_true
@step('I fill in the registration form$')
def i_fill_in_the_registration_form(step):
def i_fill_in_the_registration_form(_step):
def fill_in_reg_form():
register_form = world.css_find('form#register_form')
register_form.find_by_name('email').fill('robot+studio@edx.org')
@@ -18,19 +17,19 @@ def i_fill_in_the_registration_form(step):
@step('I press the Create My Account button on the registration form$')
def i_press_the_button_on_the_registration_form(step):
def i_press_the_button_on_the_registration_form(_step):
submit_css = 'form#register_form button#submit'
world.css_click(submit_css)
@step('I should see an email verification prompt')
def i_should_see_an_email_verification_prompt(step):
def i_should_see_an_email_verification_prompt(_step):
world.css_has_text('h1.page-header', u'Studio Home')
world.css_has_text('div.msg h3.title', u'We need to verify your email address')
@step(u'I fill in and submit the signin form$')
def i_fill_in_the_signin_form(step):
def i_fill_in_the_signin_form(_step):
def fill_login_form():
login_form = world.browser.find_by_css('form#login_form')
login_form.find_by_name('email').fill('robot+studio@edx.org')
@@ -40,18 +39,18 @@ def i_fill_in_the_signin_form(step):
@step(u'I should( not)? see a login error message$')
def i_should_see_a_login_error(step, should_not_see):
def i_should_see_a_login_error(_step, should_not_see):
if should_not_see:
# the login error may be absent or invisible. Check absence first,
# because css_visible will throw an exception if the element is not present
if world.is_css_present('div#login_error'):
assert_false(world.css_visible('div#login_error'))
assert not world.css_visible('div#login_error')
else:
assert_true(world.css_visible('div#login_error'))
assert world.css_visible('div#login_error')
@step(u'I fill in and submit the signin form incorrectly$')
def i_goof_in_the_signin_form(step):
def i_goof_in_the_signin_form(_step):
def fill_login_form():
login_form = world.browser.find_by_css('form#login_form')
login_form.find_by_name('email').fill('robot+studio@edx.org')
@@ -61,12 +60,12 @@ def i_goof_in_the_signin_form(step):
@step(u'I edit the password field$')
def i_edit_the_password_field(step):
def i_edit_the_password_field(_step):
password_css = 'form#login_form input#password'
world.css_fill(password_css, 'test')
@step(u'I submit the signin form$')
def i_submit_the_signin_form(step):
def i_submit_the_signin_form(_step):
submit_css = 'form#login_form button#submit'
world.css_click(submit_css)

View File

@@ -18,9 +18,10 @@ from logging import getLogger
# it to get the correct value
import lettuce.django
from lettuce import step, world
from nose.tools import assert_equals # pylint: disable=no-name-in-module
from opaque_keys.edx.keys import CourseKey
from openedx.core.lib.tests.tools import assert_equals # pylint: disable=no-name-in-module
from .course_helpers import *
from .ui_helpers import *

View File

@@ -12,7 +12,6 @@ from urllib import quote_plus
# it to get the correct value
import lettuce.django
from lettuce import world
from nose.tools import assert_true
from selenium.common.exceptions import (
InvalidElementStateException,
StaleElementReferenceException,
@@ -23,6 +22,8 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from openedx.core.lib.tests.tools import assert_true
GLOBAL_WAIT_FOR_TIMEOUT = 60
REQUIREJS_WAIT = {

View File

@@ -1,4 +1,5 @@
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
from __future__ import absolute_import
@@ -228,9 +229,9 @@ def get_courseware_with_tabs(course_id):
'chapter_name': c.display_name_with_default_escaped,
'sections': [{
'section_name': s.display_name_with_default_escaped,
'clickable_tab_count': len(s.get_children()) if (type(s) == seq_module.SequenceDescriptor) else 0,
'clickable_tab_count': len(s.get_children()) if isinstance(s, seq_module.SequenceDescriptor) else 0,
'tabs': [{
'children_count': len(t.get_children()) if (type(t) == vertical_block.VerticalBlock) else 0,
'children_count': len(t.get_children()) if isinstance(t, vertical_block.VerticalBlock) else 0,
'class': t.__class__.__name__} for t in s.get_children()
]
} for s in c.get_children() if not s.hide_from_toc]

View File

@@ -2,9 +2,10 @@
from django.conf import settings
from lettuce import before, step, world
from nose.tools import assert_equals, assert_in
from pymongo import MongoClient
from openedx.core.lib.tests.tools import assert_equals, assert_in # pylint: disable=no-name-in-module
REQUIRED_EVENT_FIELDS = [
'agent',
'event',
@@ -18,25 +19,25 @@ REQUIRED_EVENT_FIELDS = [
]
@before.all
@before.all # pylint: disable=no-member
def connect_to_mongodb():
world.mongo_client = MongoClient(host=settings.MONGO_HOST, port=settings.MONGO_PORT_NUM)
world.event_collection = world.mongo_client['track']['events']
@before.each_scenario
@before.each_scenario # pylint: disable=no-member
def reset_captured_events(_scenario):
world.event_collection.drop()
@before.outline
def reset_between_outline_scenarios(_scenario, order, outline, reasons_to_fail):
@before.outline # pylint: disable=no-member
def reset_between_outline_scenarios(_scenario, _order, _outline, _reasons_to_fail):
world.event_collection.drop()
@step(r'[aA]n? course url "(.*)" event is emitted$')
def course_url_event_is_emitted(_step, url_regex):
event_type = url_regex.format(world.scenario_dict['COURSE'].id)
event_type = url_regex.format(world.scenario_dict['COURSE'].id) # pylint: disable=no-member
n_events_are_emitted(_step, 1, event_type, "server")
@@ -71,7 +72,7 @@ def n_events_are_emitted(_step, count, event_type, event_source):
event = cursor.next()
expected_field_values = {
"username": world.scenario_dict['USER'].username,
"username": world.scenario_dict['USER'].username, # pylint: disable=no-member
"event_type": event_type,
}
for key, value in expected_field_values.iteritems():

View File

@@ -1,4 +1,5 @@
# pylint: disable=missing-docstring
# pylint: disable=no-member
import datetime
import os
@@ -6,14 +7,13 @@ import pytz
from django.conf import settings
from lettuce import step, world
from mock import patch
from nose.tools import assert_equal, assert_in, assert_is_none, assert_true
from pytz import UTC
from selenium.common.exceptions import NoAlertPresentException
from splinter.exceptions import ElementDoesNotExist
from common import visit_scenario_item
from courseware.access import has_access
from courseware.tests.factories import BetaTesterFactory, InstructorFactory
from openedx.core.lib.tests.tools import assert_equal, assert_in, assert_true # pylint: disable=no-name-in-module
from student.tests.factories import UserFactory
TEST_COURSE_NAME = "test_course_a"

View File

@@ -3,15 +3,16 @@ Define common steps for instructor dashboard acceptance tests.
"""
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
from __future__ import absolute_import
from lettuce import step, world
from mock import patch
from nose.tools import assert_in
from courseware.tests.factories import InstructorFactory, StaffFactory
from openedx.core.lib.tests.tools import assert_in # pylint: disable=no-name-in-module
@step(u'Given I am "([^"]*)" for a very large course')
@@ -122,7 +123,7 @@ def click_a_button(step, button): # pylint: disable=unused-argument
@step(u'I visit the "([^"]*)" tab')
def click_a_button(step, tab_name): # pylint: disable=unused-argument
def click_a_tab(step, tab_name): # pylint: disable=unused-argument
# course_info, membership, student_admin, data_download, analytics, send_email
tab_name_dict = {
'Course Info': 'course_info',

View File

@@ -4,14 +4,16 @@ acceptance tests.
"""
# pylint: disable=missing-docstring
# pylint: disable=no-member
# pylint: disable=redefined-outer-name
from django.utils import http
from lettuce import step, world
from nose.tools import assert_in, assert_regexp_matches
from terrain.steps import reload_the_page
from openedx.core.lib.tests.tools import assert_in, assert_regexp_matches # pylint: disable=no-name-in-module
@step(u'I see a table of student profiles')
def find_student_profile_table(step): # pylint: disable=unused-argument

View File

@@ -0,0 +1,43 @@
"""
Copy of the useful parts of nose.tools. This is only used for lettuce test
utility functions, which neither use pytest nor have access to a TestCase
instance. This module should be deleted once the last lettuce tests have
been ported over to bok-choy.
Tracebacks should not descend into these functions.
We define the ``__unittest`` symbol in their module namespace so unittest will
skip them when printing tracebacks, just as it does for their corresponding
methods in ``unittest`` proper.
"""
import re
import unittest
__all__ = []
# Use the same flag as unittest itself to prevent descent into these functions:
__unittest = 1
# Expose assert* from unittest.TestCase
# - give them pep8 style names
caps = re.compile('([A-Z])')
def pep8(name):
return caps.sub(lambda m: '_' + m.groups()[0].lower(), name)
class Dummy(unittest.TestCase):
def noop(self):
pass
_t = Dummy('noop')
for at in [at for at in dir(_t) if at.startswith('assert') and '_' not in at]:
pepd = pep8(at)
vars()[pepd] = getattr(_t, at)
__all__.append(pepd)
del Dummy
del _t
del pep8