From 584e7fdafbb514fb236f6cb55d69b56745a615dd Mon Sep 17 00:00:00 2001 From: Robert Raposa Date: Fri, 7 Apr 2017 15:51:22 -0400 Subject: [PATCH] Add graded homework to a11y test of course outline. Includes refactor of course home/course outline smoke test to its own file. --- common/test/acceptance/tests/lms/test_lms.py | 64 +----- .../tests/lms/test_lms_course_home.py | 182 ++++++++++++++++++ .../tests/lms/test_lms_courseware.py | 2 +- 3 files changed, 185 insertions(+), 63 deletions(-) create mode 100644 common/test/acceptance/tests/lms/test_lms_course_home.py diff --git a/common/test/acceptance/tests/lms/test_lms.py b/common/test/acceptance/tests/lms/test_lms.py index 5d3670377f..bc51481aa6 100644 --- a/common/test/acceptance/tests/lms/test_lms.py +++ b/common/test/acceptance/tests/lms/test_lms.py @@ -25,7 +25,6 @@ from common.test.acceptance.pages.common.logout import LogoutPage from common.test.acceptance.pages.lms import BASE_URL from common.test.acceptance.pages.lms.account_settings import AccountSettingsPage from common.test.acceptance.pages.lms.auto_auth import AutoAuthPage -from common.test.acceptance.pages.lms.bookmarks import BookmarksPage from common.test.acceptance.pages.lms.create_mode import ModeCreationPage from common.test.acceptance.pages.lms.course_home import CourseHomePage from common.test.acceptance.pages.lms.course_info import CourseInfoPage @@ -635,6 +634,7 @@ class CourseWikiTest(UniqueCourseTest): children_page.a11y_audit.check_for_accessibility_errors() +@attr(shard=1) class HighLevelTabTest(UniqueCourseTest): """ Tests that verify each of the high-level tabs available within a course. @@ -688,7 +688,6 @@ class HighLevelTabTest(UniqueCourseTest): # Auto-auth register for the course AutoAuthPage(self.browser, course_id=self.course_id).visit() - @attr(shard=1) def test_course_info(self): """ Navigate to the course info page. @@ -706,7 +705,6 @@ class HighLevelTabTest(UniqueCourseTest): self.assertEqual(len(handout_links), 1) self.assertIn('demoPDF.pdf', handout_links[0]) - @attr(shard=1) def test_progress(self): """ Navigate to the progress page. @@ -724,7 +722,6 @@ class HighLevelTabTest(UniqueCourseTest): actual_scores = self.progress_page.scores(CHAPTER, SECTION) self.assertEqual(actual_scores, EXPECTED_SCORES) - @attr(shard=1) def test_static_tab(self): """ Navigate to a static tab (course content) @@ -734,7 +731,6 @@ class HighLevelTabTest(UniqueCourseTest): self.tab_nav.go_to_tab('Test Static Tab') self.assertTrue(self.tab_nav.is_on_tab('Test Static Tab')) - @attr(shard=1) def test_static_tab_with_mathjax(self): """ Navigate to a static tab (course content) @@ -747,7 +743,6 @@ class HighLevelTabTest(UniqueCourseTest): # Verify that Mathjax has rendered self.tab_nav.mathjax_has_rendered() - @attr(shard=1) def test_wiki_tab_first_time(self): """ Navigate to the course wiki tab. When the wiki is accessed for @@ -769,7 +764,6 @@ class HighLevelTabTest(UniqueCourseTest): self.assertEqual(expected_article_name, course_wiki.article_name) # TODO: TNL-6546: This whole function will be able to go away, replaced by test_course_home below. - @attr(shard=1) def test_courseware_nav(self): """ Navigate to a particular unit in the course. @@ -805,13 +799,9 @@ class HighLevelTabTest(UniqueCourseTest): self.courseware_page.nav.go_to_section('Test Section 2', 'Test Subsection 3') self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) - @attr(shard=1) - def test_course_home(self): + def test_course_home_tab(self): """ Navigate to the course home page using the tab. - - Includes smoke test of course outline, courseware page, and breadcrumbs. - """ # TODO: TNL-6546: Use tab navigation and remove course_home_page.visit(). #self.course_info_page.visit() @@ -825,56 +815,6 @@ class HighLevelTabTest(UniqueCourseTest): # Check that the tab lands on the course home page. self.assertTrue(self.course_home_page.is_browser_on_page()) - # Check that the course navigation appears correctly - EXPECTED_SECTIONS = { - 'Test Section': ['Test Subsection'], - 'Test Section 2': ['Test Subsection 2', 'Test Subsection 3'] - } - - actual_sections = self.course_home_page.outline.sections - for section, subsections in EXPECTED_SECTIONS.iteritems(): - self.assertIn(section, actual_sections) - self.assertEqual(actual_sections[section], EXPECTED_SECTIONS[section]) - - # Navigate to a particular section - self.course_home_page.outline.go_to_section('Test Section', 'Test Subsection') - - # Check the sequence items on the courseware page - EXPECTED_ITEMS = ['Test Problem 1', 'Test Problem 2', 'Test HTML'] - - actual_items = self.courseware_page.nav.sequence_items - self.assertEqual(len(actual_items), len(EXPECTED_ITEMS)) - for expected in EXPECTED_ITEMS: - self.assertIn(expected, actual_items) - - # Use outline breadcrumb to get back to course home page. - self.courseware_page.nav.go_to_outline() - - # Navigate to a particular section other than the default landing section. - self.course_home_page.outline.go_to_section('Test Section 2', 'Test Subsection 3') - self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) - - # Verify that we can navigate to the bookmarks page - self.course_home_page.visit() - self.course_home_page.click_bookmarks_button() - bookmarks_page = BookmarksPage(self.browser, self.course_id) - self.assertTrue(bookmarks_page.is_browser_on_page()) - - # Test "Resume Course" button from header - self.course_home_page.visit() - self.course_home_page.resume_course_from_header() - self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) - - # Test "Resume Course" button from within outline - self.course_home_page.visit() - self.course_home_page.outline.resume_course_from_outline() - self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) - - @attr('a11y') - def test_course_home_a11y(self): - self.course_home_page.visit() - self.course_home_page.a11y_audit.check_for_accessibility_errors() - @attr(shard=1) class PDFTextBooksTabTest(UniqueCourseTest): diff --git a/common/test/acceptance/tests/lms/test_lms_course_home.py b/common/test/acceptance/tests/lms/test_lms_course_home.py new file mode 100644 index 0000000000..04f5a347f5 --- /dev/null +++ b/common/test/acceptance/tests/lms/test_lms_course_home.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +""" +End-to-end tests for the LMS that utilize the course home page and course outline. +""" +from contextlib import contextmanager +from nose.plugins.attrib import attr + +from ..helpers import auto_auth, load_data_str, UniqueCourseTest +from ...fixtures.course import CourseFixture, XBlockFixtureDesc +from ...pages.common.logout import LogoutPage +from ...pages.lms.bookmarks import BookmarksPage +from ...pages.lms.course_home import CourseHomePage +from ...pages.lms.courseware import CoursewarePage +from ...pages.studio.overview import CourseOutlinePage as StudioCourseOutlinePage + + +class CourseHomeBaseTest(UniqueCourseTest): + """ + Provides base setup for course home tests. + """ + USERNAME = "STUDENT_TESTER" + EMAIL = "student101@example.com" + + def setUp(self): + """ + Initialize pages and install a course fixture. + """ + super(CourseHomeBaseTest, self).setUp() + + self.course_home_page = CourseHomePage(self.browser, self.course_id) + self.courseware_page = CoursewarePage(self.browser, self.course_id) + + # Install a course with sections and problems + 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('static_tab', 'Test Static Tab', data=r"static tab data with mathjax \(E=mc^2\)"), + XBlockFixtureDesc('chapter', 'Test Section').add_children( + XBlockFixtureDesc('sequential', 'Test Subsection').add_children( + XBlockFixtureDesc('problem', 'Test Problem 1', data=load_data_str('multiple_choice.xml')), + XBlockFixtureDesc('problem', 'Test Problem 2', data=load_data_str('formula_problem.xml')), + XBlockFixtureDesc('html', 'Test HTML'), + ) + ), + XBlockFixtureDesc('chapter', 'Test Section 2').add_children( + XBlockFixtureDesc('sequential', 'Test Subsection 2'), + XBlockFixtureDesc('sequential', 'Test Subsection 3').add_children( + XBlockFixtureDesc('problem', 'Test Problem A', data=load_data_str('multiple_choice.xml')) + ), + ) + ).install() + + # Auto-auth register for the course. + auto_auth(self.browser, self.USERNAME, self.EMAIL, False, self.course_id) + + +class CourseHomeTest(CourseHomeBaseTest): + """ + Tests the course home page with course outline. + """ + + def test_course_home(self): + """ + Smoke test of course outline, breadcrumbs to and from cours outline, and bookmarks. + """ + self.course_home_page.visit() + + # TODO: TNL-6546: Remove unified_course_view. + self.course_home_page.unified_course_view = True + self.courseware_page.nav.unified_course_view = True + + # Check that the tab lands on the course home page. + self.assertTrue(self.course_home_page.is_browser_on_page()) + + # Check that the course navigation appears correctly + EXPECTED_SECTIONS = { + 'Test Section': ['Test Subsection'], + 'Test Section 2': ['Test Subsection 2', 'Test Subsection 3'] + } + + actual_sections = self.course_home_page.outline.sections + for section, subsections in EXPECTED_SECTIONS.iteritems(): + self.assertIn(section, actual_sections) + self.assertEqual(actual_sections[section], EXPECTED_SECTIONS[section]) + + # Navigate to a particular section + self.course_home_page.outline.go_to_section('Test Section', 'Test Subsection') + + # Check the sequence items on the courseware page + EXPECTED_ITEMS = ['Test Problem 1', 'Test Problem 2', 'Test HTML'] + + actual_items = self.courseware_page.nav.sequence_items + self.assertEqual(len(actual_items), len(EXPECTED_ITEMS)) + for expected in EXPECTED_ITEMS: + self.assertIn(expected, actual_items) + + # Use outline breadcrumb to get back to course home page. + self.courseware_page.nav.go_to_outline() + + # Navigate to a particular section other than the default landing section. + self.course_home_page.outline.go_to_section('Test Section 2', 'Test Subsection 3') + self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) + + # Verify that we can navigate to the bookmarks page + self.course_home_page.visit() + self.course_home_page.click_bookmarks_button() + bookmarks_page = BookmarksPage(self.browser, self.course_id) + self.assertTrue(bookmarks_page.is_browser_on_page()) + + # Test "Resume Course" button from header + self.course_home_page.visit() + self.course_home_page.resume_course_from_header() + self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) + + # Test "Resume Course" button from within outline + self.course_home_page.visit() + self.course_home_page.outline.resume_course_from_outline() + self.assertTrue(self.courseware_page.nav.is_on_section('Test Section 2', 'Test Subsection 3')) + + +@attr('a11y') +class CourseHomeA11yTest(CourseHomeBaseTest): + """ + Tests the accessibility of the course home page with course outline. + """ + + def setUp(self): + super(CourseHomeA11yTest, self).setUp() + + self.logout_page = LogoutPage(self.browser) + + self.studio_course_outline = StudioCourseOutlinePage( + self.browser, + self.course_info['org'], + self.course_info['number'], + self.course_info['run'] + ) + + # adds graded assignments to course home for testing course outline a11y + self._set_policy_for_subsection("Homework", 0) + + def test_course_home_a11y(self): + """ + Test the accessibility of the course home page with course outline. + """ + with self._logged_in_session(): + course_home_page = CourseHomePage(self.browser, self.course_id) + course_home_page.visit() + course_home_page.a11y_audit.check_for_accessibility_errors() + + def _set_policy_for_subsection(self, policy, section=0): + """ + Set the grading policy for the first subsection in the specified section. + If a section index is not provided, 0 is assumed. + """ + with self._logged_in_session(staff=True): + self.studio_course_outline.visit() + modal = self.studio_course_outline.section_at(section).subsection_at( + 0).edit() + modal.policy = policy + modal.save() + + @contextmanager + def _logged_in_session(self, staff=False): + """ + Ensure that the user is logged in and out appropriately at the beginning + and end of the current test. + """ + self.logout_page.visit() + try: + if staff: + auto_auth(self.browser, "STAFF_TESTER", "staff101@example.com", True, self.course_id) + else: + auto_auth(self.browser, self.USERNAME, self.EMAIL, False, self.course_id) + yield + finally: + self.logout_page.visit() diff --git a/common/test/acceptance/tests/lms/test_lms_courseware.py b/common/test/acceptance/tests/lms/test_lms_courseware.py index b81aa1f06c..33145ebe80 100644 --- a/common/test/acceptance/tests/lms/test_lms_courseware.py +++ b/common/test/acceptance/tests/lms/test_lms_courseware.py @@ -129,7 +129,7 @@ class CoursewareTest(UniqueCourseTest): @ddt.ddt class ProctoredExamTest(UniqueCourseTest): """ - Test courseware. + Tests for proctored exams. """ USERNAME = "STUDENT_TESTER" EMAIL = "student101@example.com"