From 90213d483cb0af36ca5fd33aa2c3864c6ec8d0e0 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 13 Mar 2013 14:25:36 -0400 Subject: [PATCH] Wrote lettuce tests for drop-down, multiple choice, and checkbox problems. --- common/djangoapps/terrain/steps.py | 15 +++- lms/djangoapps/courseware/features/common.py | 10 ++- .../courseware/features/courseware.feature | 2 +- .../features/high-level-tabs.feature | 2 +- .../courseware/features/problems.feature | 53 +++++++++++++ .../courseware/features/problems.py | 79 +++++++++++++++++++ .../courseware/features/registration.feature | 4 +- .../courseware/features/registration.py | 11 +-- 8 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 lms/djangoapps/courseware/features/problems.feature create mode 100644 lms/djangoapps/courseware/features/problems.py diff --git a/common/djangoapps/terrain/steps.py b/common/djangoapps/terrain/steps.py index 3dcef9b1ed..330740b6b3 100644 --- a/common/djangoapps/terrain/steps.py +++ b/common/djangoapps/terrain/steps.py @@ -116,6 +116,11 @@ def scroll_to_bottom(): @world.absorb def create_user(uname): + + # If the user already exists, don't try to create it again + if len(User.objects.filter(username=uname)) > 0: + return + portal_user = UserFactory.build(username=uname, email=uname + '@edx.org') portal_user.set_password('test') portal_user.save() @@ -133,13 +138,17 @@ def log_in(email, password): world.browser.visit(django_url('/')) world.browser.is_element_present_by_css('header.global', 10) world.browser.click_link_by_href('#login-modal') + + # wait for the login dialog to load + assert(world.browser.is_element_present_by_css('form#login_form', wait_time=10)) + login_form = world.browser.find_by_css('form#login_form') - login_form.find_by_name('email').fill(email) - login_form.find_by_name('password').fill(password) + login_form.find_by_name('email').type(email) + login_form.find_by_name('password').type(password) login_form.find_by_name('submit').click() # wait for the page to redraw - assert world.browser.is_element_present_by_css('.content-wrapper', 10) + assert world.browser.is_element_present_by_css('.content-wrapper', wait_time=10) @world.absorb diff --git a/lms/djangoapps/courseware/features/common.py b/lms/djangoapps/courseware/features/common.py index 2e19696ad4..145a56e183 100644 --- a/lms/djangoapps/courseware/features/common.py +++ b/lms/djangoapps/courseware/features/common.py @@ -81,11 +81,15 @@ def i_am_not_logged_in(step): world.browser.cookies.delete() -@step(u'I am registered for a course$') -def i_am_registered_for_a_course(step): +@step(u'I am registered for the course "([^"]*)"$') +def i_am_registered_for_the_course(step, course_id): world.create_user('robot') u = User.objects.get(username='robot') - CourseEnrollment.objects.create(user=u, course_id='MITx/6.002x/2012_Fall') + + # If the user is not already enrolled, enroll the user. + if len(CourseEnrollment.objects.filter(user=u, course_id=course_id)) == 0: + CourseEnrollment.objects.create(user=u, course_id=course_id) + world.log_in('robot@edx.org', 'test') diff --git a/lms/djangoapps/courseware/features/courseware.feature b/lms/djangoapps/courseware/features/courseware.feature index 279e5732c9..14e7786fc9 100644 --- a/lms/djangoapps/courseware/features/courseware.feature +++ b/lms/djangoapps/courseware/features/courseware.feature @@ -4,7 +4,7 @@ Feature: View the Courseware Tab I want to view the info on the courseware tab Scenario: I can get to the courseware tab when logged in - Given I am registered for a course + Given I am registered for the course "MITx/6.002x/2013_Spring" And I log in And I click on View Courseware When I click on the "Courseware" tab diff --git a/lms/djangoapps/courseware/features/high-level-tabs.feature b/lms/djangoapps/courseware/features/high-level-tabs.feature index 2e9c4f1886..354376b154 100644 --- a/lms/djangoapps/courseware/features/high-level-tabs.feature +++ b/lms/djangoapps/courseware/features/high-level-tabs.feature @@ -8,7 +8,7 @@ Feature: All the high level tabs should work # TODO: break this apart so that if one fails the others # will still run Scenario: A student can see all tabs of the course - Given I am registered for a course + Given I am registered for the course "MITx/6.002x/2013_Spring" And I log in And I click on View Courseware When I click on the "Courseware" tab diff --git a/lms/djangoapps/courseware/features/problems.feature b/lms/djangoapps/courseware/features/problems.feature new file mode 100644 index 0000000000..cc459fa35f --- /dev/null +++ b/lms/djangoapps/courseware/features/problems.feature @@ -0,0 +1,53 @@ +Feature: Answer choice problems + As a student in an edX course + In order to test my understanding of the material + I want to answer choice based problems + + Scenario: I can answer a problem correctly + Given I am viewing a "" problem + When I answer a "" problem "correctly" + Then My "" answer is marked "correct" + + Examples: + | ProblemType | + | drop down | + | multiple choice | + | checkbox | + + Scenario: I can answer a problem incorrectly + Given I am viewing a "" problem + When I answer a "" problem "incorrectly" + Then My "" answer is marked "incorrect" + + Examples: + | ProblemType | + | drop down | + | multiple choice | + | checkbox | + + Scenario: I can submit a blank answer + Given I am viewing a "" problem + When I check a problem + Then My "" answer is marked "incorrect" + + Examples: + | ProblemType | + | drop down | + | multiple choice | + | checkbox | + + + Scenario: I can reset a problem + Given I am viewing a "" problem + And I answer a "" problem "ly" + When I reset the problem + Then My "" answer is marked "unanswered" + + Examples: + | ProblemType | Correctness | + | drop down | correct | + | drop down | incorrect | + | multiple choice | correct | + | multiple choice | incorrect | + | checkbox | correct | + | checkbox | incorrect | diff --git a/lms/djangoapps/courseware/features/problems.py b/lms/djangoapps/courseware/features/problems.py new file mode 100644 index 0000000000..4758e16b8d --- /dev/null +++ b/lms/djangoapps/courseware/features/problems.py @@ -0,0 +1,79 @@ +from lettuce import world, step +from lettuce.django import django_url +from selenium.webdriver.support.ui import Select +from common import i_am_registered_for_the_course + +problem_urls = { 'drop down': '/courses/edX/model_course/2013_Spring/courseware/Problem_Components/Drop_Down_Problems', + 'multiple choice': '/courses/edX/model_course/2013_Spring/courseware/Problem_Components/Multiple_Choice_Problems', + 'checkbox': '/courses/edX/model_course/2013_Spring/courseware/Problem_Components/Checkbox_Problems', } + +@step(u'I am viewing a "([^"]*)" problem') +def view_problem(step, problem_type): + i_am_registered_for_the_course(step, 'edX/model_course/2013_Spring') + url = django_url(problem_urls[problem_type]) + world.browser.visit(url) + +@step(u'I answer a "([^"]*)" problem "([^"]*)ly"') +def answer_problem(step, problem_type, correctness): + assert(correctness in ['correct', 'incorrect']) + + if problem_type == "drop down": + select_name = "input_i4x-edX-model_course-problem-Drop_Down_Problem_2_1" + option_text = 'Option 2' if correctness == 'correct' else 'Option 3' + world.browser.select(select_name, option_text) + + elif problem_type == "multiple choice": + if correctness == 'correct': + world.browser.find_by_css("#input_i4x-edX-model_course-problem-Multiple_Choice_Problem_2_1_choice_choice_3").check() + else: + world.browser.find_by_css("#input_i4x-edX-model_course-problem-Multiple_Choice_Problem_2_1_choice_choice_2").check() + + elif problem_type == "checkbox": + if correctness == 'correct': + world.browser.find_by_css('#input_i4x-edX-model_course-problem-Checkbox_Problem_2_1_choice_0').check() + world.browser.find_by_css('#input_i4x-edX-model_course-problem-Checkbox_Problem_2_1_choice_2').check() + else: + world.browser.find_by_css('#input_i4x-edX-model_course-problem-Checkbox_Problem_2_1_choice_3').check() + + check_problem(step) + +@step(u'I check a problem') +def check_problem(step): + world.browser.find_by_css("input.check").click() + +@step(u'I reset the problem') +def reset_problem(step): + world.browser.find_by_css('input.reset').click() + +@step(u'My "([^"]*)" answer is marked "([^"]*)"') +def assert_answer_mark(step, problem_type, correctness): + assert(correctness in ['correct', 'incorrect', 'unanswered']) + + if problem_type == "multiple choice": + if correctness == 'unanswered': + mark_classes = ['.choicegroup_correct', '.choicegroup_incorrect', + '.correct', '.incorrect'] + for css in mark_classes: + assert(world.browser.is_element_not_present_by_css(css)) + + else: + if correctness == 'correct': + mark_class = '.choicegroup_correct' + assert(world.browser.is_element_present_by_css(mark_class, wait_time=4)) + + else: + # Two ways to be marked incorrect: either applying a + # class to the label (marking a particular option) + # or applying a class to a span (marking the whole problem incorrect) + mark_classes = ['.choicegroup_incorrect', '.incorrect'] + assert(world.browser.is_element_present_by_css(mark_classes[0], wait_time=4) or + world.browser.is_element_present_by_css(mark_classes[1], wait_time=4)) + + else: + if correctness == 'unanswered': + assert(world.browser.is_element_not_present_by_css('.correct')) + assert(world.browser.is_element_not_present_by_css('.incorrect')) + + else: + mark_class = '.correct' if correctness == 'correct' else '.incorrect' + assert(world.browser.is_element_present_by_css(mark_class, wait_time=4)) diff --git a/lms/djangoapps/courseware/features/registration.feature b/lms/djangoapps/courseware/features/registration.feature index d9b588534b..890beec1d8 100644 --- a/lms/djangoapps/courseware/features/registration.feature +++ b/lms/djangoapps/courseware/features/registration.feature @@ -6,11 +6,11 @@ Feature: Register for a course Scenario: I can register for a course Given I am logged in And I visit the courses page - When I register for the course numbered "6.002x" + When I register for the course "MITx/6.002x/2013_Spring" Then I should see the course numbered "6.002x" in my dashboard Scenario: I can unregister for a course - Given I am registered for a course + Given I am registered for the course "MITx/6.002x/2013_Spring" And I visit the dashboard When I click the link with the text "Unregister" And I press the "Unregister" button in the Unenroll dialog diff --git a/lms/djangoapps/courseware/features/registration.py b/lms/djangoapps/courseware/features/registration.py index f585136412..5535319f15 100644 --- a/lms/djangoapps/courseware/features/registration.py +++ b/lms/djangoapps/courseware/features/registration.py @@ -1,12 +1,9 @@ from lettuce import world, step +from lettuce.django import django_url - -@step('I register for the course numbered "([^"]*)"$') -def i_register_for_the_course(step, course): - courses_section = world.browser.find_by_css('section.courses') - course_link_css = 'article[id*="%s"] > div' % course - course_link = courses_section.find_by_css(course_link_css).first - course_link.click() +@step('I register for the course "([^"]*)"$') +def i_register_for_the_course(step, course_id): + world.browser.visit(django_url('courses/%s/about' % course_id)) intro_section = world.browser.find_by_css('section.intro') register_link = intro_section.find_by_css('a.register')