diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 0acc355ed9..437000d8ad 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -555,6 +555,8 @@ class XModuleMixin(XModuleFields, XBlockMixin): # Skip rebinding if we're already bound a user, and it's this user. if self.scope_ids.user_id is not None and user_id == self.scope_ids.user_id: + if getattr(xmodule_runtime, 'position', None): + self.position = xmodule_runtime.position # update the position of the tab return # If we are switching users mid-request, save the data from the old user. diff --git a/common/test/acceptance/pages/lms/courseware.py b/common/test/acceptance/pages/lms/courseware.py index b5c835a398..3ab89ade1f 100644 --- a/common/test/acceptance/pages/lms/courseware.py +++ b/common/test/acceptance/pages/lms/courseware.py @@ -87,3 +87,28 @@ class CoursewarePage(CoursePage): return False return True + + def get_active_subsection_url(self): + """ + return the url of the active subsection in the left nav + """ + return self.q(css='.chapter ul li.active a').attrs('href')[0] + + +class CoursewareSequentialTabPage(CoursePage): + """ + Courseware Sequential page + """ + + def __init__(self, browser, course_id, chapter, subsection, position): + super(CoursewareSequentialTabPage, self).__init__(browser, course_id) + self.url_path = "courseware/{}/{}/{}".format(chapter, subsection, position) + + def is_browser_on_page(self): + return self.q(css='nav.sequence-list-wrapper').present + + def get_selected_tab_content(self): + """ + return the body of the sequential currently selected + """ + return self.q(css='#seq_content .xblock').text[0] diff --git a/common/test/acceptance/tests/lms/test_lms_courseware.py b/common/test/acceptance/tests/lms/test_lms_courseware.py index efc6883ca9..f9cc0931a3 100644 --- a/common/test/acceptance/tests/lms/test_lms_courseware.py +++ b/common/test/acceptance/tests/lms/test_lms_courseware.py @@ -7,7 +7,8 @@ import time from ..helpers import UniqueCourseTest from ...pages.studio.auto_auth import AutoAuthPage from ...pages.studio.overview import CourseOutlinePage -from ...pages.lms.courseware import CoursewarePage +from ...pages.lms.courseware import CoursewarePage, CoursewareSequentialTabPage +from ...pages.lms.course_nav import CourseNavPage from ...pages.lms.problem import ProblemPage from ...pages.common.logout import LogoutPage from ...fixtures.course import CourseFixture, XBlockFixtureDesc @@ -104,6 +105,95 @@ class CoursewareTest(UniqueCourseTest): # Visit courseware as a student. self.courseware_page.visit() - # Problem name should be "TEST PROBLEM 2". self.assertEqual(self.problem_page.problem_name, 'TEST PROBLEM 2') + + +class CoursewareMultipleVerticalsTest(UniqueCourseTest): + """ + Test courseware with multiple verticals + """ + USERNAME = "STUDENT_TESTER" + EMAIL = "student101@example.com" + + def setUp(self): + super(CoursewareMultipleVerticalsTest, 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_children( + XBlockFixtureDesc('chapter', 'Test Section 1').add_children( + XBlockFixtureDesc('sequential', 'Test Subsection 1').add_children( + XBlockFixtureDesc('problem', 'Test Problem 1', data='problem 1 dummy body'), + XBlockFixtureDesc('html', 'html 1', data="html 1 dummy body"), + XBlockFixtureDesc('problem', 'Test Problem 2', data="problem 2 dummy body"), + XBlockFixtureDesc('html', 'html 2', data="html 2 dummy body"), + ), + XBlockFixtureDesc('sequential', 'Test Subsection 2'), + ), + ).install() + + # Auto-auth register for the course. + AutoAuthPage(self.browser, username=self.USERNAME, email=self.EMAIL, + course_id=self.course_id, staff=False).visit() + self.courseware_page.visit() + self.course_nav = CourseNavPage(self.browser) + + def test_tab_position(self): + # test that using the position in the url direct to correct tab in courseware + self.course_nav.go_to_section('Test Section 1', 'Test Subsection 1') + subsection_url = self.courseware_page.get_active_subsection_url() + url_part_list = subsection_url.split('/') + self.assertEqual(len(url_part_list), 9) + + course_id = url_part_list[4] + chapter_id = url_part_list[-3] + subsection_id = url_part_list[-2] + problem1_page = CoursewareSequentialTabPage( + self.browser, + course_id=course_id, + chapter=chapter_id, + subsection=subsection_id, + position=1 + ).visit() + self.assertIn('problem 1 dummy body', problem1_page.get_selected_tab_content()) + + html1_page = CoursewareSequentialTabPage( + self.browser, + course_id=course_id, + chapter=chapter_id, + subsection=subsection_id, + position=2 + ).visit() + self.assertIn('html 1 dummy body', html1_page.get_selected_tab_content()) + + problem2_page = CoursewareSequentialTabPage( + self.browser, + course_id=course_id, + chapter=chapter_id, + subsection=subsection_id, + position=3 + ).visit() + self.assertIn('problem 2 dummy body', problem2_page.get_selected_tab_content()) + + html2_page = CoursewareSequentialTabPage( + self.browser, + course_id=course_id, + chapter=chapter_id, + subsection=subsection_id, + position=4 + ).visit() + self.assertIn('html 2 dummy body', html2_page.get_selected_tab_content())