# -*- coding: utf-8 -*- """ E2E tests for the LMS. """ from unittest import skip from .helpers import UniqueCourseTest, load_data_str from ..pages.lms.auto_auth import AutoAuthPage from ..pages.lms.find_courses import FindCoursesPage from ..pages.lms.course_about import CourseAboutPage from ..pages.lms.course_info import CourseInfoPage from ..pages.lms.tab_nav import TabNavPage from ..pages.lms.course_nav import CourseNavPage from ..pages.lms.progress import ProgressPage from ..pages.lms.dashboard import DashboardPage from ..pages.lms.video.video import VideoPage from ..pages.xblock.acid import AcidView from ..fixtures.course import CourseFixture, XBlockFixtureDesc, CourseUpdateDesc class RegistrationTest(UniqueCourseTest): """ Test the registration process. """ def setUp(self): """ Initialize pages and install a course fixture. """ super(RegistrationTest, self).setUp() self.find_courses_page = FindCoursesPage(self.browser) self.course_about_page = CourseAboutPage(self.browser, self.course_id) # Create a course to register for course_fix = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'] ).install() def test_register(self): # Visit the main page with the list of courses self.find_courses_page.visit() # Expect that the fixture course exists course_ids = self.find_courses_page.course_id_list self.assertIn(self.course_id, course_ids) # Go to the course about page and click the register button self.course_about_page.visit() register_page = self.course_about_page.register() # Fill in registration info and submit username = "test_" + self.unique_id[0:6] register_page.provide_info( username + "@example.com", "test", username, "Test User" ) dashboard = register_page.submit() # We should end up at the dashboard # Check that we're registered for the course course_names = dashboard.available_courses self.assertIn(self.course_info['display_name'], course_names) class LanguageTest(UniqueCourseTest): """ Tests that the change language functionality on the dashboard works """ def setUp(self): """ Initiailize dashboard page """ super(LanguageTest, self).setUp() self.dashboard_page = DashboardPage(self.browser) self.test_new_lang = 'eo' # This string is unicode for "ÇÜRRÉNT ÇØÜRSÉS", which should appear in our Dummy Esperanto page # We store the string this way because Selenium seems to try and read in strings from # the HTML in this format. Ideally we could just store the raw ÇÜRRÉNT ÇØÜRSÉS string here self.current_courses_text = u'\xc7\xdcRR\xc9NT \xc7\xd6\xdcRS\xc9S' self.username = "test" self.password = "testpass" self.email = "test@example.com" def test_change_lang(self): AutoAuthPage(self.browser, course_id=self.course_id).visit() self.dashboard_page.visit() # Change language to Dummy Esperanto self.dashboard_page.change_language(self.test_new_lang) changed_text = self.dashboard_page.current_courses_text # We should see the dummy-language text on the page self.assertIn(self.current_courses_text, changed_text) def test_language_persists(self): auto_auth_page = AutoAuthPage(self.browser, username=self.username, password=self.password, email=self.email, course_id=self.course_id) auto_auth_page.visit() self.dashboard_page.visit() # Change language to Dummy Esperanto self.dashboard_page.change_language(self.test_new_lang) # destroy session self.browser.delete_all_cookies() # log back in auto_auth_page.visit() self.dashboard_page.visit() changed_text = self.dashboard_page.current_courses_text # We should see the dummy-language text on the page self.assertIn(self.current_courses_text, changed_text) class HighLevelTabTest(UniqueCourseTest): """ Tests that verify each of the high-level tabs available within a course. """ def setUp(self): """ Initialize pages and install a course fixture. """ super(HighLevelTabTest, self).setUp() self.course_info_page = CourseInfoPage(self.browser, self.course_id) self.progress_page = ProgressPage(self.browser, self.course_id) self.course_nav = CourseNavPage(self.browser) self.tab_nav = TabNavPage(self.browser) self.video = VideoPage(self.browser) # 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_update( CourseUpdateDesc(date='January 29, 2014', content='Test course update1') ) course_fix.add_handout('demoPDF.pdf') course_fix.add_children( XBlockFixtureDesc('static_tab', 'Test Static Tab'), 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'), ) ).install() # Auto-auth register for the course AutoAuthPage(self.browser, course_id=self.course_id).visit() def test_course_info(self): """ Navigate to the course info page. """ # Navigate to the course info page from the progress page self.progress_page.visit() self.tab_nav.go_to_tab('Course Info') # Expect just one update self.assertEqual(self.course_info_page.num_updates, 1) # Expect a link to the demo handout pdf handout_links = self.course_info_page.handout_links self.assertEqual(len(handout_links), 1) self.assertIn('demoPDF.pdf', handout_links[0]) def test_progress(self): """ Navigate to the progress page. """ # Navigate to the progress page from the info page self.course_info_page.visit() self.tab_nav.go_to_tab('Progress') # We haven't answered any problems yet, so assume scores are zero # Only problems should have scores; so there should be 2 scores. CHAPTER = 'Test Section' SECTION = 'Test Subsection' EXPECTED_SCORES = [(0, 3), (0, 1)] actual_scores = self.progress_page.scores(CHAPTER, SECTION) self.assertEqual(actual_scores, EXPECTED_SCORES) def test_static_tab(self): """ Navigate to a static tab (course content) """ # From the course info page, navigate to the static tab self.course_info_page.visit() self.tab_nav.go_to_tab('Test Static Tab') self.assertTrue(self.tab_nav.is_on_tab('Test Static Tab')) def test_courseware_nav(self): """ Navigate to a particular unit in the courseware. """ # Navigate to the courseware page from the info page self.course_info_page.visit() self.tab_nav.go_to_tab('Courseware') # Check that the courseware navigation appears correctly EXPECTED_SECTIONS = { 'Test Section': ['Test Subsection'], 'Test Section 2': ['Test Subsection 2', 'Test Subsection 3'] } actual_sections = self.course_nav.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_nav.go_to_section('Test Section', 'Test Subsection') # Check the sequence items EXPECTED_ITEMS = ['Test Problem 1', 'Test Problem 2', 'Test HTML'] actual_items = self.course_nav.sequence_items self.assertEqual(len(actual_items), len(EXPECTED_ITEMS)) for expected in EXPECTED_ITEMS: self.assertIn(expected, actual_items) class VideoTest(UniqueCourseTest): """ Navigate to a video in the courseware and play it. """ def setUp(self): """ Initialize pages and install a course fixture. """ super(VideoTest, self).setUp() self.course_info_page = CourseInfoPage(self.browser, self.course_id) self.course_nav = CourseNavPage(self.browser) self.tab_nav = TabNavPage(self.browser) self.video = VideoPage(self.browser) # Install a course fixture with a video component 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').add_children( XBlockFixtureDesc('sequential', 'Test Subsection').add_children( XBlockFixtureDesc('vertical', 'Test Unit').add_children( XBlockFixtureDesc('video', 'Video') )))).install() # Auto-auth register for the course AutoAuthPage(self.browser, course_id=self.course_id).visit() @skip("BLD-563: Video Player Stuck on Pause") def test_video_player(self): """ Play a video in the courseware. """ # Navigate to a video self.course_info_page.visit() self.tab_nav.go_to_tab('Courseware') # The video should start off paused # Since the video hasn't loaded yet, it's elapsed time is 0 self.assertFalse(self.video.is_playing) self.assertEqual(self.video.elapsed_time, 0) # Play the video self.video.play() # Now we should be playing self.assertTrue(self.video.is_playing) # Commented the below EmptyPromise, will move to its page once this test is working and stable # Also there is should be no Promise check in any test as this should be done in Page Object # Wait for the video to load the duration # EmptyPromise( # lambda: self.video.duration > 0, # 'video has duration', timeout=20 # ).fulfill() # Pause the video self.video.pause() # Expect that the elapsed time and duration are reasonable # Again, we can't expect the video to actually play because of # latency through the ssh tunnel self.assertGreaterEqual(self.video.elapsed_time, 0) self.assertGreaterEqual(self.video.duration, self.video.elapsed_time) class XBlockAcidBase(UniqueCourseTest): """ Base class for tests that verify that XBlock integration is working correctly """ __test__ = False def setUp(self): """ Create a unique identifier for the course used in this test. """ # Ensure that the superclass sets up super(XBlockAcidBase, self).setUp() self.setup_fixtures() AutoAuthPage(self.browser, course_id=self.course_id).visit() self.course_info_page = CourseInfoPage(self.browser, self.course_id) self.tab_nav = TabNavPage(self.browser) def validate_acid_block_view(self, acid_block): """ Verify that the LMS view for the Acid Block is correct """ self.assertTrue(acid_block.init_fn_passed) self.assertTrue(acid_block.resource_url_passed) self.assertTrue(acid_block.scope_passed('user_state')) self.assertTrue(acid_block.scope_passed('user_state_summary')) self.assertTrue(acid_block.scope_passed('preferences')) self.assertTrue(acid_block.scope_passed('user_info')) def test_acid_block(self): """ Verify that all expected acid block tests pass in the lms. """ self.course_info_page.visit() self.tab_nav.go_to_tab('Courseware') acid_block = AcidView(self.browser, '.xblock-student_view[data-block-type=acid]') self.validate_acid_block_view(acid_block) class XBlockAcidNoChildTest(XBlockAcidBase): """ Tests of an AcidBlock with no children """ __test__ = True def setup_fixtures(self): 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').add_children( XBlockFixtureDesc('sequential', 'Test Subsection').add_children( XBlockFixtureDesc('vertical', 'Test Unit').add_children( XBlockFixtureDesc('acid', 'Acid Block') ) ) ) ).install() @skip('Flakey test, TE-401') def test_acid_block(self): super(XBlockAcidNoChildTest, self).test_acid_block() class XBlockAcidChildTest(XBlockAcidBase): """ Tests of an AcidBlock with children """ __test__ = True def setup_fixtures(self): 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').add_children( XBlockFixtureDesc('sequential', 'Test Subsection').add_children( XBlockFixtureDesc('vertical', 'Test Unit').add_children( XBlockFixtureDesc('acid_parent', 'Acid Parent Block').add_children( XBlockFixtureDesc('acid', 'First Acid Child', metadata={'name': 'first'}), XBlockFixtureDesc('acid', 'Second Acid Child', metadata={'name': 'second'}), XBlockFixtureDesc('html', 'Html Child', data="Contents"), ) ) ) ) ).install() def validate_acid_block_view(self, acid_block): super(XBlockAcidChildTest, self).validate_acid_block_view() self.assertTrue(acid_block.child_tests_passed) @skip('This will fail until we fix support of children in pure XBlocks') def test_acid_block(self): super(XBlockAcidChildTest, self).test_acid_block()