component.py 6.49 KB
Newer Older
1
# pylint: disable=missing-docstring
2
# pylint: disable=redefined-outer-name
3

4 5
# Lettuce formats proposed definitions for unimplemented steps with the
# argument name "step" instead of "_step" and pylint does not like that.
6
# pylint: disable=unused-argument
7

8
from lettuce import world, step
9
from nose.tools import assert_true, assert_in, assert_equal  # pylint: disable=no-name-in-module
10

11 12
DISPLAY_NAME = "Display Name"

13

14 15 16 17 18 19
@step(u'I add this type of single step component:$')
def add_a_single_step_component(step):
    for step_hash in step.hashes:
        component = step_hash['Component']
        assert_in(component, ['Discussion', 'Video'])

20 21 22 23
        world.create_component_instance(
            step=step,
            category='{}'.format(component.lower()),
        )
24

25 26 27 28 29 30

@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'])
31
        component_css = 'div.xmodule_{}Module'.format(component)
32 33 34 35 36 37 38
        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):
    for step_hash in step.hashes:
39 40 41 42
        world.create_component_instance(
            step=step,
            category='{}'.format(category.lower()),
            component_type=step_hash['Component'],
43
            is_advanced=bool(is_advanced),
44
        )
45 46 47 48


@step(u'I see (HTML|Problem) components in this order:')
def see_a_multi_step_component(step, category):
49 50

    # Wait for all components to finish rendering
51
    selector = 'li.studio-xblock-wrapper div.xblock-student_view'
52 53
    world.wait_for(lambda _: len(world.css_find(selector)) == len(step.hashes))

54 55 56
    for idx, step_hash in enumerate(step.hashes):
        if category == 'HTML':
            html_matcher = {
57
                'Text': '\n    \n',
58
                'Announcement': '<h3>Announcement Date</h3>',
59
                'Zooming Image Tool': '<h2>Zooming Image Tool</h2>',
60
                'E-text Written in LaTeX': '<h3>Example: E-text page</h3>',
61
                'Raw HTML': '<p>This template is similar to the Text template. The only difference is',
62
            }
63
            actual_html = world.css_html(selector, index=idx)
64
            assert_in(html_matcher[step_hash['Component']].strip(), actual_html.strip())
65
        else:
66 67
            actual_text = world.css_text(selector, index=idx)
            assert_in(step_hash['Component'].upper(), actual_text)
68 69


70 71
@step(u'I see a "([^"]*)" Problem component$')
def see_a_problem_component(step, category):
72
    component_css = 'div.xmodule_CapaModule'
73
    assert_true(world.is_css_present(component_css),
74
                'No problem was added to the unit.')
75

76
    problem_css = 'li.studio-xblock-wrapper div.xblock-student_view'
77 78
    # This view presents the given problem component in uppercase. Assert that the text matches
    # the component selected (in uppercase)
79
    assert_true(world.css_contains_text(problem_css, category.upper()))
80 81


82
@step(u'I add a "([^"]*)" "([^"]*)" component$')
83
def add_component_category(step, component, category):
84 85 86 87 88 89
    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$')
90
def delete_all_components(step):
91
    count = len(world.css_find('ol.reorderable-container li.studio-xblock-wrapper'))
92 93 94 95 96
    step.given('I delete "' + str(count) + '" component')


@step(u'I delete "([^"]*)" component$')
def delete_components(step, number):
97
    world.wait_for_xmodule()
98 99 100 101
    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'
102
    for _ in range(int(number)):
103
        world.css_click(delete_btn_css)
104 105
        assert_true(
            world.is_css_present('{}.is-shown'.format(prompt_css)),
106 107 108 109 110 111 112 113 114 115 116 117
            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))
118 119 120 121


@step(u'I see no components')
def see_no_components(steps):
122
    assert world.is_css_not_present('li.studio-xblock-wrapper')
123 124


125 126 127 128 129 130 131 132 133
@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')
134 135


136 137 138 139 140 141 142 143
@step(u'I duplicate the (first|second|third) component$')
def duplicated_component(step, ordinal):
    ord_map = {
        "first": 0,
        "second": 1,
        "third": 2,
    }
    index = ord_map[ordinal]
144 145 146 147 148 149
    duplicate_btn_css = 'a.duplicate-button'
    world.css_click(duplicate_btn_css, int(index))


@step(u'I see a Problem component with display name "([^"]*)" in position "([^"]*)"$')
def see_component_in_position(step, display_name, index):
150
    component_css = 'div.xmodule_CapaModule'
151 152 153 154 155

    def find_problem(_driver):
        return world.css_text(component_css, int(index)).startswith(display_name.upper())

    world.wait_for(find_problem, timeout_msg='Did not find the duplicated problem')
156 157 158 159


@step(u'I see the display name is "([^"]*)"')
def check_component_display_name(step, display_name):
160 161 162
    # The display name for the unit uses the same structure, must differentiate by level-element.
    label = world.css_html("section.level-element>header>div>div>span.xblock-display-name")
    assert_equal(display_name, label)
163 164 165 166 167


@step(u'I change the display name to "([^"]*)"')
def change_display_name(step, display_name):
    world.edit_component_and_select_settings()
168 169
    index = world.get_setting_entry_index(DISPLAY_NAME)
    world.set_field_value(index, display_name)
170
    world.save_component()
171 172 173 174 175 176


@step(u'I unset the display name')
def unset_display_name(step):
    world.edit_component_and_select_settings()
    world.revert_setting_entry(DISPLAY_NAME)
177
    world.save_component()