diff --git a/common/test/acceptance/pages/lms/course_nav.py b/common/test/acceptance/pages/lms/course_nav.py
index a7bde281a7..36b5171240 100644
--- a/common/test/acceptance/pages/lms/course_nav.py
+++ b/common/test/acceptance/pages/lms/course_nav.py
@@ -82,7 +82,7 @@ class CourseNavPage(PageObject):
# Click the section to ensure it's open (no harm in clicking twice if it's already open)
# Add one to convert from list index to CSS index
- section_css = 'nav>div.chapter:nth-of-type({0})>h3>a'.format(sec_index + 1)
+ section_css = 'nav>div.chapter:nth-of-type({0})'.format(sec_index + 1)
self.q(css=section_css).first.click()
# Get the subsection by index
@@ -94,7 +94,7 @@ class CourseNavPage(PageObject):
return
# Convert list indices (start at zero) to CSS indices (start at 1)
- subsection_css = "nav>div.chapter:nth-of-type({0})>ul>li:nth-of-type({1})>a".format(
+ subsection_css = "nav>div.chapter-content-container:nth-of-type({0})>div>ol>li:nth-of-type({1})>a".format(
sec_index + 1, subsec_index + 1
)
@@ -130,7 +130,7 @@ class CourseNavPage(PageObject):
"""
Return a list of all section titles on the page.
"""
- chapter_css = 'nav > div.chapter > h3 > a'
+ chapter_css = 'nav > button.chapter > h3'
return self.q(css=chapter_css).map(lambda el: el.text.strip()).results
def _subsection_titles(self, section_index):
@@ -140,7 +140,9 @@ class CourseNavPage(PageObject):
"""
# Retrieve the subsection title for the section
# Add one to the list index to get the CSS index, which starts at one
- subsection_css = 'nav>div.chapter:nth-of-type({0})>ul>li>a>p:nth-of-type(1)'.format(section_index)
+ subsection_css = 'nav>.chapter-content-container:nth-of-type({0})>div>ol>li>a>p:nth-of-type(1)'.format(
+ section_index
+ )
# If the element is visible, we can get its text directly
# Otherwise, we need to get the HTML
@@ -171,8 +173,8 @@ class CourseNavPage(PageObject):
That's true right after we click the section/subsection, but not true in general
(the user could go to a section, then expand another tab).
"""
- current_section_list = self.q(css='nav>div.chapter.is-open>h3>a').text
- current_subsection_list = self.q(css='nav>div.chapter.is-open li.active>a>p').text
+ current_section_list = self.q(css='nav>button.chapter.is-open>h3').text
+ current_subsection_list = self.q(css='nav div.chapter-content-container ol li.active>a>p').text
if len(current_section_list) == 0:
self.warning("Could not find the current section")
diff --git a/common/test/acceptance/pages/lms/courseware.py b/common/test/acceptance/pages/lms/courseware.py
index bb842682d8..292917f3fb 100644
--- a/common/test/acceptance/pages/lms/courseware.py
+++ b/common/test/acceptance/pages/lms/courseware.py
@@ -14,7 +14,7 @@ class CoursewarePage(CoursePage):
url_path = "courseware/"
xblock_component_selector = '.vert .xblock'
section_selector = '.chapter'
- subsection_selector = '.chapter ul li'
+ subsection_selector = '.chapter-content-container ol li'
def is_browser_on_page(self):
return self.q(css='body.courseware').present
@@ -102,7 +102,7 @@ class CoursewarePage(CoursePage):
"""
return the url of the active subsection in the left nav
"""
- return self.q(css='.chapter ul li.active a').attrs('href')[0]
+ return self.q(css='.chapter-content-container ol li.active a').attrs('href')[0]
@property
def can_start_proctored_exam(self):
diff --git a/common/test/acceptance/tests/lms/test_lms.py b/common/test/acceptance/tests/lms/test_lms.py
index ca0a6a260e..8eae4bbdc1 100644
--- a/common/test/acceptance/tests/lms/test_lms.py
+++ b/common/test/acceptance/tests/lms/test_lms.py
@@ -1121,7 +1121,7 @@ class EntranceExamTest(UniqueCourseTest):
When I view the courseware that has an entrance exam
Then there should be an "Entrance Exam" chapter.'
"""
- entrance_exam_link_selector = 'div#accordion nav div h3 a'
+ entrance_exam_link_selector = 'div#accordion nav button h3'
# visit courseware page and make sure there is not entrance exam chapter.
self.courseware_page.visit()
self.courseware_page.wait_for_page()
diff --git a/lms/djangoapps/courseware/features/navigation.py b/lms/djangoapps/courseware/features/navigation.py
index 72eb109a7a..1b3613fe07 100644
--- a/lms/djangoapps/courseware/features/navigation.py
+++ b/lms/djangoapps/courseware/features/navigation.py
@@ -92,7 +92,7 @@ def when_i_navigate_to_a_section(step):
world.disable_jquery_animations()
# Open the 2nd section
- world.css_click(css_selector='div.chapter', index=1)
+ world.css_click(css_selector='button.chapter', index=1)
subsection_css = 'a[href*="Test_Subsection_2/"]'
# Click on the subsection to see the content
diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py
index ddb321e4ed..43b9866782 100644
--- a/lms/djangoapps/courseware/module_render.py
+++ b/lms/djangoapps/courseware/module_render.py
@@ -74,6 +74,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.x_module import XModuleDescriptor
from xmodule.mixin import wrap_with_license
from util.json_request import JsonResponse
+from util.model_utils import slugify
from util.sandboxing import can_execute_unsafe_code, get_python_lib_zip
from util import milestones_helpers
from verify_student.services import ReverificationService
@@ -165,6 +166,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
for chapter in chapters:
# Only show required content, if there is required content
# chapter.hide_from_toc is read-only (boo)
+ display_id = slugify(chapter.display_name_with_default)
local_hide_from_toc = False
if required_content:
if unicode(chapter.location) not in required_content:
@@ -246,6 +248,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
sections.append(section_context)
toc_chapters.append({
'display_name': chapter.display_name_with_default,
+ 'display_id': display_id,
'url_name': chapter.url_name,
'sections': sections,
'active': chapter.url_name == active_chapter
diff --git a/lms/djangoapps/courseware/tests/test_entrance_exam.py b/lms/djangoapps/courseware/tests/test_entrance_exam.py
index 636dcc1e3b..cf74d16d6a 100644
--- a/lms/djangoapps/courseware/tests/test_entrance_exam.py
+++ b/lms/djangoapps/courseware/tests/test_entrance_exam.py
@@ -155,7 +155,8 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase):
}
],
'url_name': u'Entrance_Exam_Section_-_Chapter_1',
- 'display_name': u'Entrance Exam Section - Chapter 1'
+ 'display_name': u'Entrance Exam Section - Chapter 1',
+ 'display_id': u'Entrance-Exam-Section---Chapter-1',
}
]
)
@@ -182,19 +183,22 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase):
}
],
'url_name': u'Overview',
- 'display_name': u'Overview'
+ 'display_name': u'Overview',
+ 'display_id': u'Overview'
},
{
'active': False,
'sections': [],
'url_name': u'Week_1',
- 'display_name': u'Week 1'
+ 'display_name': u'Week 1',
+ 'display_id': u'Week-1'
},
{
'active': False,
'sections': [],
'url_name': u'Instructor',
- 'display_name': u'Instructor'
+ 'display_name': u'Instructor',
+ 'display_id': u'Instructor'
},
{
'active': True,
@@ -209,7 +213,8 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase):
}
],
'url_name': u'Entrance_Exam_Section_-_Chapter_1',
- 'display_name': u'Entrance Exam Section - Chapter 1'
+ 'display_name': u'Entrance Exam Section - Chapter 1',
+ 'display_id': u'Entrance-Exam-Section---Chapter-1'
}
]
)
diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_module_render.py
index 8f8849a100..a1dbd47c24 100644
--- a/lms/djangoapps/courseware/tests/test_module_render.py
+++ b/lms/djangoapps/courseware/tests/test_module_render.py
@@ -642,11 +642,11 @@ class TestTOC(ModuleStoreTestCase):
'format': '', 'due': None, 'active': False},
{'url_name': 'video_4f66f493ac8f', 'display_name': 'Video', 'graded': True,
'format': '', 'due': None, 'active': False}],
- 'url_name': 'Overview', 'display_name': u'Overview'},
+ 'url_name': 'Overview', 'display_name': u'Overview', 'display_id': u'Overview'},
{'active': False, 'sections':
[{'url_name': 'toyvideo', 'display_name': 'toyvideo', 'graded': True,
'format': '', 'due': None, 'active': False}],
- 'url_name': 'secret:magic', 'display_name': 'secret:magic'}])
+ 'url_name': 'secret:magic', 'display_name': 'secret:magic', 'display_id': 'secretmagic'}])
course = self.store.get_course(self.toy_course.id, depth=2)
with check_mongo_calls(toc_finds):
@@ -682,11 +682,11 @@ class TestTOC(ModuleStoreTestCase):
'format': '', 'due': None, 'active': False},
{'url_name': 'video_4f66f493ac8f', 'display_name': 'Video', 'graded': True,
'format': '', 'due': None, 'active': False}],
- 'url_name': 'Overview', 'display_name': u'Overview'},
+ 'url_name': 'Overview', 'display_name': u'Overview', 'display_id': u'Overview'},
{'active': False, 'sections':
[{'url_name': 'toyvideo', 'display_name': 'toyvideo', 'graded': True,
'format': '', 'due': None, 'active': False}],
- 'url_name': 'secret:magic', 'display_name': 'secret:magic'}])
+ 'url_name': 'secret:magic', 'display_name': 'secret:magic', 'display_id': 'secretmagic'}])
with check_mongo_calls(toc_finds):
actual = render.toc_for_course(
diff --git a/lms/static/coffee/fixtures/accordion.html b/lms/static/coffee/fixtures/accordion.html
index 148c245c8f..5d5d7f146b 100644
--- a/lms/static/coffee/fixtures/accordion.html
+++ b/lms/static/coffee/fixtures/accordion.html
@@ -2,5 +2,11 @@
+ % endif
+
+
+ % endfor
+
+