From 268c4fa01b0b6ca8d5ea6a273ea4251b8f3c4a2a Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 18 Dec 2013 16:11:02 -0500 Subject: [PATCH] Add acceptance tests of the conditional module [LMS-1639] --- .../courseware/features/conditional.feature | 22 ++++ .../courseware/features/conditional.py | 119 ++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 lms/djangoapps/courseware/features/conditional.feature create mode 100644 lms/djangoapps/courseware/features/conditional.py diff --git a/lms/djangoapps/courseware/features/conditional.feature b/lms/djangoapps/courseware/features/conditional.feature new file mode 100644 index 0000000000..65080f76be --- /dev/null +++ b/lms/djangoapps/courseware/features/conditional.feature @@ -0,0 +1,22 @@ +@shard_2 +Feature: LMS.Conditional Module + As a student, I want to view a Conditional component in the LMS + + Scenario: A Conditional hides content when conditions aren't satisfied + Given that a course has a Conditional conditioned on problem attempted=True + And that the conditioned problem has not been attempted + When I view the conditional + Then the conditional contents are hidden + + Scenario: A Conditional shows content when conditions are satisfied + Given that a course has a Conditional conditioned on problem attempted=True + And that the conditioned problem has been attempted + When I view the conditional + Then the conditional contents are visible + + Scenario: A Conditional containing a Poll is updated when the poll is answered + Given that a course has a Conditional conditioned on poll poll_answer=yes + When I view the conditional + Then the conditional contents are hidden + When I answer the conditioned poll "yes" + Then the conditional contents are visible diff --git a/lms/djangoapps/courseware/features/conditional.py b/lms/djangoapps/courseware/features/conditional.py new file mode 100644 index 0000000000..665cfbcd07 --- /dev/null +++ b/lms/djangoapps/courseware/features/conditional.py @@ -0,0 +1,119 @@ + +from lettuce import world, steps +from nose.tools import assert_in, assert_equals, assert_true + +from common import i_am_registered_for_the_course, visit_scenario_item +from problems_setup import add_problem_to_course, answer_problem + +@steps +class ConditionalSteps(object): + COURSE_NUM = 'test_course' + + def setup_conditional(self, step, condition_type, condition, cond_value): + r'that a course has a Conditional conditioned on (?P\w+) (?P\w+)=(?P\w+)$' + + i_am_registered_for_the_course(step, self.COURSE_NUM) + + world.scenario_dict['VERTICAL'] = world.ItemFactory( + parent_location=world.scenario_dict['SECTION'].location, + category='vertical', + display_name="Test Vertical", + ) + + world.scenario_dict['WRAPPER'] = world.ItemFactory( + parent_location=world.scenario_dict['VERTICAL'].location, + category='wrapper', + display_name="Test Poll Wrapper" + ) + + if condition_type == 'problem': + world.scenario_dict['CONDITION_SOURCE'] = add_problem_to_course(self.COURSE_NUM, 'string') + elif condition_type == 'poll': + world.scenario_dict['CONDITION_SOURCE'] = world.ItemFactory( + parent_location=world.scenario_dict['WRAPPER'].location, + category='poll_question', + display_name='Conditional Poll', + data={ + 'question': 'Is this a good poll?', + 'answers': [ + {'id': 'yes', 'text': 'Yes, of course'}, + {'id': 'no', 'text': 'Of course not!'} + ], + } + ) + else: + raise Exception("Unknown condition type: {!r}".format(condition_type)) + + metadata = { + 'xml_attributes': { + 'sources': world.scenario_dict['CONDITION_SOURCE'].location.url() + } + } + metadata['xml_attributes'][condition] = cond_value + + world.scenario_dict['CONDITIONAL'] = world.ItemFactory( + parent_location=world.scenario_dict['WRAPPER'].location, + category='conditional', + display_name="Test Conditional", + metadata=metadata + ) + + world.ItemFactory( + parent_location=world.scenario_dict['CONDITIONAL'].location, + category='html', + display_name='Conditional Contents', + data='
Hidden Contents

' + ) + + + def setup_problem_attempts(self, step, not_attempted=None): + r'that the conditioned problem has (?Pnot )?been attempted$' + visit_scenario_item('CONDITION_SOURCE') + + if not_attempted is None: + answer_problem(self.COURSE_NUM, 'string', True) + world.css_click("input.check") + + def when_i_view_the_conditional(self, step): + r'I view the conditional$' + visit_scenario_item('CONDITIONAL') + world.wait_for_js_variable_truthy('$(".xblock-student_view[data-type=Conditional]").data("initialized")') + + def check_visibility(self, step, visible): + r'the conditional contents are (?P\w+)$' + world.wait_for_ajax_complete() + + assert_in(visible, ('visible', 'hidden')) + + if visible == 'visible': + world.wait_for_visible('.hidden-contents') + assert_true(world.css_visible('.hidden-contents')) + else: + assert_true(world.is_css_not_present('.hidden-contents')) + + def answer_poll(self, step, answer): + r' I answer the conditioned poll "([^"]*)"$' + visit_scenario_item('CONDITION_SOURCE') + world.wait_for_js_variable_truthy('$(".xblock-student_view[data-type=Poll]").data("initialized")') + world.wait_for_ajax_complete() + + answer_text = [ + poll_answer['text'] + for poll_answer + in world.scenario_dict['CONDITION_SOURCE'].answers + if poll_answer['id'] == answer + ][0] + + text_selector = '.poll_answer .text' + + poll_texts = world.retry_on_exception( + lambda: [elem.text for elem in world.css_find(text_selector)] + ) + + for idx, poll_text in enumerate(poll_texts): + if poll_text == answer_text: + world.css_click(text_selector, index=idx) + return + + +ConditionalSteps() \ No newline at end of file