Пример #1
0
def see_a_single_step_component(step):
    for step_hash in step.hashes:
        component = step_hash['Component']
        assert_in(component, ['Discussion', 'Video'])
        component_css = '.xmodule_{}Module'.format(component)
        assert_true(world.is_css_present(component_css),
                    "{} couldn't be found".format(component))
Пример #2
0
def find_student_profile_table(step):  # pylint: disable=unused-argument
    # Find the grading configuration display
    world.wait_for_visible('#data-student-profiles-table')

    # Wait for the data table to be populated
    world.wait_for(lambda _: world.css_text('#data-student-profiles-table') not in [u'', u'Loading'])

    if world.role == 'instructor':
        expected_data = [
            world.instructor.username,
            world.instructor.email,
            world.instructor.profile.name,
            world.instructor.profile.gender,
            world.instructor.profile.goals
        ]
    elif world.role == 'staff':
        expected_data = [
            world.staff.username,
            world.staff.email,
            world.staff.profile.name,
            world.staff.profile.gender,
            world.staff.profile.goals
        ]
    for datum in expected_data:
        assert_in(datum, world.css_text('#data-student-profiles-table'))
Пример #3
0
def see_a_single_step_component(step):
    for step_hash in step.hashes:
        component = step_hash['Component']
        assert_in(component, ['Discussion', 'Video'])
        component_css = '.xmodule_{}Module'.format(component)
        assert_true(world.is_css_present(component_css),
                    u"{} couldn't be found".format(component))
Пример #4
0
def see_a_multi_step_component(step, category):

    # Wait for all components to finish rendering
    if category == 'HTML':
        selector = 'li.studio-xblock-wrapper div.xblock-student_view'
    else:
        selector = 'li.studio-xblock-wrapper div.xblock-author_view'
    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':
                '<h3 class="hd hd-2">Announcement Date</h3>',
                'Zooming Image Tool':
                '<h3 class="hd hd-2">Zooming Image Tool</h3>',
                'E-text Written in LaTeX':
                '<h3 class="hd hd-2">Example: E-text page</h3>',
                'Raw HTML':
                '<p>This template is similar to the Text template. The only difference is',
            }
            actual_html = world.css_html(selector, index=idx)
            assert_in(html_matcher[step_hash['Component']].strip(),
                      actual_html.strip())
        else:
            actual_text = world.css_text(selector, index=idx)
            assert_in(step_hash['Component'], actual_text)
Пример #5
0
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
        assert_in(
            unicode(world.scenario_dict['COURSE'].id.make_asset_key(
                'asset', path)), link['href'])
Пример #6
0
def log_into_studio(uname='robot',
                    email='*****@*****.**',
                    password='******',
                    name='Robot Studio'):

    world.log_in(username=uname, password=password, email=email, name=name)
    # Navigate to the studio dashboard
    world.visit('/')
    assert_in(uname, world.css_text('span.account-username', timeout=10))
Пример #7
0
def add_a_single_step_component(step):
    for step_hash in step.hashes:
        component = step_hash['Component']
        assert_in(component, ['Discussion', 'Video'])

        world.create_component_instance(
            step=step,
            category='{}'.format(component.lower()),
        )
Пример #8
0
def check_lti_component_no_elem(_step, text):
    selector_map = {
        'a launch button': '.link_lti_new_window',
        'an provider iframe': '.ltiLaunchFrame',
        'feedback': '.problem-feedback',
        'progress': '.problem-progress',
    }
    assert_in(text, selector_map)
    assert_true(world.is_css_not_present(selector_map[text]))
Пример #9
0
def check_lti_component_no_elem(_step, text):
    selector_map = {
        'a launch button': '.link_lti_new_window',
        'an provider iframe': '.ltiLaunchFrame',
        'feedback': '.problem-feedback',
        'progress': '.problem-progress',
    }
    assert_in(text, selector_map)
    assert_true(world.is_css_not_present(selector_map[text]))
Пример #10
0
def add_a_single_step_component(step):
    for step_hash in step.hashes:
        component = step_hash['Component']
        assert_in(component, ['Discussion', 'Video'])

        world.create_component_instance(
            step=step,
            category='{}'.format(component.lower()),
        )
