class LibraryTabHelpTest(AcceptanceTest): """ Test help links on the library tab present at dashboard. """ def setUp(self): super(LibraryTabHelpTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.auth_page.visit() self.dashboard_page.visit() def test_library_tab_nav_help(self): """ Scenario: Help link in navigation bar is working on 'Home'(Courses tab) page. Given that I am on the 'Home'(Courses tab) page. And I want help about the process And I click the 'Help' in the navigation bar Then Help link should open. And help url should be correct """ self.assertTrue(self.dashboard_page.has_new_library_button) click_css(self.dashboard_page, '#course-index-tabs .libraries-tab', 0, False) expected_url = _get_expected_documentation_url('/getting_started/CA_get_started_Studio.html') # Assert that help link is correct. assert_nav_help_link( test=self, page=self.dashboard_page, href=expected_url )
class LibraryTabHelpTest(AcceptanceTest): """ Test help links on the library tab present at dashboard. """ def setUp(self): super(LibraryTabHelpTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.auth_page.visit() self.dashboard_page.visit() def test_library_tab_nav_help(self): """ Scenario: Help link in navigation bar is working on 'Home'(Courses tab) page. Given that I am on the 'Home'(Courses tab) page. And I want help about the process And I click the 'Help' in the navigation bar Then Help link should open. And help url should be correct """ self.assertTrue(self.dashboard_page.has_new_library_button) click_css(self.dashboard_page, '#course-index-tabs .libraries-tab', 0, False) expected_url = _get_expected_documentation_url( '/getting_started/CA_get_started_Studio.html') # Assert that help link is correct. assert_nav_help_link(test=self, page=self.dashboard_page, href=expected_url)
def auth(self, enroll=True): """Authenticate, enrolling the user in the configured course if requested.""" CourseFixture(**self.course_info).install() course_id = self.course_id if enroll else None auth_page = AutoAuthPage(self.browser, course_id=course_id) auth_page.visit() self.username = auth_page.user_info['username']
def log_in(self, user, is_staff=False): """ Log in as the user that created the library. By default the user will not have staff access unless is_staff is passed as True. """ auth_page = AutoAuthPage(self.browser, staff=is_staff, username=user.get('username'), email=user.get('email'), password=user.get('password')) auth_page.visit()
def log_in(self, user, is_staff=False): """ Log in as the user that created the library. By default the user will not have staff access unless is_staff is passed as True. """ auth_page = AutoAuthPage( self.browser, staff=is_staff, username=user.get('username'), email=user.get('email'), password=user.get('password') ) auth_page.visit()
class CreateLibraryTest(AcceptanceTest): """ Test that we can create a new content library on the studio home page. """ def setUp(self): """ Load the helper for the home page (dashboard page) """ super(CreateLibraryTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) def test_create_library(self): """ From the home page: Click "New Library" Fill out the form Submit the form We should be redirected to the edit view for the library Return to the home page The newly created library should now appear in the list of libraries """ unique_suffix = uuid4().hex[:4] name = "New Library Name " + unique_suffix org = "TestOrgX" + unique_suffix number = "TESTLIB_" + unique_suffix self.auth_page.visit() self.dashboard_page.visit() self.assertFalse(self.dashboard_page.has_library(name=name, org=org, number=number)) self.assertTrue(self.dashboard_page.has_new_library_button()) self.dashboard_page.click_new_library() self.assertTrue(self.dashboard_page.is_new_library_form_visible()) self.dashboard_page.fill_new_library_form(name, org, number) self.assertTrue(self.dashboard_page.is_new_library_form_valid()) self.dashboard_page.submit_new_library_form() # The next page is the library edit view; make sure it loads: lib_page = LibraryEditPage(self.browser, LibraryLocator(org, number)) lib_page.wait_for_page() # Then go back to the home page and make sure the new library is listed there: self.dashboard_page.visit() self.assertTrue(self.dashboard_page.has_library(name=name, org=org, number=number)) # Click on the library listing and verify that the library edit view loads. self.dashboard_page.click_library(name) lib_page.wait_for_page()
class NewLibraryHelpTest(AcceptanceTest): """ Test help links while creating a new library """ def setUp(self): super(NewLibraryHelpTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.auth_page.visit() self.dashboard_page.visit() self.assertTrue(self.dashboard_page.has_new_library_button) self.dashboard_page.click_new_library() def test_library_create_nav_help(self): """ Scenario: Help link in navigation bar is working on 'Create a New Library' page in the dashboard. Given that I am on the 'Create a New Library' page in the dashboard. And I want help about the process And I click the 'Help' in the navigation bar Then Help link should open. And help url should be correct """ expected_url = _get_expected_documentation_url('/getting_started/CA_get_started_Studio.html') # Assert that help link is correct. assert_nav_help_link( test=self, page=self.dashboard_page, href=expected_url ) def test_library_create_side_bar_help(self): """ Scenario: Help link in sidebar links is working on 'Create a New Library' page in the dashboard. Given that I am on the 'Create a New Library' page in the dashboard. And I want help about the process And I click the 'Getting Started with Your Platform Studio' in the sidebar links Then Help link should open. And help url should be correct """ expected_url = _get_expected_documentation_url('/getting_started/CA_get_started_Studio.html') # Assert that help link is correct. assert_side_bar_help_link( test=self, page=self.dashboard_page, href=expected_url, help_text='Getting Started with Your Platform Studio', as_list_item=True )
class NewLibraryHelpTest(AcceptanceTest): """ Test help links while creating a new library """ def setUp(self): super(NewLibraryHelpTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.auth_page.visit() self.dashboard_page.visit() self.assertTrue(self.dashboard_page.has_new_library_button) self.dashboard_page.click_new_library() def test_library_create_nav_help(self): """ Scenario: Help link in navigation bar is working on 'Create a New Library' page in the dashboard. Given that I am on the 'Create a New Library' page in the dashboard. And I want help about the process And I click the 'Help' in the navigation bar Then Help link should open. And help url should be correct """ expected_url = _get_expected_documentation_url('/getting_started/CA_get_started_Studio.html') # Assert that help link is correct. assert_nav_help_link( test=self, page=self.dashboard_page, href=expected_url ) def test_library_create_side_bar_help(self): """ Scenario: Help link in sidebar links is working on 'Create a New Library' page in the dashboard. Given that I am on the 'Create a New Library' page in the dashboard. And I want help about the process And I click the 'Getting Started with edX Studio' in the sidebar links Then Help link should open. And help url should be correct """ expected_url = _get_expected_documentation_url('/getting_started/CA_get_started_Studio.html') # Assert that help link is correct. assert_side_bar_help_link( test=self, page=self.dashboard_page, href=expected_url, help_text='Getting Started with edX Studio', as_list_item=True )
class CreateLibraryTest(AcceptanceTest): """ Test that we can create a new content library on the studio home page. """ def setUp(self): """ Load the helper for the home page (dashboard page) """ super(CreateLibraryTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) def test_create_library(self): """ From the home page: Click "New Library" Fill out the form Submit the form We should be redirected to the edit view for the library Return to the home page The newly created library should now appear in the list of libraries """ unique_suffix = uuid4().hex[:4] name = "New Library Name " + unique_suffix org = "TestOrgX" + unique_suffix number = "TESTLIB_" + unique_suffix self.auth_page.visit() self.dashboard_page.visit() self.assertFalse(self.dashboard_page.has_library(name=name, org=org, number=number)) self.assertTrue(self.dashboard_page.has_new_library_button()) self.dashboard_page.click_new_library() self.assertTrue(self.dashboard_page.is_new_library_form_visible()) self.dashboard_page.fill_new_library_form(name, org, number) self.assertTrue(self.dashboard_page.is_new_library_form_valid()) self.dashboard_page.submit_new_library_form() # The next page is the library edit view; make sure it loads: lib_page = LibraryEditPage(self.browser, LibraryLocator(org, number)) lib_page.wait_for_page() # Then go back to the home page and make sure the new library is listed there: self.dashboard_page.visit() self.assertTrue(self.dashboard_page.has_library(name=name, org=org, number=number))
class LoggedInPagesTest(AcceptanceTest): """ Verify the pages in Studio that you can get to when logged in and do not have a course yet. """ def setUp(self): super(LoggedInPagesTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.home_page = HomePage(self.browser) def test_logged_in_no_courses(self): """ Make sure that you can get to the dashboard and home pages without a course. """ self.auth_page.visit() self.dashboard_page.visit() self.home_page.visit()
def log_in_as_instructor(self, global_staff=True, course_access_roles=None): """ Login with an instructor account. Args: course_access_roles (str[]): List of course access roles that should be assigned to the user. Returns username (str) user_id (int) """ course_access_roles = course_access_roles or [] auto_auth_page = AutoAuthPage( self.browser, course_id=self.course_id, staff=global_staff, course_access_roles=course_access_roles ) auto_auth_page.visit() user_info = auto_auth_page.user_info return user_info['username'], user_info['user_id'], user_info['email'], user_info['password']
class VideoBaseTest(UniqueCourseTest): """ Base class for tests of the Video Player Sets up the course and provides helper functions for the Video tests. """ def setUp(self): """ Initialization of pages and course fixture for video tests """ super(VideoBaseTest, self).setUp() self.longMessage = True self.video = VideoPage(self.browser) self.tab_nav = TabNavPage(self.browser) self.courseware_page = CoursewarePage(self.browser, self.course_id) self.course_info_page = CourseInfoPage(self.browser, self.course_id) self.auth_page = AutoAuthPage(self.browser, course_id=self.course_id) self.course_fixture = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'] ) self.metadata = None self.assets = [] self.contents_of_verticals = None self.youtube_configuration = {} self.user_info = {} # reset youtube stub server self.addCleanup(YouTubeStubConfig.reset) def navigate_to_video(self): """ Prepare the course and get to the video and render it """ self._install_course_fixture() self._navigate_to_courseware_video_and_render() def navigate_to_video_no_render(self): """ Prepare the course and get to the video unit however do not wait for it to render, because the has been an error. """ self._install_course_fixture() self._navigate_to_courseware_video_no_render() def _install_course_fixture(self): """ Install the course fixture that has been defined """ if self.assets: self.course_fixture.add_asset(self.assets) chapter_sequential = XBlockFixtureDesc('sequential', 'Test Section') chapter_sequential.add_children(*self._add_course_verticals()) chapter = XBlockFixtureDesc('chapter', 'Test Chapter').add_children(chapter_sequential) self.course_fixture.add_children(chapter) self.course_fixture.install() if len(self.youtube_configuration) > 0: YouTubeStubConfig.configure(self.youtube_configuration) def _add_course_verticals(self): """ Create XBlockFixtureDesc verticals :return: a list of XBlockFixtureDesc """ xblock_verticals = [] _contents_of_verticals = self.contents_of_verticals # Video tests require at least one vertical with a single video. if not _contents_of_verticals: _contents_of_verticals = [[{'display_name': 'Video', 'metadata': self.metadata}]] for vertical_index, vertical in enumerate(_contents_of_verticals): xblock_verticals.append(self._create_single_vertical(vertical, vertical_index)) return xblock_verticals def _create_single_vertical(self, vertical_contents, vertical_index): """ Create a single course vertical of type XBlockFixtureDesc with category `vertical`. A single course vertical can contain single or multiple video modules. :param vertical_contents: a list of items for the vertical to contain :param vertical_index: index for the vertical display name :return: XBlockFixtureDesc """ xblock_course_vertical = XBlockFixtureDesc('vertical', u'Test Vertical-{0}'.format(vertical_index)) for video in vertical_contents: xblock_course_vertical.add_children( XBlockFixtureDesc('video', video['display_name'], metadata=video.get('metadata'))) return xblock_course_vertical def _navigate_to_courseware_video(self): """ Register for the course and navigate to the video unit """ self.auth_page.visit() self.user_info = self.auth_page.user_info self.courseware_page.visit() def _navigate_to_courseware_video_and_render(self): """ Wait for the video player to render """ self._navigate_to_courseware_video() self.video.wait_for_video_player_render() def _navigate_to_courseware_video_no_render(self): """ Wait for the video Xmodule but not for rendering """ self._navigate_to_courseware_video() self.video.wait_for_video_class() def metadata_for_mode(self, player_mode, additional_data=None): """ Create a dictionary for video player configuration according to `player_mode` :param player_mode (str): Video player mode :param additional_data (dict): Optional additional metadata. :return: dict """ metadata = {} youtube_ids = { 'youtube_id_1_0': '', 'youtube_id_0_75': '', 'youtube_id_1_25': '', 'youtube_id_1_5': '', } if player_mode == 'html5': metadata.update(youtube_ids) metadata.update({ 'html5_sources': HTML5_SOURCES }) if player_mode == 'youtube_html5': metadata.update({ 'html5_sources': HTML5_SOURCES, }) if player_mode == 'youtube_html5_unsupported_video': metadata.update({ 'html5_sources': HTML5_SOURCES_INCORRECT }) if player_mode == 'html5_unsupported_video': metadata.update(youtube_ids) metadata.update({ 'html5_sources': HTML5_SOURCES_INCORRECT }) if player_mode == 'hls': metadata.update(youtube_ids) metadata.update({ 'html5_sources': HLS_SOURCES, }) if player_mode == 'html5_and_hls': metadata.update(youtube_ids) metadata.update({ 'html5_sources': HTML5_SOURCES + HLS_SOURCES, }) if additional_data: metadata.update(additional_data) return metadata def go_to_sequential_position(self, position): """ Navigate to sequential specified by `video_display_name` """ self.courseware_page.go_to_sequential_position(position) self.video.wait_for_video_player_render()
class XBlockAcidBase(AcceptanceTest): """ 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() # Define a unique course identifier self.course_info = { 'org': 'test_org', 'number': 'course_' + self.unique_id[:5], 'run': 'test_' + self.unique_id, 'display_name': 'Test Course ' + self.unique_id } self.outline = CourseOutlinePage( self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run'] ) self.course_id = '{org}.{number}.{run}'.format(**self.course_info) self.setup_fixtures() self.auth_page = AutoAuthPage( self.browser, staff=False, username=self.user.get('username'), email=self.user.get('email'), password=self.user.get('password') ) self.auth_page.visit() def validate_acid_block_preview(self, acid_block): """ Validate the Acid Block's preview """ 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_preview(self): """ Verify that all expected acid block tests pass in studio preview """ self.outline.visit() subsection = self.outline.section('Test Section').subsection('Test Subsection') unit = subsection.expand_subsection().unit('Test Unit').go_to() acid_block = AcidView(self.browser, unit.xblocks[0].preview_selector) self.validate_acid_block_preview(acid_block) def test_acid_block_editor(self): """ Verify that all expected acid block tests pass in studio editor """ self.outline.visit() subsection = self.outline.section('Test Section').subsection('Test Subsection') unit = subsection.expand_subsection().unit('Test Unit').go_to() acid_block = AcidView(self.browser, unit.xblocks[0].edit().editor_selector) self.assertTrue(acid_block.init_fn_passed) self.assertTrue(acid_block.resource_url_passed)
class CreateCourseTest(AcceptanceTest): """ Test that we can create a new course the studio home page. """ def setUp(self): """ Load the helper for the home page (dashboard page) """ super(CreateCourseTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.course_name = "New Course Name" self.course_org = "orgX" self.course_number = str(uuid.uuid4().get_hex().upper()[0:6]) self.course_run = "2015_T2" def test_create_course_with_non_existing_org(self): """ Scenario: Ensure that the course creation with non existing org display proper error message. Given I have filled course creation form with a non existing and all required fields When I click 'Create' button Form validation should pass Then I see the error message explaining reason for failure to create course """ self.auth_page.visit() self.dashboard_page.visit() self.assertFalse(self.dashboard_page.has_course( org='testOrg', number=self.course_number, run=self.course_run )) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form( self.course_name, 'testOrg', self.course_number, self.course_run ) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() self.assertTrue(self.dashboard_page.error_notification.present) self.assertIn( u'Organization you selected does not exist in the system', self.dashboard_page.error_notification_message ) def test_create_course_with_existing_org(self): """ Scenario: Ensure that the course creation with an existing org should be successful. Given I have filled course creation form with an existing org and all required fields When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ self.auth_page.visit() self.dashboard_page.visit() self.assertFalse(self.dashboard_page.has_course( org=self.course_org, number=self.course_number, run=self.course_run )) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form( self.course_name, self.course_org, self.course_number, self.course_run ) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage( self.browser, self.course_org, self.course_number, self.course_run ) course_outline_page.visit() course_outline_page.wait_for_page() # Go back to dashboard and verify newly created course exists there self.dashboard_page.visit() self.assertTrue(self.dashboard_page.has_course( org=self.course_org, number=self.course_number, run=self.course_run )) # Click on the course listing and verify that the Studio course outline page opens. self.dashboard_page.click_course_run(self.course_run) course_outline_page.wait_for_page() def test_create_course_with_existing_org_via_autocomplete(self): """ Scenario: Ensure that the course creation with an existing org should be successful. Given I have filled course creation form with an existing org and all required fields And I selected `Course Organization` input via autocomplete When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ self.auth_page.visit() self.dashboard_page.visit() new_org = 'orgX2' self.assertFalse(self.dashboard_page.has_course( org=new_org, number=self.course_number, run=self.course_run )) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form( self.course_name, '', self.course_number, self.course_run ) self.dashboard_page.course_org_field.fill('org') self.dashboard_page.select_item_in_autocomplete_widget(new_org) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage( self.browser, new_org, self.course_number, self.course_run ) course_outline_page.visit() course_outline_page.wait_for_page() # Go back to dashboard and verify newly created course exists there self.dashboard_page.visit() self.assertTrue(self.dashboard_page.has_course( org=new_org, number=self.course_number, run=self.course_run ))
class CreateCourseTest(AcceptanceTest): """ Test that we can create a new course the studio home page. """ def setUp(self): """ Load the helper for the home page (dashboard page) """ super(CreateCourseTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.course_name = "New Course Name" self.course_org = "orgX" self.course_number = str(uuid.uuid4().get_hex().upper()[0:6]) self.course_run = "2015_T2" def test_create_course_with_non_existing_org(self): """ Scenario: Ensure that the course creation with non existing org display proper error message. Given I have filled course creation form with a non existing and all required fields When I click 'Create' button Form validation should pass Then I see the error message explaining reason for failure to create course """ self.auth_page.visit() self.dashboard_page.visit() self.assertFalse( self.dashboard_page.has_course(org='testOrg', number=self.course_number, run=self.course_run)) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, 'testOrg', self.course_number, self.course_run) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() self.assertTrue(self.dashboard_page.error_notification.present) self.assertIn( u'Organization you selected does not exist in the system', self.dashboard_page.error_notification_message) def test_create_course_with_existing_org(self): """ Scenario: Ensure that the course creation with an existing org should be successful. Given I have filled course creation form with an existing org and all required fields When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ self.auth_page.visit() self.dashboard_page.visit() self.assertFalse( self.dashboard_page.has_course(org=self.course_org, number=self.course_number, run=self.course_run)) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, self.course_org, self.course_number, self.course_run) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage(self.browser, self.course_org, self.course_number, self.course_run) course_outline_page.visit() course_outline_page.wait_for_page() # Go back to dashboard and verify newly created course exists there self.dashboard_page.visit() self.assertTrue( self.dashboard_page.has_course(org=self.course_org, number=self.course_number, run=self.course_run)) # Click on the course listing and verify that the Studio course outline page opens. self.dashboard_page.click_course_run(self.course_run) course_outline_page.wait_for_page() def test_create_course_with_existing_org_via_autocomplete(self): """ Scenario: Ensure that the course creation with an existing org should be successful. Given I have filled course creation form with an existing org and all required fields And I selected `Course Organization` input via autocomplete When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ self.auth_page.visit() self.dashboard_page.visit() new_org = 'orgX2' self.assertFalse( self.dashboard_page.has_course(org=new_org, number=self.course_number, run=self.course_run)) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, '', self.course_number, self.course_run) self.dashboard_page.course_org_field.fill('org') self.dashboard_page.select_item_in_autocomplete_widget(new_org) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage(self.browser, new_org, self.course_number, self.course_run) course_outline_page.visit() course_outline_page.wait_for_page() # Go back to dashboard and verify newly created course exists there self.dashboard_page.visit() self.assertTrue( self.dashboard_page.has_course(org=new_org, number=self.course_number, run=self.course_run)) def test_error_appears_with_long_tuple(self): """ Scenario: Ensure that the course creation is not successful with 66 characters long tuple. Given I have filled course creation from with combined length of 66 characters for Organization, course Number and course Run. And I have a valid course name Then form validation should not pass And I see error for combined length longer than 65 """ course_org = "012345678901234567890123456789" course_number = ''.join( random.choice(string.digits) for _ in range(30)) course_run = "0123456" self.auth_page.visit() self.dashboard_page.visit() self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, course_org, course_number, course_run) self.assertEqual( self.dashboard_page.course_creation_error_message, 'The combined length of the organization, course number, and course run fields cannot be more than 65 ' 'characters.') self.assertTrue(self.dashboard_page.is_create_button_disabled()) def test_no_error_appears_for_long_course_name(self): """ Scenario: Ensure that the course creation with 66 characters long course name is successful. Given I have filled course creation form with 66 characters long course name. And I have filled remaining form within the allowed characters length. When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ course_name = ''.join( random.choice(string.ascii_uppercase) for _ in range(66)) self.auth_page.visit() self.dashboard_page.visit() self.assertFalse( self.dashboard_page.has_course(org=self.course_org, number=self.course_number, run=self.course_run)) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(course_name, self.course_org, self.course_number, self.course_run) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage(self.browser, self.course_org, self.course_number, self.course_run) course_outline_page.visit() course_outline_page.wait_for_page() self.dashboard_page.visit() # Assert that course is present on dashboard self.assertTrue( self.dashboard_page.has_course(org=self.course_org, number=self.course_number, run=self.course_run))
class VideoBaseTest(UniqueCourseTest): """ Base class for tests of the Video Player Sets up the course and provides helper functions for the Video tests. """ def setUp(self): """ Initialization of pages and course fixture for video tests """ super(VideoBaseTest, self).setUp() self.longMessage = True self.video = VideoPage(self.browser) self.tab_nav = TabNavPage(self.browser) self.courseware_page = CoursewarePage(self.browser, self.course_id) self.course_info_page = CourseInfoPage(self.browser, self.course_id) self.auth_page = AutoAuthPage(self.browser, course_id=self.course_id) self.course_fixture = CourseFixture(self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name']) self.metadata = None self.assets = [] self.contents_of_verticals = None self.youtube_configuration = {} self.user_info = {} # reset youtube stub server self.addCleanup(YouTubeStubConfig.reset) def navigate_to_video(self): """ Prepare the course and get to the video and render it """ self._install_course_fixture() self._navigate_to_courseware_video_and_render() def navigate_to_video_no_render(self): """ Prepare the course and get to the video unit however do not wait for it to render, because the has been an error. """ self._install_course_fixture() self._navigate_to_courseware_video_no_render() def _install_course_fixture(self): """ Install the course fixture that has been defined """ if self.assets: self.course_fixture.add_asset(self.assets) chapter_sequential = XBlockFixtureDesc('sequential', 'Test Section') chapter_sequential.add_children(*self._add_course_verticals()) chapter = XBlockFixtureDesc( 'chapter', 'Test Chapter').add_children(chapter_sequential) self.course_fixture.add_children(chapter) self.course_fixture.install() if len(self.youtube_configuration) > 0: YouTubeStubConfig.configure(self.youtube_configuration) def _add_course_verticals(self): """ Create XBlockFixtureDesc verticals :return: a list of XBlockFixtureDesc """ xblock_verticals = [] _contents_of_verticals = self.contents_of_verticals # Video tests require at least one vertical with a single video. if not _contents_of_verticals: _contents_of_verticals = [[{ 'display_name': 'Video', 'metadata': self.metadata }]] for vertical_index, vertical in enumerate(_contents_of_verticals): xblock_verticals.append( self._create_single_vertical(vertical, vertical_index)) return xblock_verticals def _create_single_vertical(self, vertical_contents, vertical_index): """ Create a single course vertical of type XBlockFixtureDesc with category `vertical`. A single course vertical can contain single or multiple video modules. :param vertical_contents: a list of items for the vertical to contain :param vertical_index: index for the vertical display name :return: XBlockFixtureDesc """ xblock_course_vertical = XBlockFixtureDesc( 'vertical', u'Test Vertical-{0}'.format(vertical_index)) for video in vertical_contents: xblock_course_vertical.add_children( XBlockFixtureDesc('video', video['display_name'], metadata=video.get('metadata'))) return xblock_course_vertical def _navigate_to_courseware_video(self): """ Register for the course and navigate to the video unit """ self.auth_page.visit() self.user_info = self.auth_page.user_info self.courseware_page.visit() def _navigate_to_courseware_video_and_render(self): """ Wait for the video player to render """ self._navigate_to_courseware_video() self.video.wait_for_video_player_render() def _navigate_to_courseware_video_no_render(self): """ Wait for the video Xmodule but not for rendering """ self._navigate_to_courseware_video() self.video.wait_for_video_class() def metadata_for_mode(self, player_mode, additional_data=None): """ Create a dictionary for video player configuration according to `player_mode` :param player_mode (str): Video player mode :param additional_data (dict): Optional additional metadata. :return: dict """ metadata = {} youtube_ids = { 'youtube_id_1_0': '', 'youtube_id_0_75': '', 'youtube_id_1_25': '', 'youtube_id_1_5': '', } if player_mode == 'html5': metadata.update(youtube_ids) metadata.update({'html5_sources': HTML5_SOURCES}) if player_mode == 'youtube_html5': metadata.update({ 'html5_sources': HTML5_SOURCES, }) if player_mode == 'youtube_html5_unsupported_video': metadata.update({'html5_sources': HTML5_SOURCES_INCORRECT}) if player_mode == 'html5_unsupported_video': metadata.update(youtube_ids) metadata.update({'html5_sources': HTML5_SOURCES_INCORRECT}) if player_mode == 'hls': metadata.update(youtube_ids) metadata.update({ 'html5_sources': HLS_SOURCES, }) if player_mode == 'html5_and_hls': metadata.update(youtube_ids) metadata.update({ 'html5_sources': HTML5_SOURCES + HLS_SOURCES, }) if additional_data: metadata.update(additional_data) return metadata def go_to_sequential_position(self, position): """ Navigate to sequential specified by `video_display_name` """ self.courseware_page.go_to_sequential_position(position) self.video.wait_for_video_player_render()
class XBlockAcidBase(AcceptanceTest): """ Base class for tests that verify that XBlock integration is working correctly """ shard = 21 __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() # Define a unique course identifier self.course_info = { 'org': 'test_org', 'number': 'course_' + self.unique_id[:5], 'run': 'test_' + self.unique_id, 'display_name': 'Test Course ' + self.unique_id } self.outline = CourseOutlinePage(self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run']) self.course_id = '{org}.{number}.{run}'.format(**self.course_info) self.setup_fixtures() self.auth_page = AutoAuthPage(self.browser, staff=False, username=self.user.get('username'), email=self.user.get('email'), password=self.user.get('password')) self.auth_page.visit() def validate_acid_block_preview(self, acid_block): """ Validate the Acid Block's preview """ 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_preview(self): """ Verify that all expected acid block tests pass in studio preview """ self.outline.visit() subsection = self.outline.section('Test Section').subsection( 'Test Subsection') unit = subsection.expand_subsection().unit('Test Unit').go_to() acid_block = AcidView(self.browser, unit.xblocks[0].preview_selector) self.validate_acid_block_preview(acid_block) def test_acid_block_editor(self): """ Verify that all expected acid block tests pass in studio editor """ self.outline.visit() subsection = self.outline.section('Test Section').subsection( 'Test Subsection') unit = subsection.expand_subsection().unit('Test Unit').go_to() acid_block = AcidView(self.browser, unit.xblocks[0].edit().editor_selector) self.assertTrue(acid_block.init_fn_passed) self.assertTrue(acid_block.resource_url_passed)
class CreateCourseTest(AcceptanceTest): """ Test that we can create a new course the studio home page. """ def setUp(self): """ Load the helper for the home page (dashboard page) """ super(CreateCourseTest, self).setUp() self.auth_page = AutoAuthPage(self.browser, staff=True) self.dashboard_page = DashboardPage(self.browser) self.course_name = "New Course Name" self.course_org = "orgX" self.course_number = str(uuid.uuid4().get_hex().upper()[0:6]) self.course_run = "2015_T2" def test_create_course_with_non_existing_org(self): """ Scenario: Ensure that the course creation with non existing org display proper error message. Given I have filled course creation form with a non existing and all required fields When I click 'Create' button Form validation should pass Then I see the error message explaining reason for failure to create course """ self.auth_page.visit() self.dashboard_page.visit() self.assertFalse( self.dashboard_page.has_course(org='testOrg', number=self.course_number, run=self.course_run)) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, 'testOrg', self.course_number, self.course_run) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() self.assertTrue(self.dashboard_page.error_notification.present) self.assertIn( u'Organization you selected does not exist in the system', self.dashboard_page.error_notification_message) def test_create_course_with_existing_org(self): """ Scenario: Ensure that the course creation with an existing org should be successful. Given I have filled course creation form with an existing org and all required fields When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ self.auth_page.visit() self.dashboard_page.visit() self.assertFalse( self.dashboard_page.has_course(org=self.course_org, number=self.course_number, run=self.course_run)) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, self.course_org, self.course_number, self.course_run) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage(self.browser, self.course_org, self.course_number, self.course_run) course_outline_page.visit() course_outline_page.wait_for_page() # Go back to dashboard and verify newly created course exists there self.dashboard_page.visit() self.assertTrue( self.dashboard_page.has_course(org=self.course_org, number=self.course_number, run=self.course_run)) def test_create_course_with_existing_org_via_autocomplete(self): """ Scenario: Ensure that the course creation with an existing org should be successful. Given I have filled course creation form with an existing org and all required fields And I selected `Course Organization` input via autocomplete When I click 'Create' button Form validation should pass Then I see the course listing page with newly created course """ self.auth_page.visit() self.dashboard_page.visit() new_org = 'orgX2' self.assertFalse( self.dashboard_page.has_course(org=new_org, number=self.course_number, run=self.course_run)) self.assertTrue(self.dashboard_page.new_course_button.present) self.dashboard_page.click_new_course_button() self.assertTrue(self.dashboard_page.is_new_course_form_visible()) self.dashboard_page.fill_new_course_form(self.course_name, '', self.course_number, self.course_run) self.dashboard_page.course_org_field.fill('org') self.dashboard_page.select_item_in_autocomplete_widget(new_org) self.assertTrue(self.dashboard_page.is_new_course_form_valid()) self.dashboard_page.submit_new_course_form() # Successful creation of course takes user to course outline page course_outline_page = CourseOutlinePage(self.browser, new_org, self.course_number, self.course_run) course_outline_page.visit() course_outline_page.wait_for_page() # Go back to dashboard and verify newly created course exists there self.dashboard_page.visit() self.assertTrue( self.dashboard_page.has_course(org=new_org, number=self.course_number, run=self.course_run))
class StudioCourseTest(UniqueCourseTest): """ Base class for all Studio course tests. """ def setUp(self, is_staff=False, test_xss=True): # pylint: disable=arguments-differ """ Install a course with no content using a fixture. """ super(StudioCourseTest, self).setUp() self.test_xss = test_xss self.install_course_fixture(is_staff) def install_course_fixture(self, is_staff=False): """ Install a course fixture """ self.course_fixture = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'], ) if self.test_xss: xss_injected_unique_id = XSS_INJECTION + self.unique_id test_improper_escaping = {u"value": xss_injected_unique_id} self.course_fixture.add_advanced_settings({ "advertised_start": test_improper_escaping, "info_sidebar_name": test_improper_escaping, "cert_name_short": test_improper_escaping, "cert_name_long": test_improper_escaping, "display_organization": test_improper_escaping, "display_coursenumber": test_improper_escaping, }) self.course_info['display_organization'] = xss_injected_unique_id self.course_info['display_coursenumber'] = xss_injected_unique_id self.populate_course_fixture(self.course_fixture) self.course_fixture.install() self.user = self.course_fixture.user self.log_in(self.user, is_staff) def populate_course_fixture(self, course_fixture): """ Populate the children of the test course fixture. """ pass def log_in(self, user, is_staff=False): """ Log in as the user that created the course. The user will be given instructor access to the course and enrolled in it. By default the user will not have staff access unless is_staff is passed as True. Args: user(dict): dictionary containing user data: {'username': ..., 'email': ..., 'password': ...} is_staff(bool): register this user as staff """ self.auth_page = AutoAuthPage( self.browser, staff=is_staff, username=user.get('username'), email=user.get('email'), password=user.get('password') ) self.auth_page.visit()
class StudioCourseTest(UniqueCourseTest): """ Base class for all Studio course tests. """ def setUp(self, is_staff=False, test_xss=True): # pylint: disable=arguments-differ """ Install a course with no content using a fixture. """ super(StudioCourseTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.test_xss = test_xss self.install_course_fixture(is_staff) def install_course_fixture(self, is_staff=False): """ Install a course fixture """ self.course_fixture = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'], ) if self.test_xss: xss_injected_unique_id = XSS_INJECTION + self.unique_id test_improper_escaping = {u"value": xss_injected_unique_id} self.course_fixture.add_advanced_settings({ "advertised_start": test_improper_escaping, "info_sidebar_name": test_improper_escaping, "cert_name_short": test_improper_escaping, "cert_name_long": test_improper_escaping, "display_organization": test_improper_escaping, "display_coursenumber": test_improper_escaping, }) self.course_info['display_organization'] = xss_injected_unique_id self.course_info['display_coursenumber'] = xss_injected_unique_id self.populate_course_fixture(self.course_fixture) self.course_fixture.install() self.user = self.course_fixture.user self.log_in(self.user, is_staff) def populate_course_fixture(self, course_fixture): """ Populate the children of the test course fixture. """ pass # lint-amnesty, pylint: disable=unnecessary-pass def log_in(self, user, is_staff=False): """ Log in as the user that created the course. The user will be given instructor access to the course and enrolled in it. By default the user will not have staff access unless is_staff is passed as True. Args: user(dict): dictionary containing user data: {'username': ..., 'email': ..., 'password': ...} is_staff(bool): register this user as staff """ self.auth_page = AutoAuthPage( # lint-amnesty, pylint: disable=attribute-defined-outside-init self.browser, staff=is_staff, username=user.get('username'), email=user.get('email'), password=user.get('password')) self.auth_page.visit()