problems.py 6.5 KB
Newer Older
Will Daly committed
1 2 3 4
'''
Steps for problem.feature lettuce tests
'''

5
# pylint: disable=missing-docstring
6
# pylint: disable=redefined-outer-name
Will Daly committed
7

8
from lettuce import world, step
9
from common import i_am_registered_for_the_course, visit_scenario_item
10
from problems_setup import PROBLEM_DICT, answer_problem, problem_has_answer, add_problem_to_course
11

12

13
def _view_problem(step, problem_type, problem_settings=None):
14 15 16
    i_am_registered_for_the_course(step, 'model_course')

    # Ensure that the course has this problem type
17
    add_problem_to_course(world.scenario_dict['COURSE'].number, problem_type, problem_settings)
18 19 20

    # Go to the one section in the factory-created course
    # which should be loaded with the correct problem
21
    visit_scenario_item('SECTION')
22 23


24 25 26
@step(u'I am viewing a "([^"]*)" problem with "([^"]*)" attempt')
def view_problem_with_attempts(step, problem_type, attempts):
    _view_problem(step, problem_type, {'max_attempts': attempts})
27

28

29 30 31 32 33 34 35
@step(u'I am viewing a randomization "([^"]*)" "([^"]*)" problem with "([^"]*)" attempts with reset')
def view_problem_attempts_reset(step, randomization, problem_type, attempts, ):
    _view_problem(step, problem_type, {'max_attempts': attempts,
                                       'rerandomize': randomization,
                                       'show_reset_button': True})


36 37 38
@step(u'I am viewing a "([^"]*)" that shows the answer "([^"]*)"')
def view_problem_with_show_answer(step, problem_type, answer):
    _view_problem(step, problem_type, {'showanswer': answer})
Will Daly committed
39

40 41 42

@step(u'I am viewing a "([^"]*)" problem')
def view_problem(step, problem_type):
43
    _view_problem(step, problem_type)
44

Will Daly committed
45

46 47 48 49 50
@step(u'I am viewing a randomization "([^"]*)" "([^"]*)" problem with reset button on')
def view_random_reset_problem(step, randomization, problem_type):
    _view_problem(step, problem_type, {'rerandomize': randomization, 'show_reset_button': True})


51 52 53 54
@step(u'External graders respond "([^"]*)"')
def set_external_grader_response(step, correctness):
    assert(correctness in ['correct', 'incorrect'])

55 56 57 58 59
    response_dict = {
        'correct': True if correctness == 'correct' else False,
        'score': 1 if correctness == 'correct' else 0,
        'msg': 'Your problem was graded {0}'.format(correctness)
    }
60 61 62

    # Set the fake xqueue server to always respond
    # correct/incorrect when asked to grade a problem
63
    world.xqueue.config['default'] = response_dict
64

65

66
@step(u'I answer a "([^"]*)" problem "([^"]*)ly"')
67
def answer_problem_step(step, problem_type, correctness):
68 69 70 71 72
    """ Mark a given problem type correct or incorrect, then submit it.

    *problem_type* is a string representing the type of problem (e.g. 'drop down')
    *correctness* is in ['correct', 'incorrect']
    """
73 74
    # Change the answer on the page
    input_problem_answer(step, problem_type, correctness)
75

76 77 78 79 80 81 82 83 84
    # Submit the problem
    check_problem(step)


@step(u'I input an answer on a "([^"]*)" problem "([^"]*)ly"')
def input_problem_answer(_, problem_type, correctness):
    """
    Have the browser input an answer (either correct or incorrect)
    """
85
    assert(correctness in ['correct', 'incorrect'])
86
    assert(problem_type in PROBLEM_DICT)
87
    answer_problem(world.scenario_dict['COURSE'].number, problem_type, correctness)
Will Daly committed
88

Will Daly committed
89

90 91
@step(u'I check a problem')
def check_problem(step):
92 93 94
    # first scroll down so the loading mathjax button does not
    # cover up the Check button
    world.browser.execute_script("window.scrollTo(0,1024)")
95
    world.css_click("button.check")
96

97 98 99
    # Wait for the problem to finish re-rendering
    world.wait_for_ajax_complete()

100

101 102 103 104 105 106 107 108 109 110 111
@step(u'The "([^"]*)" problem displays a "([^"]*)" answer')
def assert_problem_has_answer(step, problem_type, answer_class):
    '''
    Assert that the problem is displaying a particular answer.
    These correspond to the same correct/incorrect
    answers we set in answer_problem()

    We can also check that a problem has been left blank
    by setting answer_class='blank'
    '''
    assert answer_class in ['correct', 'incorrect', 'blank']
112
    assert problem_type in PROBLEM_DICT
113
    problem_has_answer(world.scenario_dict['COURSE'].number, problem_type, answer_class)
114

Will Daly committed
115

116
@step(u'I reset the problem')
Don Mitchell committed
117
def reset_problem(_step):
118
    world.css_click('button.reset')
119

120 121 122
    # Wait for the problem to finish re-rendering
    world.wait_for_ajax_complete()

Will Daly committed
123

124
@step(u'I press the button with the label "([^"]*)"$')
Don Mitchell committed
125
def press_the_button_with_label(_step, buttonname):
126 127
    button_css = 'button span.show-label'
    elem = world.css_find(button_css).first
128
    world.css_has_text(button_css, elem)
129
    world.css_click(button_css)
130 131


132
@step(u'The "([^"]*)" button does( not)? appear')
Don Mitchell committed
133
def action_button_present(_step, buttonname, doesnt_appear):
134
    button_css = 'div.action button[data-value*="%s"]' % buttonname
135
    if bool(doesnt_appear):
Jay Zoldak committed
136 137 138 139 140
        assert world.is_css_not_present(button_css)
    else:
        assert world.is_css_present(button_css)


141 142 143 144 145 146
@step(u'the Show/Hide button label is "([^"]*)"$')
def show_hide_label_is(_step, label_name):
    # The label text is changed by static/xmodule_js/src/capa/display.js
    # so give it some time to change on the page.
    label_css = 'button.show span.show-label'
    world.wait_for(lambda _: world.css_has_text(label_css, label_name))
147 148


149 150
@step(u'I should see a score of "([^"]*)"$')
def see_score(_step, score):
151 152 153
    # The problem progress is changed by
    # cms/static/xmodule_js/src/capa/display.js
    # so give it some time to render on the page.
154
    score_css = 'div.problem-progress'
155 156
    expected_text = '({})'.format(score)
    world.wait_for(lambda _: world.css_has_text(score_css, expected_text))
157 158


159 160
@step(u'[Mm]y "([^"]*)" answer is( NOT)? marked "([^"]*)"')
def assert_answer_mark(_step, problem_type, isnt_marked, correctness):
Will Daly committed
161 162 163
    """
    Assert that the expected answer mark is visible
    for a given problem type.
164 165 166

    *problem_type* is a string identifying the type of problem (e.g. 'drop down')
    *correctness* is in ['correct', 'incorrect', 'unanswered']
167 168
    """
    # Determine which selector(s) to look for based on correctness
169 170
    assert(correctness in ['correct', 'incorrect', 'unanswered'])
    assert(problem_type in PROBLEM_DICT)
171 172

    # At least one of the correct selectors should be present
173
    for sel in PROBLEM_DICT[problem_type][correctness]:
174
        if bool(isnt_marked):
175 176 177
            has_expected = world.is_css_not_present(sel)
        else:
            has_expected = world.is_css_present(sel)
178 179 180 181

        # As soon as we find the selector, break out of the loop
        if has_expected:
            break
182

183 184
    # Expect that we found the expected selector
    assert(has_expected)