Пример #11
0
def see_elem_text(_step, elem, text):
    selector_map = {
        'progress': '.problem-progress',
        'feedback': '.problem-feedback',
        'module title': '.problem-header',
        'button': '.link_lti_new_window',
        'description': '.lti-description'
    }
    assert_in(elem, selector_map)
    assert_true(world.css_has_text(selector_map[elem], text))
Пример #12
0
def log_into_studio(
        uname='robot',
        email='*****@*****.**',
        password='******',
        name='Robot Studio'):

    world.log_in(username=uname, password=password, email=email, name=name)
    # Navigate to the studio dashboard
    world.visit('/')
    assert_in(uname, world.css_text('span.account-username', timeout=10))
Пример #13
0
def see_elem_text(_step, elem, text):
    selector_map = {
        'progress': '.problem-progress',
        'feedback': '.problem-feedback',
        'module title': '.problem-header',
        'button': '.link_lti_new_window',
        'description': '.lti-description'
    }
    assert_in(elem, selector_map)
    assert_true(world.css_has_text(selector_map[elem], text))
Пример #14
0
def click_grade(_step, version):
    version_map = {
        '1': {'selector': 'submit-button', 'expected_text': 'LTI consumer (edX) responded with XML content'},
        '2': {'selector': 'submit-lti2-button', 'expected_text': 'LTI consumer (edX) responded with HTTP 200'},
    }
    assert_in(version, version_map)
    location = world.scenario_dict['LTI'].location.html_id()
    iframe_name = 'ltiFrame-' + location
    with world.browser.get_iframe(iframe_name) as iframe:
        css_ele = version_map[version]['selector']
        css_loc = '#' + css_ele
        world.wait_for_visible(css_loc)
        world.css_click(css_loc)
        assert iframe.is_text_present(version_map[version]['expected_text'])
Пример #15
0
def i_am_staff_or_instructor(step, role):  # pylint: disable=unused-argument
    ## In summary: makes a test course, makes a new Staff or Instructor user
    ## (depending on `role`), and logs that user in to the course

    # Store the role
    assert_in(role, ['instructor', 'staff'])

    # Clear existing courses to avoid conflicts
    world.clear_courses()

    # Create a new course
    course = world.CourseFactory.create(
        org='edx',
        number='999',
        display_name='Test Course'
    )

    world.course_key = course.id
    world.role = 'instructor'
    # Log in as the an instructor or staff for the course
    if role == 'instructor':
        # Make & register an instructor for the course
        world.instructor = InstructorFactory(course_key=world.course_key)
        world.enroll_user(world.instructor, world.course_key)

        world.log_in(
            username=world.instructor.username,
            password='******',
            email=world.instructor.email,
            name=world.instructor.profile.name
        )

    else:
        world.role = 'staff'
        # Make & register a staff member
        world.staff = StaffFactory(course_key=world.course_key)
        world.enroll_user(world.staff, world.course_key)

        world.log_in(
            username=world.staff.username,
            password='******',
            email=world.staff.email,
            name=world.staff.profile.name
        )
Пример #16
0
def create_component_instance(step,
                              category,
                              component_type=None,
                              is_advanced=False,
                              advanced_component=None):
    """
    Create a new component in a Unit.

    Parameters
    ----------
    category: component type (discussion, html, problem, video, advanced)
    component_type: for components with multiple templates, the link text in the menu
    is_advanced: for problems, is the desired component under the advanced menu?
    advanced_component: for advanced components, the related value of policy key 'advanced_modules'
    """
    assert_in(category, ['advanced', 'problem', 'html', 'video', 'discussion'])

    component_button_css = 'span.large-{}-icon'.format(category.lower())
    if category == 'problem':
        module_css = 'div.xmodule_CapaModule'
    elif category == 'advanced':
        module_css = 'div.xmodule_{}Module'.format(advanced_component.title())
    elif category == 'discussion':
        module_css = 'div.xblock-author_view-{}'.format(category.lower())
    else:
        module_css = 'div.xmodule_{}Module'.format(category.title())

    # Count how many of that module is on the page. Later we will
    # assert that one more was added.
    # We need to use world.browser.find_by_css instead of world.css_find
    # because it's ok if there are currently zero of them.
    module_count_before = len(world.browser.find_by_css(module_css))

    # Disable the jquery animation for the transition to the menus.
    world.disable_jquery_animations()
    world.css_click(component_button_css)

    if category in ('problem', 'html', 'advanced'):
        world.wait_for_invisible(component_button_css)
        click_component_from_menu(category, component_type, is_advanced)

    expected_count = module_count_before + 1
    world.wait_for(lambda _: len(world.css_find(module_css)) == expected_count,
                   timeout=20)
