class GatingTest(UniqueCourseTest): """ Test gating feature in LMS. """ STAFF_USERNAME = "******" STAFF_EMAIL = "*****@*****.**" STUDENT_USERNAME = "******" STUDENT_EMAIL = "*****@*****.**" shard = 23 def setUp(self): super(GatingTest, self).setUp() self.logout_page = LogoutPage(self.browser) self.course_home_page = CourseHomePage(self.browser, self.course_id) self.courseware_page = CoursewarePage(self.browser, self.course_id) self.studio_course_outline = StudioCourseOutlinePage( self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run']) xml = dedent(""" <problem> <p>What is height of eiffel tower without the antenna?.</p> <multiplechoiceresponse> <choicegroup label="What is height of eiffel tower without the antenna?" type="MultipleChoice"> <choice correct="false">324 meters<choicehint>Antenna is 24 meters high</choicehint></choice> <choice correct="true">300 meters</choice> <choice correct="false">224 meters</choice> <choice correct="false">400 meters</choice> </choicegroup> </multiplechoiceresponse> </problem> """) self.problem1 = XBlockFixtureDesc('problem', 'HEIGHT OF EIFFEL TOWER', data=xml) # Install a course with sections/problems course_fixture = CourseFixture(self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name']) course_fixture.add_advanced_settings({ "enable_subsection_gating": { "value": "true" }, 'enable_proctored_exams': { "value": "true" } }) course_fixture.add_children( XBlockFixtureDesc('chapter', 'Test Section 1').add_children( XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children( self.problem1), XBlockFixtureDesc('sequential', 'Test Subsection 2').add_children( XBlockFixtureDesc( 'problem', 'Test Problem 2')), XBlockFixtureDesc('sequential', 'Test Subsection 3').add_children( XBlockFixtureDesc( 'problem', 'Test Problem 3')), )).install() def _auto_auth(self, username, email, staff): """ Logout and login with given credentials. """ self.logout_page.visit() AutoAuthPage(self.browser, username=username, email=email, course_id=self.course_id, staff=staff).visit() def _setup_prereq(self): """ Make the first subsection a prerequisite """ # Login as staff self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True) # Make the first subsection a prerequisite self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(0) self.studio_course_outline.select_advanced_tab( desired_item='gated_content') self.studio_course_outline.make_gating_prerequisite() def _setup_gated_subsection(self, subsection_index=1): """ Gate the given indexed subsection on the first subsection """ # Login as staff self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True) # Gate the second subsection based on the score achieved in the first subsection self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog( subsection_index) self.studio_course_outline.select_advanced_tab( desired_item='gated_content') self.studio_course_outline.add_prerequisite_to_subsection("80", "") def _fulfill_prerequisite(self): """ Fulfill the prerequisite needed to see gated content """ problem_page = ProblemPage(self.browser) self.assertEqual(problem_page.wait_for_page().problem_name, 'HEIGHT OF EIFFEL TOWER') problem_page.click_choice('choice_1') problem_page.click_submit() def test_subsection_gating_in_studio(self): """ Given that I am a staff member When I visit the course outline page in studio. And open the subsection edit dialog Then I can view all settings related to Gating And update those settings to gate a subsection """ self._setup_prereq() # Assert settings are displayed correctly for a prerequisite subsection self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(0) self.studio_course_outline.select_advanced_tab( desired_item='gated_content') self.assertTrue(self.studio_course_outline. gating_prerequisite_checkbox_is_visible()) self.assertTrue(self.studio_course_outline. gating_prerequisite_checkbox_is_checked()) self.assertFalse(self.studio_course_outline. gating_prerequisites_dropdown_is_visible()) self.assertFalse(self.studio_course_outline. gating_prerequisite_min_score_is_visible()) self._setup_gated_subsection() # Assert settings are displayed correctly for a gated subsection self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(1) self.studio_course_outline.select_advanced_tab( desired_item='gated_content') self.assertTrue(self.studio_course_outline. gating_prerequisite_checkbox_is_visible()) self.assertTrue(self.studio_course_outline. gating_prerequisites_dropdown_is_visible()) self.assertTrue(self.studio_course_outline. gating_prerequisite_min_score_is_visible()) def test_gated_subsection_in_lms_for_student(self): """ Given that I am a student When I visit the LMS Courseware Then I can see a gated subsection The gated subsection should have a lock icon and be in the format: "<Subsection Title> (Prerequisite Required)" When I fulfill the gating Prerequisite Then I can see the gated subsection Now the gated subsection should have an unlock icon and screen readers should read the section as: "<Subsection Title> Unlocked" """ self._setup_prereq() self._setup_gated_subsection() self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False) self.course_home_page.visit() self.assertEqual(self.course_home_page.outline.num_subsections, 3) # Fulfill prerequisite and verify that gated subsection is shown self.courseware_page.visit() self._fulfill_prerequisite() self.course_home_page.visit() self.assertEqual(self.course_home_page.outline.num_subsections, 3) def test_gated_subsection_in_lms_for_staff(self): """ Given that I am a staff member When I visit the LMS Courseware Then I can see all gated subsections Displayed along with notification banners Then if I masquerade as a student Then I can see a gated subsection The gated subsection should have a lock icon and be in the format: "<Subsection Title> (Prerequisite Required)" """ self._setup_prereq() self._setup_gated_subsection() self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True) self.course_home_page.visit() self.assertEqual(self.course_home_page.preview.staff_view_mode, 'Staff') self.assertEqual(self.course_home_page.outline.num_subsections, 3) # Click on gated section and check for banner self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2') self.courseware_page.wait_for_page() self.assertTrue(self.courseware_page.has_banner()) self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1') self.courseware_page.wait_for_page() self.course_home_page.visit() self.course_home_page.preview.set_staff_view_mode('Learner') self.course_home_page.wait_for_page() self.assertEqual(self.course_home_page.outline.num_subsections, 3) self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1') self.courseware_page.wait_for_page() # banner displayed informing section is a prereq self.assertTrue(self.courseware_page.has_banner()) def test_gated_banner_before_special_exam(self): """ When a subsection with a prereq is a special exam, show the gating banner before starting the special exam. Setup the course with a subsection having pre-req Subsection with pre-req is a special exam Go the LMS course outline page Click the special exam subsection The gated banner asking for completing prereqs should be visible Go to the required subsection Fulfill the requirements Visit the special exam subsection again The gated banner is not visible anymore and user can start the special exam """ self._setup_prereq() # Gating subsection 1 and making it a timed exam self._setup_gated_subsection() self.studio_course_outline.open_subsection_settings_dialog(1) self.studio_course_outline.select_advanced_tab() self.studio_course_outline.make_exam_timed() # Gating subsection 2 and making it a proctored exam self._setup_gated_subsection(2) self.studio_course_outline.open_subsection_settings_dialog(2) self.studio_course_outline.select_advanced_tab() self.studio_course_outline.make_exam_proctored() self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False) self.course_home_page.visit() # Test gating banner before starting timed exam self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2') self.assertTrue(self.courseware_page.is_gating_banner_visible()) # Test gating banner before proctored exams self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 3') self.assertTrue(self.courseware_page.is_gating_banner_visible()) # Fulfill requirements self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1') self._fulfill_prerequisite() # Banner is not visible anymore on timed exam sub-section self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2') self.assertFalse(self.courseware_page.is_gating_banner_visible()) # Banner is not visible on proctored exam subsection self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 3') self.assertFalse(self.courseware_page.is_gating_banner_visible())
class ProctoredExamTest(UniqueCourseTest): """ Test courseware. """ USERNAME = "******" EMAIL = "*****@*****.**" def setUp(self): super(ProctoredExamTest, self).setUp() self.courseware_page = CoursewarePage(self.browser, self.course_id) self.course_outline = CourseOutlinePage( self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run'] ) # Install a course with sections/problems, tabs, updates, and handouts course_fix = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'] ) course_fix.add_advanced_settings({ "enable_proctored_exams": {"value": "true"} }) course_fix.add_children( XBlockFixtureDesc('chapter', 'Test Section 1').add_children( XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children( XBlockFixtureDesc('problem', 'Test Problem 1') ) ) ).install() self.track_selection_page = TrackSelectionPage(self.browser, self.course_id) self.payment_and_verification_flow = PaymentAndVerificationFlow(self.browser, self.course_id) self.immediate_verification_page = PaymentAndVerificationFlow( self.browser, self.course_id, entry_point='verify-now' ) self.upgrade_page = PaymentAndVerificationFlow(self.browser, self.course_id, entry_point='upgrade') self.fake_payment_page = FakePaymentPage(self.browser, self.course_id) self.dashboard_page = DashboardPage(self.browser) self.problem_page = ProblemPage(self.browser) # Add a verified mode to the course ModeCreationPage( self.browser, self.course_id, mode_slug=u'verified', mode_display_name=u'Verified Certificate', min_price=10, suggested_prices='10,20' ).visit() # Auto-auth register for the course. self._auto_auth(self.USERNAME, self.EMAIL, False) def _auto_auth(self, username, email, staff): """ Logout and login with given credentials. """ AutoAuthPage(self.browser, username=username, email=email, course_id=self.course_id, staff=staff).visit() def _login_as_a_verified_user(self): """ login as a verififed user """ self._auto_auth(self.USERNAME, self.EMAIL, False) # the track selection page cannot be visited. see the other tests to see if any prereq is there. # Navigate to the track selection page self.track_selection_page.visit() # Enter the payment and verification flow by choosing to enroll as verified self.track_selection_page.enroll('verified') # Proceed to the fake payment page self.payment_and_verification_flow.proceed_to_payment() # Submit payment self.fake_payment_page.submit_payment() def test_can_create_proctored_exam_in_studio(self): """ Given that I am a staff member When I visit the course outline page in studio. And open the subsection edit dialog Then I can view all settings related to Proctored and timed exams """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.assertTrue(self.course_outline.proctoring_items_are_displayed()) def test_proctored_exam_flow(self): """ Given that I am a staff member on the exam settings section select advanced settings tab When I Make the exam proctored. And I login as a verified student. And visit the courseware as a verified student. Then I can see an option to take the exam as a proctored exam. """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.course_outline.select_advanced_tab() self.course_outline.make_exam_proctored() LogoutPage(self.browser).visit() self._login_as_a_verified_user() self.courseware_page.visit() self.assertTrue(self.courseware_page.can_start_proctored_exam) def _setup_and_take_timed_exam(self, hide_after_due=False): """ Helper to perform the common action "set up a timed exam as staff, then take it as student" """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.course_outline.select_advanced_tab() self.course_outline.make_exam_timed(hide_after_due=hide_after_due) LogoutPage(self.browser).visit() self._login_as_a_verified_user() self.courseware_page.visit() self.courseware_page.start_timed_exam() self.assertTrue(self.courseware_page.is_timer_bar_present) self.courseware_page.stop_timed_exam() self.assertTrue(self.courseware_page.has_submitted_exam_message()) LogoutPage(self.browser).visit() @ddt.data(True, False) def test_timed_exam_flow(self, hide_after_due): """ Given that I am a staff member on the exam settings section select advanced settings tab When I Make the exam timed. And I login as a verified student. And visit the courseware as a verified student. And I start the timed exam Then I am taken to the exam with a timer bar showing When I finish the exam Then I see the exam submitted dialog in place of the exam When I log back into studio as a staff member And change the problem's due date to be in the past And log back in as the original verified student Then I see the exam or message in accordance with the hide_after_due setting """ self._setup_and_take_timed_exam(hide_after_due) LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() last_week = (datetime.today() - timedelta(days=7)).strftime("%m/%d/%Y") self.course_outline.change_problem_due_date(last_week) LogoutPage(self.browser).visit() self._auto_auth(self.USERNAME, self.EMAIL, False) self.courseware_page.visit() self.assertEqual(self.courseware_page.has_submitted_exam_message(), hide_after_due) def test_masquerade_visibility_override(self): """ Given that a timed exam problem exists in the course And a student has taken that exam And that exam is hidden to the student And I am a staff user masquerading as the student Then I should be able to see the exam content """ self._setup_and_take_timed_exam() LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.courseware_page.visit() staff_page = StaffPage(self.browser, self.course_id) self.assertEqual(staff_page.staff_view_mode, 'Staff') staff_page.set_staff_view_mode_specific_student(self.USERNAME) self.assertFalse(self.courseware_page.has_submitted_exam_message()) def test_field_visiblity_with_all_exam_types(self): """ Given that I am a staff member And I have visited the course outline page in studio. And the subsection edit dialog is open select advanced settings tab For each of None, Timed, Proctored, and Practice exam types The time allotted and review rules fields have proper visibility None: False, False Timed: True, False Proctored: True, True Practice: True, False """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.course_outline.select_advanced_tab() self.course_outline.select_none_exam() self.assertFalse(self.course_outline.time_allotted_field_visible()) self.assertFalse(self.course_outline.exam_review_rules_field_visible()) self.course_outline.select_timed_exam() self.assertTrue(self.course_outline.time_allotted_field_visible()) self.assertFalse(self.course_outline.exam_review_rules_field_visible()) self.course_outline.select_proctored_exam() self.assertTrue(self.course_outline.time_allotted_field_visible()) self.assertTrue(self.course_outline.exam_review_rules_field_visible()) self.course_outline.select_practice_exam() self.assertTrue(self.course_outline.time_allotted_field_visible()) self.assertFalse(self.course_outline.exam_review_rules_field_visible())
class ProctoredExamTest(UniqueCourseTest): """ Test courseware. """ USERNAME = "******" EMAIL = "*****@*****.**" def setUp(self): super(ProctoredExamTest, self).setUp() self.courseware_page = CoursewarePage(self.browser, self.course_id) self.course_outline = CourseOutlinePage(self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run']) # Install a course with sections/problems, tabs, updates, and handouts course_fix = CourseFixture(self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name']) course_fix.add_advanced_settings( {"enable_proctored_exams": { "value": "true" }}) course_fix.add_children( XBlockFixtureDesc('chapter', 'Test Section 1').add_children( XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children( XBlockFixtureDesc( 'problem', 'Test Problem 1')))).install() self.track_selection_page = TrackSelectionPage(self.browser, self.course_id) self.payment_and_verification_flow = PaymentAndVerificationFlow( self.browser, self.course_id) self.immediate_verification_page = PaymentAndVerificationFlow( self.browser, self.course_id, entry_point='verify-now') self.upgrade_page = PaymentAndVerificationFlow(self.browser, self.course_id, entry_point='upgrade') self.fake_payment_page = FakePaymentPage(self.browser, self.course_id) self.dashboard_page = DashboardPage(self.browser) self.problem_page = ProblemPage(self.browser) # Add a verified mode to the course ModeCreationPage(self.browser, self.course_id, mode_slug=u'verified', mode_display_name=u'Verified Certificate', min_price=10, suggested_prices='10,20').visit() # Auto-auth register for the course. self._auto_auth(self.USERNAME, self.EMAIL, False) def _auto_auth(self, username, email, staff): """ Logout and login with given credentials. """ AutoAuthPage(self.browser, username=username, email=email, course_id=self.course_id, staff=staff).visit() def _login_as_a_verified_user(self): """ login as a verififed user """ self._auto_auth(self.USERNAME, self.EMAIL, False) # the track selection page cannot be visited. see the other tests to see if any prereq is there. # Navigate to the track selection page self.track_selection_page.visit() # Enter the payment and verification flow by choosing to enroll as verified self.track_selection_page.enroll('verified') # Proceed to the fake payment page self.payment_and_verification_flow.proceed_to_payment() # Submit payment self.fake_payment_page.submit_payment() def test_can_create_proctored_exam_in_studio(self): """ Given that I am a staff member When I visit the course outline page in studio. And open the subsection edit dialog Then I can view all settings related to Proctored and timed exams """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.assertTrue(self.course_outline.proctoring_items_are_displayed()) def test_proctored_exam_flow(self): """ Given that I am a staff member on the exam settings section select advanced settings tab When I Make the exam proctored. And I login as a verified student. And visit the courseware as a verified student. Then I can see an option to take the exam as a proctored exam. """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.course_outline.select_advanced_tab() self.course_outline.make_exam_proctored() LogoutPage(self.browser).visit() self._login_as_a_verified_user() self.courseware_page.visit() self.assertTrue(self.courseware_page.can_start_proctored_exam) def _setup_and_take_timed_exam(self, hide_after_due=False): """ Helper to perform the common action "set up a timed exam as staff, then take it as student" """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.course_outline.select_advanced_tab() self.course_outline.make_exam_timed(hide_after_due=hide_after_due) LogoutPage(self.browser).visit() self._login_as_a_verified_user() self.courseware_page.visit() self.courseware_page.start_timed_exam() self.assertTrue(self.courseware_page.is_timer_bar_present) self.courseware_page.stop_timed_exam() self.assertTrue(self.courseware_page.has_submitted_exam_message()) LogoutPage(self.browser).visit() @ddt.data(True, False) def test_timed_exam_flow(self, hide_after_due): """ Given that I am a staff member on the exam settings section select advanced settings tab When I Make the exam timed. And I login as a verified student. And visit the courseware as a verified student. And I start the timed exam Then I am taken to the exam with a timer bar showing When I finish the exam Then I see the exam submitted dialog in place of the exam When I log back into studio as a staff member And change the problem's due date to be in the past And log back in as the original verified student Then I see the exam or message in accordance with the hide_after_due setting """ self._setup_and_take_timed_exam(hide_after_due) LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() last_week = (datetime.today() - timedelta(days=7)).strftime("%m/%d/%Y") self.course_outline.change_problem_due_date(last_week) LogoutPage(self.browser).visit() self._auto_auth(self.USERNAME, self.EMAIL, False) self.courseware_page.visit() self.assertEqual(self.courseware_page.has_submitted_exam_message(), hide_after_due) def test_masquerade_visibility_override(self): """ Given that a timed exam problem exists in the course And a student has taken that exam And that exam is hidden to the student And I am a staff user masquerading as the student Then I should be able to see the exam content """ self._setup_and_take_timed_exam() LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.courseware_page.visit() staff_page = StaffPage(self.browser, self.course_id) self.assertEqual(staff_page.staff_view_mode, 'Staff') staff_page.set_staff_view_mode_specific_student(self.USERNAME) self.assertFalse(self.courseware_page.has_submitted_exam_message()) def test_field_visiblity_with_all_exam_types(self): """ Given that I am a staff member And I have visited the course outline page in studio. And the subsection edit dialog is open select advanced settings tab For each of None, Timed, Proctored, and Practice exam types The time allotted and review rules fields have proper visibility None: False, False Timed: True, False Proctored: True, True Practice: True, False """ LogoutPage(self.browser).visit() self._auto_auth("STAFF_TESTER", "*****@*****.**", True) self.course_outline.visit() self.course_outline.open_subsection_settings_dialog() self.course_outline.select_advanced_tab() self.course_outline.select_none_exam() self.assertFalse(self.course_outline.time_allotted_field_visible()) self.assertFalse(self.course_outline.exam_review_rules_field_visible()) self.course_outline.select_timed_exam() self.assertTrue(self.course_outline.time_allotted_field_visible()) self.assertFalse(self.course_outline.exam_review_rules_field_visible()) self.course_outline.select_proctored_exam() self.assertTrue(self.course_outline.time_allotted_field_visible()) self.assertTrue(self.course_outline.exam_review_rules_field_visible()) self.course_outline.select_practice_exam() self.assertTrue(self.course_outline.time_allotted_field_visible()) self.assertFalse(self.course_outline.exam_review_rules_field_visible())
class GatingTest(UniqueCourseTest): """ Test gating feature in LMS. """ STAFF_USERNAME = "******" STAFF_EMAIL = "*****@*****.**" STUDENT_USERNAME = "******" STUDENT_EMAIL = "*****@*****.**" shard = 23 def setUp(self): super(GatingTest, self).setUp() self.logout_page = LogoutPage(self.browser) self.course_home_page = CourseHomePage(self.browser, self.course_id) self.courseware_page = CoursewarePage(self.browser, self.course_id) self.studio_course_outline = StudioCourseOutlinePage( self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run'] ) xml = dedent(""" <problem> <p>What is height of eiffel tower without the antenna?.</p> <multiplechoiceresponse> <choicegroup label="What is height of eiffel tower without the antenna?" type="MultipleChoice"> <choice correct="false">324 meters<choicehint>Antenna is 24 meters high</choicehint></choice> <choice correct="true">300 meters</choice> <choice correct="false">224 meters</choice> <choice correct="false">400 meters</choice> </choicegroup> </multiplechoiceresponse> </problem> """) self.problem1 = XBlockFixtureDesc('problem', 'HEIGHT OF EIFFEL TOWER', data=xml) # Install a course with sections/problems course_fixture = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'] ) course_fixture.add_advanced_settings({ "enable_subsection_gating": {"value": "true"}, 'enable_proctored_exams': {"value": "true"} }) course_fixture.add_children( XBlockFixtureDesc('chapter', 'Test Section 1').add_children( XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children( self.problem1 ), XBlockFixtureDesc('sequential', 'Test Subsection 2').add_children( XBlockFixtureDesc('problem', 'Test Problem 2') ), XBlockFixtureDesc('sequential', 'Test Subsection 3').add_children( XBlockFixtureDesc('problem', 'Test Problem 3') ), ) ).install() def _auto_auth(self, username, email, staff): """ Logout and login with given credentials. """ self.logout_page.visit() AutoAuthPage(self.browser, username=username, email=email, course_id=self.course_id, staff=staff).visit() def _setup_prereq(self): """ Make the first subsection a prerequisite """ # Login as staff self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True) # Make the first subsection a prerequisite self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(0) self.studio_course_outline.select_advanced_tab(desired_item='gated_content') self.studio_course_outline.make_gating_prerequisite() def _setup_gated_subsection(self, subsection_index=1): """ Gate the given indexed subsection on the first subsection """ # Login as staff self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True) # Gate the second subsection based on the score achieved in the first subsection self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(subsection_index) self.studio_course_outline.select_advanced_tab(desired_item='gated_content') self.studio_course_outline.add_prerequisite_to_subsection("80", "") def _fulfill_prerequisite(self): """ Fulfill the prerequisite needed to see gated content """ problem_page = ProblemPage(self.browser) self.assertEqual(problem_page.wait_for_page().problem_name, 'HEIGHT OF EIFFEL TOWER') problem_page.click_choice('choice_1') problem_page.click_submit() def test_subsection_gating_in_studio(self): """ Given that I am a staff member When I visit the course outline page in studio. And open the subsection edit dialog Then I can view all settings related to Gating And update those settings to gate a subsection """ self._setup_prereq() # Assert settings are displayed correctly for a prerequisite subsection self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(0) self.studio_course_outline.select_advanced_tab(desired_item='gated_content') self.assertTrue(self.studio_course_outline.gating_prerequisite_checkbox_is_visible()) self.assertTrue(self.studio_course_outline.gating_prerequisite_checkbox_is_checked()) self.assertFalse(self.studio_course_outline.gating_prerequisites_dropdown_is_visible()) self.assertFalse(self.studio_course_outline.gating_prerequisite_min_score_is_visible()) self._setup_gated_subsection() # Assert settings are displayed correctly for a gated subsection self.studio_course_outline.visit() self.studio_course_outline.open_subsection_settings_dialog(1) self.studio_course_outline.select_advanced_tab(desired_item='gated_content') self.assertTrue(self.studio_course_outline.gating_prerequisite_checkbox_is_visible()) self.assertTrue(self.studio_course_outline.gating_prerequisites_dropdown_is_visible()) self.assertTrue(self.studio_course_outline.gating_prerequisite_min_score_is_visible()) def test_gated_subsection_in_lms_for_student(self): """ Given that I am a student When I visit the LMS Courseware Then I can see a gated subsection The gated subsection should have a lock icon and be in the format: "<Subsection Title> (Prerequisite Required)" When I fulfill the gating Prerequisite Then I can see the gated subsection Now the gated subsection should have an unlock icon and screen readers should read the section as: "<Subsection Title> Unlocked" """ self._setup_prereq() self._setup_gated_subsection() self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False) self.course_home_page.visit() self.assertEqual(self.course_home_page.outline.num_subsections, 3) # Fulfill prerequisite and verify that gated subsection is shown self.courseware_page.visit() self._fulfill_prerequisite() self.course_home_page.visit() self.assertEqual(self.course_home_page.outline.num_subsections, 3) def test_gated_subsection_in_lms_for_staff(self): """ Given that I am a staff member When I visit the LMS Courseware Then I can see all gated subsections Displayed along with notification banners Then if I masquerade as a student Then I can see a gated subsection The gated subsection should have a lock icon and be in the format: "<Subsection Title> (Prerequisite Required)" """ self._setup_prereq() self._setup_gated_subsection() self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True) self.course_home_page.visit() self.assertEqual(self.course_home_page.preview.staff_view_mode, 'Staff') self.assertEqual(self.course_home_page.outline.num_subsections, 3) # Click on gated section and check for banner self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2') self.courseware_page.wait_for_page() self.assertTrue(self.courseware_page.has_banner()) self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1') self.courseware_page.wait_for_page() self.course_home_page.visit() self.course_home_page.preview.set_staff_view_mode('Learner') self.course_home_page.wait_for_page() self.assertEqual(self.course_home_page.outline.num_subsections, 3) self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1') self.courseware_page.wait_for_page() # banner displayed informing section is a prereq self.assertTrue(self.courseware_page.has_banner()) def test_gated_banner_before_special_exam(self): """ When a subsection with a prereq is a special exam, show the gating banner before starting the special exam. Setup the course with a subsection having pre-req Subsection with pre-req is a special exam Go the LMS course outline page Click the special exam subsection The gated banner asking for completing prereqs should be visible Go to the required subsection Fulfill the requirements Visit the special exam subsection again The gated banner is not visible anymore and user can start the special exam """ self._setup_prereq() # Gating subsection 1 and making it a timed exam self._setup_gated_subsection() self.studio_course_outline.open_subsection_settings_dialog(1) self.studio_course_outline.select_advanced_tab() self.studio_course_outline.make_exam_timed() # Gating subsection 2 and making it a proctored exam self._setup_gated_subsection(2) self.studio_course_outline.open_subsection_settings_dialog(2) self.studio_course_outline.select_advanced_tab() self.studio_course_outline.make_exam_proctored() self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False) self.course_home_page.visit() # Test gating banner before starting timed exam self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2') self.assertTrue(self.courseware_page.is_gating_banner_visible()) # Test gating banner before proctored exams self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 3') self.assertTrue(self.courseware_page.is_gating_banner_visible()) # Fulfill requirements self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1') self._fulfill_prerequisite() # Banner is not visible anymore on timed exam sub-section self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2') self.assertFalse(self.courseware_page.is_gating_banner_visible()) # Banner is not visible on proctored exam subsection self.course_home_page.visit() self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 3') self.assertFalse(self.courseware_page.is_gating_banner_visible())