def create_component_instance(step, category, component_type=None, is_advanced=False, advanced_component=None):
    """
    Create a new component in a Unit.

    Parameters
    ----------
    category: component type (discussion, html, problem, video, advanced)
    component_type: for components with multiple templates, the link text in the menu
    is_advanced: for problems, is the desired component under the advanced menu?
    advanced_component: for advanced components, the related value of policy key 'advanced_modules'
    """
    assert_in(category, ['advanced', 'problem', 'html', 'video', 'discussion'])

    component_button_css = 'span.large-{}-icon'.format(category.lower())
    if category == 'problem':
        module_css = 'div.xmodule_CapaModule'
    elif category == 'advanced':
        module_css = 'div.xmodule_{}Module'.format(advanced_component.title())
    elif category == 'discussion':
        module_css = 'div.xblock-author_view-{}'.format(category.lower())
    else:
        module_css = 'div.xmodule_{}Module'.format(category.title())

    # Count how many of that module is on the page. Later we will
    # assert that one more was added.
    # We need to use world.browser.find_by_css instead of world.css_find
    # because it's ok if there are currently zero of them.
    module_count_before = len(world.browser.find_by_css(module_css))

    # Disable the jquery animation for the transition to the menus.
    world.disable_jquery_animations()
    world.css_click(component_button_css)

    if category in ('problem', 'html', 'advanced'):
        world.wait_for_invisible(component_button_css)
        click_component_from_menu(category, component_type, is_advanced)

    expected_count = module_count_before + 1
    world.wait_for(
        lambda _: len(world.css_find(module_css)) == expected_count,
        timeout=20
    )
Пример #18
0
def click_grade(_step, version):
    version_map = {
        '1': {
            'selector': 'submit-button',
            'expected_text': 'LTI consumer (edX) responded with XML content'
        },
        '2': {
            'selector': 'submit-lti2-button',
            'expected_text': 'LTI consumer (edX) responded with HTTP 200'
        },
    }
    assert_in(version, version_map)
    location = world.scenario_dict['LTI'].location.html_id()
    iframe_name = 'ltiFrame-' + location
    with world.browser.get_iframe(iframe_name) as iframe:
        css_ele = version_map[version]['selector']
        css_loc = '#' + css_ele
        world.wait_for_visible(css_loc)
        world.css_click(css_loc)
        assert iframe.is_text_present(version_map[version]['expected_text'])
Пример #19
0
def find_grading_config(step):  # pylint: disable=unused-argument
    # Find the grading configuration display
    world.wait_for_visible('#data-grade-config-text')
    # expected config is the default grading configuration from common/lib/xmodule/xmodule/course_module.py
    expected_config = u"""-----------------------------------------------------------------------------
Course grader:
<class 'xmodule.graders.WeightedSubsectionsGrader'>

Graded sections:
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Homework, category=Homework, weight=0.15
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Lab, category=Lab, weight=0.15
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Midterm Exam, category=Midterm Exam, weight=0.3
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Final Exam, category=Final Exam, weight=0.4
-----------------------------------------------------------------------------
Listing grading context for course {}
graded sections:
[]
all graded blocks:
length=0""".format(world.course_key)
    assert_in(expected_config, world.css_text('#data-grade-config-text'))
Пример #20
0
def find_grading_config(step):  # pylint: disable=unused-argument
    # Find the grading configuration display
    world.wait_for_visible('#data-grade-config-text')
    # expected config is the default grading configuration from common/lib/xmodule/xmodule/course_module.py
    expected_config = u"""-----------------------------------------------------------------------------
Course grader:
<class 'xmodule.graders.WeightedSubsectionsGrader'>

Graded sections:
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Homework, category=Homework, weight=0.15
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Lab, category=Lab, weight=0.15
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Midterm Exam, category=Midterm Exam, weight=0.3
  subgrader=<class 'xmodule.graders.AssignmentFormatGrader'>, type=Final Exam, category=Final Exam, weight=0.4
-----------------------------------------------------------------------------
Listing grading context for course {}
graded sections:
[]
all graded blocks:
length=0""".format(world.course_key)
    assert_in(expected_config, world.css_text('#data-grade-config-text'))
Пример #21
0
def find_student_profile_table(step):  # pylint: disable=unused-argument
    # Find the grading configuration display
    world.wait_for_visible('#data-student-profiles-table')

    # Wait for the data table to be populated
    world.wait_for(lambda _: world.css_text('#data-student-profiles-table')
                   not in [u'', u'Loading'])

    if world.role == 'instructor':
        expected_data = [
            world.instructor.username, world.instructor.email,
            world.instructor.profile.name, world.instructor.profile.gender,
            world.instructor.profile.goals
        ]
    elif world.role == 'staff':
        expected_data = [
            world.staff.username, world.staff.email, world.staff.profile.name,
            world.staff.profile.gender, world.staff.profile.goals
        ]
    for datum in expected_data:
        assert_in(datum, world.css_text('#data-student-profiles-table'))
Пример #22
0
def click_a_button(step, button):  # pylint: disable=unused-argument

    if button == "Generate Grade Report":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        # Click generate grade report button
        world.css_click('input[name="calculate-grades-csv"]')

        # Expect to see a message that grade report is being generated
        expected_msg = "The grade report is being created." \
                       " To view the status of the report, see" \
                       " Pending Tasks below."
        world.wait_for_visible('#report-request-response')
        assert_in(
            expected_msg,
            world.css_text('#report-request-response'),
            msg="Could not find grade report generation success message.")

    elif button == "Grading Configuration":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        world.css_click('input[name="dump-gradeconf"]')

    elif button == "List enrolled students' profile information":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        world.css_click('input[name="list-profiles"]')

    elif button == "Download profile information as a CSV":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        world.css_click('input[name="list-profiles-csv"]')

    else:
        raise ValueError("Unrecognized button option " + button)
Пример #23
0
def click_a_button(step, button):  # pylint: disable=unused-argument

    if button == "Generate Grade Report":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        # Click generate grade report button
        world.css_click('input[name="calculate-grades-csv"]')

        # Expect to see a message that grade report is being generated
        expected_msg = "The grade report is being created." \
                       " To view the status of the report, see" \
                       " Pending Tasks below."
        world.wait_for_visible('#report-request-response')
        assert_in(
            expected_msg, world.css_text('#report-request-response'),
            msg="Could not find grade report generation success message."
        )

    elif button == "Grading Configuration":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        world.css_click('input[name="dump-gradeconf"]')

    elif button == "List enrolled students' profile information":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        world.css_click('input[name="list-profiles"]')

    elif button == "Download profile information as a CSV":
        # Go to the data download section of the instructor dash
        go_to_section("data_download")

        world.css_click('input[name="list-profiles-csv"]')

    else:
        raise ValueError("Unrecognized button option " + button)
Пример #24
0
def i_am_staff_or_instructor(step, role):  # pylint: disable=unused-argument
    ## In summary: makes a test course, makes a new Staff or Instructor user
    ## (depending on `role`), and logs that user in to the course

    # Store the role
    assert_in(role, ['instructor', 'staff'])

    # Clear existing courses to avoid conflicts
    world.clear_courses()

    # Create a new course
    course = world.CourseFactory.create(org='edx',
                                        number='999',
                                        display_name='Test Course')

    world.course_key = course.id
    world.role = 'instructor'
    # Log in as the an instructor or staff for the course
    if role == 'instructor':
        # Make & register an instructor for the course
        world.instructor = InstructorFactory(course_key=world.course_key)
        world.enroll_user(world.instructor, world.course_key)

        world.log_in(username=world.instructor.username,
                     password='******',
                     email=world.instructor.email,
                     name=world.instructor.profile.name)

    else:
        world.role = 'staff'
        # Make & register a staff member
        world.staff = StaffFactory(course_key=world.course_key)
        world.enroll_user(world.staff, world.course_key)

        world.log_in(username=world.staff.username,
                     password='******',
                     email=world.staff.email,
                     name=world.staff.profile.name)
Пример #25
0
def n_events_are_emitted(_step, count, event_type, event_source):

    # Ensure all events are written out to mongo before querying.
    world.mongo_client.fsync()

    # Note that splinter makes 2 requests when you call browser.visit('/foo')
    # the first just checks to see if the server responds with a status
    # code of 200, the next actually uses the browser to submit the request.
    # We filter out events associated with the status code checks by ignoring
    # events that come directly from splinter.
    criteria = {
        'event_type': event_type,
        'event_source': event_source,
        'agent': {
            '$ne': 'python/splinter'
        }
    }

    cursor = world.event_collection.find(criteria)

    try:
        number_events = int(count)
    except ValueError:
        number_events = 1

    assert_equals(cursor.count(), number_events)

    event = cursor.next()

    expected_field_values = {
        "username": world.scenario_dict['USER'].username,  # pylint: disable=no-member
        "event_type": event_type,
    }
    for key, value in expected_field_values.iteritems():
        assert_equals(event[key], value)

    for field in REQUIRED_EVENT_FIELDS:
        assert_in(field, event)
Пример #26
0
def see_a_multi_step_component(step, category):

    # Wait for all components to finish rendering
    if category == 'HTML':
        selector = 'li.studio-xblock-wrapper div.xblock-student_view'
    else:
        selector = 'li.studio-xblock-wrapper div.xblock-author_view'
    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': '<h3 class="hd hd-2">Announcement Date</h3>',
                'Zooming Image Tool': '<h3 class="hd hd-2">Zooming Image Tool</h3>',
                'E-text Written in LaTeX': '<h3 class="hd hd-2">Example: E-text page</h3>',
                'Raw HTML': '<p>This template is similar to the Text template. The only difference is',
            }
            actual_html = world.css_html(selector, index=idx)
            assert_in(html_matcher[step_hash['Component']].strip(), actual_html.strip())
        else:
            actual_text = world.css_text(selector, index=idx)
            assert_in(step_hash['Component'], actual_text)
Пример #27
0
def default_options_sets_expected_font_family(step):  # pylint: disable=unused-argument, redefined-outer-name
    fonts = get_available_fonts(get_fonts_list_panel(world))
    fonts_found = fonts.get("Default", None)
    expected_font_family = CUSTOM_FONTS.get('Default')
    for expected_font in expected_font_family:
        assert_in(expected_font, fonts_found)
Пример #28
0
def check_page_text(step):
    assert_in(step.multiline, world.css_find('.xmodule_HtmlModule').html)
Пример #29
0
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:
            assert_in(expected_font, fonts.get(label, None))
Пример #30
0
def i_see_the_assignment_type(_step, name):
    assignment_css = '#course-grading-assignment-name'
    assignments = world.css_find(assignment_css)
    types = [ele['value'] for ele in assignments]
    assert_in(name, types)
Пример #31
0
def main_course_page(_step):
    main_page_link = reverse_course_url('course_handler', world.scenario_dict['COURSE'].id)

    world.visit(main_page_link)
    assert_in('Course Outline', world.css_text('h1.page-header'))
Пример #32
0
def default_options_sets_expected_font_family(step):  # pylint: disable=unused-argument, redefined-outer-name
    fonts = get_available_fonts(get_fonts_list_panel(world))
    fonts_found = fonts.get("Default", None)
    expected_font_family = CUSTOM_FONTS.get('Default')
    for expected_font in expected_font_family:
        assert_in(expected_font, fonts_found)
Пример #33
0
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:
            assert_in(expected_font, fonts.get(label, None))
Пример #34
0
def see_pages_in_expected_order(page_names_in_expected_order):
    pages = world.css_find("li.course-tab")
    assert_equal(len(page_names_in_expected_order), len(pages))
    for i, page_name in enumerate(page_names_in_expected_order):
        assert_in(page_name, pages[i].text)
Пример #35
0
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
        assert_in(unicode(world.scenario_dict['COURSE'].id.make_asset_key('asset', path)), link['href'])
Пример #36
0
def check_page_text(step):
    assert_in(step.multiline, world.css_find('.xmodule_HtmlModule').html)