class TestCreateNewQuestionAndAssignmentTypes(unittest.TestCase): """T2.12 - Create New Question and Assignment Types.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.student = Student(use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities) def tearDown(self): """Test destructor.""" self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) self.student = None try: self.teacher.delete() except: pass # 14739 - 001 - Teacher | Vocabulary question is a question type @pytest.mark.skipif(str(14739) not in TESTS, reason='Excluded') def test_teacher_vocabulary_question_is_a_question_type_14739(self): """Vocabulary question is a question type. Steps: Go to Tutor Click on the 'Login' button Enter the teacher account in the username and password text boxes Click on the 'Sign in' button Click "Write a new exercise" Click "New Vocabulary Term" Expected Result: The user is presented with a page where a new vocabulary question can be created """ self.ps.test_updates['name'] = 't2.12.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.001', '14739'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get("https://exercises-qa.openstax.org/") # login self.teacher.find( By.XPATH, '//div[@id="account-bar-content"]//a[text()="Sign in"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'auth_key').send_keys(self.teacher.username) self.teacher.find(By.ID, 'password').send_keys(self.teacher.password) self.teacher.find(By.XPATH, '//button[text()="Sign in"]').click() # create new vocab self.teacher.page.wait_for_page_load() self.teacher.find(By.XPATH, '//a[@href="/exercises/new"]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[text()="New Vocabulary Term"]'))).click() assert('/vocabulary/new' in self.teacher.current_url()), \ 'not at new vocab page' self.ps.test_updates['passed'] = True # 14741 - 002 - Teacher | True/False is a question type @pytest.mark.skipif(str(14741) not in TESTS, reason='Excluded') def test_teacher_truefalse_is_a_question_type_14741(self): """True/False is a question type. Steps: Click "Write a new exercise" Click on the "True/False" radio button Expected Result: The user is presented with a page where a True/False question can be created """ self.ps.test_updates['name'] = 't2.12.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.002', '14741'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get("https://exercises-qa.openstax.org/") # login self.teacher.find( By.XPATH, '//div[@id="account-bar-content"]//a[text()="Sign in"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'auth_key').send_keys(self.teacher.username) self.teacher.find(By.ID, 'password').send_keys(self.teacher.password) self.teacher.find(By.XPATH, '//button[text()="Sign in"]').click() # create new vocab self.teacher.page.wait_for_page_load() self.teacher.find(By.XPATH, '//a[@href="/exercises/new"]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//input[@label="True/False"]'))).click() self.teacher.find(By.XPATH, '//span[text()="True/False"]') self.ps.test_updates['passed'] = True # possibly changed implementation on site # no info icon found # 14742 - 003 - System | Display embedded videos with attribution and link # back to author @pytest.mark.skipif(str(14742) not in TESTS, reason='Excluded') def test_system_display_embedded_videos_with_attribution_14742(self): """Display embedded videos with attribution and a link back to author. Steps: Go to Tutor Click Login Sign in as student01 Click "HS AP Physics LG" Click on a homework assignment Click through it until you get to a video Click on the info icon on the video Expected Result: Attribution and links are displayed """ self.ps.test_updates['name'] = 't2.12.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.003', '14742'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # NOT DONE # create hw helper still not working # but works for manually created assignemnt, add assignemnt commented out # 14743 - 004 - Teacher | Each part of a multi-part question counts as a # seperate problem when scored @pytest.mark.skipif(str(14743) not in TESTS, reason='Excluded') def test_teacher_each_part_of_a_multipart_question_counts_as_14743(self): """Multi-part questions count as seperate problems when scored. Steps: Go to Tutor Click on the 'Login' button Log in as teacher03 Click "College Introduction to Sociology" Go to "Student Scores" Pick a homework that has multipart question Click "Review" Expected Result: There is a breadcrumb for each part of a multipart question """ self.ps.test_updates['name'] = 't2.12.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.004', '14743'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # create a hw with a multi part question, and gice it a randomized name # ID: 12061@6 is multi part self.teacher.login() self.teacher.find( By.XPATH, '//div[@data-appearance="intro_sociology"]' + '//a[not(contains(@href,"/cc-dashboard"))]').click() assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y') self.teacher.add_assignment(assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': { 'all': (begin, end) }, 'problems': { '1.1': ['12024@10'], }, 'status': 'publish', }) self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Student Scores').click() self.teacher.page.wait_for_page_load() # can just click the first review because assignemnt just created # and should be the most recent one self.teacher.find(By.LINK_TEXT, 'Review').click() cards = self.teacher.find_all(By.XPATH, '//div[contains(@class,"card-body")]') questions = self.teacher.find_all( By.XPATH, '//div[contains(@class,"openstax-question")]') breadcrumbs = self.teacher.find_all( By.XPATH, '//span[contains(@class,"openstax-breadcrumb")]') assert(len(questions) == len(breadcrumbs)), \ 'breadcrumbs and questions not equal' assert(len(cards) < len(breadcrumbs)), \ 'multipart question card has multiple questions,' + \ 'not matching up with breadcrumbs' self.ps.test_updates['passed'] = True # NOT DONE # same issue as above w/ add_homework helper # but works for manually created assignemnt # (add assignemnt gets commented out, manual assignemnt name added) # 14744 - 005 - Student | Each part of a multi-part question counts as a # seperate problem when scored @pytest.mark.skipif(str(14744) not in TESTS, reason='Excluded') def test_student_each_part_of_a_multipart_question_counts_as_14744(self): """Multi-part questions count as seperate problems when scored. Steps: Go to Tutor Click on the 'Login' button Log in as abarnes Click "College Introduction to Sociology" Click on a homework assignment Go through the questions Expected Result: There is a breadcrumb for each part in the multipart question and the progress/score is out of the total number of questions, rather than counting the multipart question as one question """ self.ps.test_updates['name'] = 't2.12.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.005', '14744'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # create a hw with a multi part question, and give it a randomized name # ID: 12252@5 is multi part self.teacher.login() self.teacher.find( By.XPATH, '//div[@data-appearance="intro_sociology"]' + '//a[not(contains(@href,"/cc-dashboard"))]').click() assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y') self.teacher.add_assignment(assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': { 'all': (begin, end) }, 'problems': { '1.1': ['12024@10'], }, 'status': 'publish', }) self.teacher.logout() # assignemnt name put here for manual testing # assignment_name = 'hw w/ video and multi part question' # login as student and go to same class self.student.login() self.teacher.find( By.XPATH, '//div[@data-appearance="intro_sociology"]' + '//a[not(contains(@href,"/cc-dashboard"))]').click() self.student.page.wait_for_page_load() # go to assignment (find my assignemnt_name) self.student.find( By.XPATH, '//a[contains(@class,"homework workable")]' + '//span[text()="' + assignment_name + '"]').click() # go through all questions breadcrumbs = self.teacher.find_all( By.XPATH, '//span[contains(@class,"openstax-breadcrumb")' + ' and not(contains(@class,"intro"))' + ' and not(contains(@class,"personalized"))' ' and not(contains(@class,"end"))]') total_questions = 0 found_multipart = False i = 0 while i < len(breadcrumbs): breadcrumbs[i].click() try: self.student.find(By.XPATH, '//span[text()="Multi-part question"]') found_multipart = True questions = self.teacher.find_all( By.XPATH, '//div[contains(@class,"openstax-question")]') total_questions += len(questions) i += len(questions) except NoSuchElementException: i += 1 questions = self.teacher.find_all( By.XPATH, '//div[contains(@class,"openstax-question")]') total_questions += len(questions) # check that everything worked out assert (found_multipart), 'no multipart question found' assert(total_questions == len(breadcrumbs)), \ 'breadcrumbs and questions not equal' self.ps.test_updates['passed'] = True
class TestEditCourseSettingsAndRoster(unittest.TestCase): """T1.42 - Edit Course Settings and Roster.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster') ) ).click() self.teacher.page.wait_for_page_load() def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C8258 - 001 - Teacher | Edit the course name @pytest.mark.skipif(str(8258) not in TESTS, reason='Excluded') def test_teacher_edit_the_course_name_8258(self): """Edit the course name. Steps: Click the "Rename Course" button that is next to the course name Enter a new course name Click the "Rename" button Click the X that is on the upper right corner of the dialogue box Expected Result: The course name is edited. (then put it back at the end) """ self.ps.test_updates['name'] = 't1.42.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.001', '8258'] self.ps.test_updates['passed'] = False # Test steps and verification assertions course_name = self.teacher.driver.find_element( By.XPATH, '//div[@class="course-settings-title"]/span' ).text self.teacher.find( By.XPATH, '//button[contains(@class,"edit-course")]' + '//span[contains(text(),"Rename Course")]' ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys('_EDIT') self.teacher.find( By.XPATH, '//button[contains(@class,"edit-course-confirm")]' ).click() # check that it was edited self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="course-settings-title"]' + '/span[contains(text(),"%s_EDIT")]' % course_name) ) ) # set it back self.teacher.sleep(1) self.teacher.driver.find_element( By.XPATH, '//button[contains(@class,"edit-course")]' + '//span[contains(text(),"Rename Course")]' ).click() for _ in range(len('_EDIT')): self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys(Keys.BACK_SPACE) self.teacher.find( By.XPATH, '//button[contains(@class,"edit-course-confirm")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="course-settings-title"]' + '/span[text()="%s"]' % course_name) ) ) self.ps.test_updates['passed'] = True # Case C8259 - 002 - Teacher | Remove an instructor from the course @pytest.mark.skipif(str(8259) not in TESTS, reason='Excluded') def test_teacher_remove_an_instructor_from_a_course_8259(self): """Remove an instructor from the course. Steps: Click "Remove" for an instructor under the Instructors section Click "Remove" on the box that pops up Expected Result: The instructor is removed from the Instructors list. """ self.ps.test_updates['name'] = 't1.42.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.002', '8259'] self.ps.test_updates['passed'] = False self.teacher.logout() # add extra instructor through admin first admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) admin.login() admin.get('https://tutor-qa.openstax.org/admin/courses/1/edit') admin.page.wait_for_page_load() teacher_name = 'Trent' admin.find( By.XPATH, '//a[contains(text(),"Teachers")]').click() admin.find( By.ID, 'course_teacher').send_keys(teacher_name) admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name) ) ).click() admin.sleep(1) admin.find( By.LINK_TEXT, 'Main Dashboard').click() admin.page.wait_for_page_load() admin.logout() # redo set-up, but make sure to go to course 1 self.teacher.login() self.teacher.get('https://tutor-qa.openstax.org/courses/1') self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster') ) ).click() self.teacher.page.wait_for_page_load() # delete teacher teachers_list = self.teacher.find_all( By.XPATH, '//div[@class="teachers-table"]//tbody//tr') for x in range(len(teachers_list)): temp_first = self.teacher.find( By.XPATH, '//div[@class="teachers-table"]//tbody//tr[' + str(x + 1) + ']/td' ).text if temp_first == teacher_name: self.teacher.find( By.XPATH, '//div[@class="teachers-table"]//tbody//tr[' + str(x + 1) + ']//td//span[contains(text(),"Remove")]' ).click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//div[@class="popover-content"]//button' ).click() break if x == len(teachers_list) - 1: print('added teacher was not found, and not deleted') raise Exception deleted_teacher = self.teacher.driver.find_elements( By.XPATH, '//td[contains(text(),"%s")]' % teacher_name) assert(len(deleted_teacher) == 0), 'teacher not deleted' self.ps.test_updates['passed'] = True # Case C8260 - 003 - Teacher | Remove the last instructor from the course @pytest.mark.skipif(str(8260) not in TESTS, reason='Excluded') def test_teacher_remove_the_last_instructor_from_the_course_8260(self): """Remove the last instructor from the course. Steps: Click on the user menu in the upper right corner of the page Click "Course Roster" Click "Remove" for an instructor under the Instructors section Click "Remove" on the box that pops up Expected Result: The instructor is removed from the Instructors list. """ self.ps.test_updates['name'] = 't1.42.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.003', '8260'] self.ps.test_updates['passed'] = False raise NotImplementedError(inspect.currentframe().f_code.co_name) self.teacher.logout() # add extra instructor through admin first admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) admin.login() admin.get('https://tutor-qa.openstax.org/admin/courses/1/edit') admin.page.wait_for_page_load() teacher_name = 'Trent' admin.find( By.XPATH, '//a[contains(text(),"Teachers")]').click() admin.find( By.ID, 'course_teacher').send_keys(teacher_name) admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name) ) ).click() admin.sleep(1) admin.find( By.LINK_TEXT, 'Main Dashboard').click() admin.page.wait_for_page_load() admin.logout() # redo set-up, but make sure to go to course 1 self.teacher.login() self.teacher.get('https://tutor-qa.openstax.org/courses/1') self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster') ) ).click() self.teacher.page.wait_for_page_load() # delete teacher teachers_list = self.teacher.find_all( By.XPATH, '//div[@class="teachers-table"]//tbody//tr') for x in range(len(teachers_list)): temp_first = self.teacher.find( By.XPATH, '//div[@class="teachers-table"]//tbody//tr[' + str(x + 1) + ']/td' ).text if temp_first == teacher_name: self.teacher.find( By.XPATH, '//div[@class="teachers-table"]//tbody//tr[' + str(x + 1) + ']//td//span[contains(text(),"Remove")]' ).click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//div[@class="popover-content"]//button' ).click() break if x == len(teachers_list) - 1: print('added teacher was not found, and not deleted') raise Exception deleted_teacher = self.teacher.driver.find_elements( By.XPATH, '//td[contains(text(),"%s")]' % teacher_name) assert(len(deleted_teacher) == 0), 'teacher not deleted' self.ps.test_updates['passed'] = True # Case C8261 - 004 - Teacher | Add a period @pytest.mark.skipif(str(8261) not in TESTS, reason='Excluded') def test_teacher_add_a_period_8261(self): """Add a period. Steps: Click "+ Add Period" Enter a period name into the Period Name text box Click "Add" Expected Result: A new period is added. """ self.ps.test_updates['name'] = 't1.42.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.004', '8261'] self.ps.test_updates['passed'] = False # Test steps and verification assertions period_name = 'automated_' + str(randint(0, 999)) self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button').click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys(period_name) self.teacher.find( By.XPATH, '//button[contains(@class,"edit-period-confirm")]' ).click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//a[contains(text(),"'+period_name+'")]') self.ps.test_updates['passed'] = True # Case C8262 - 005 - Teacher | Rename a period @pytest.mark.skipif(str(8262) not in TESTS, reason='Excluded') def test_teacher_rename_a_period_8262(self): """Rename a period. Steps: Click "Rename Period" Enter a new period name into the Period Name text box Click "Rename" Expected Result: A period is renamed. """ self.ps.test_updates['name'] = 't1.42.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.005', '8262'] self.ps.test_updates['passed'] = False # create a period period_name = 'automated_' + str(randint(0, 999)) self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button').click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys(period_name) self.teacher.find( By.XPATH, '//button[contains(@class,"edit-period-confirm")]' ).click() self.teacher.sleep(1) # edit the period self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"'+period_name+'")]') ) ).click() self.teacher.find( By.XPATH, '//span[contains(@class,"rename-period")]/button' ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys('_EDIT') self.teacher.find( By.XPATH, '//button[contains(@class,"edit-period-confirm")]' ).click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//a[contains(text(),"'+period_name+'_EDIT")]') self.ps.test_updates['passed'] = True # Case C8263 - 006 - Teacher | Archive an empty period @pytest.mark.skipif(str(8263) not in TESTS, reason='Excluded') def test_teacher_archive_an_empt_period_8263(self): """Archive an empty period. Steps: Click on an empty period Click "Archive Period" Click "Archive" on the dialogue box Expected Result: An empty period is archived. """ self.ps.test_updates['name'] = 't1.42.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.006', '8263'] self.ps.test_updates['passed'] = False # create a period period_name = 'automated_' + str(randint(0, 999)) self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button').click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys(period_name) self.teacher.find( By.XPATH, '//button[contains(@class,"edit-period-confirm")]' ).click() self.teacher.sleep(1) # edit the period self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"'+period_name+'")]') ) ).click() self.teacher.find( By.XPATH, '//a[contains(@class,"archive-period")]').click() self.teacher.find( By.XPATH, '//div[contains(@class,"popover-content")]' + '//button[contains(@class,"archive")]').click() self.teacher.sleep(2) archived_period = self.teacher.find_all( By.XPATH, '//a[contains(text(),"'+period_name+'")]') assert(len(archived_period) == 0), 'period not archived' self.ps.test_updates['passed'] = True # Case C8264 - 007 - Teacher | Archive a non-empty period @pytest.mark.skipif(str(8264) not in TESTS, reason='Excluded') def test_teacher_archive_a_non_empty_period_8264(self): """Archive a non-empty period. Steps: Click on a non-empty period Click "Archive Period" Click Archive Expected Result: Period is archived """ self.ps.test_updates['name'] = 't1.42.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.007', '8264'] self.ps.test_updates['passed'] = False # Test steps and verification assertions period_name = self.teacher.find( By.XPATH, '//ul[@role="tablist"]//a[@role="tab"]').text self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"'+period_name+'")]') ) ).click() self.teacher.find( By.XPATH, '//a[contains(@class,"archive-period")]').click() self.teacher.find( By.XPATH, '//div[contains(@class,"popover-content")]' + '//button[contains(@class,"archive")]').click() self.teacher.find( By.XPATH, '//span[contains(text(),"View Archived")]').click() self.teacher.find( By.XPATH, '//div[@class="modal-body"]//td[contains(text(),"' + period_name + '")]') # add the section back periods = self.teacher.find_all( By.XPATH, '//div[@class="modal-body"]//table//tbody//tr') for x in range(len(periods)): temp_period = self.teacher.find( By.XPATH, '//div[@class="modal-body"]//table//tbody' + '//tr['+str(x+1)+']/td').text if temp_period == period_name: self.teacher.find( By.XPATH, '//div[@class="modal-body"]//table//tbody//tr[' + str(x+1) + ']//button//span[contains(text(),"Unarchive")]' ).click() break self.ps.test_updates['passed'] = True # Case C8265 - 008 - Teacher | Move a student to another period @pytest.mark.skipif(str(8265) not in TESTS, reason='Excluded') def test_teacher_mover_a_student_to_another_period_8265(self): """Move a student to another period. Steps: Click on the user menu in the upper right corner of the page Click "Course Roster" Click "Change Period" for a student under the Roster section Click the desired period to move a student Expected Result: A student is moved to another period """ self.ps.test_updates['name'] = 't1.42.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.008', '8265'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.find( By.XPATH, '//a[@aria-describedby="change-period"]').click() student_name = self.teacher.find( By.XPATH, '//div[@class="roster"]//td').text element = self.teacher.find( By.XPATH, '//div[@class="popover-content"]//a') period_name = element.text element.click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//li/a[contains(text(),"'+period_name+'")]').click() self.teacher.driver.find_element( By.XPATH, '//td[contains(text(),"%s")]' % student_name) self.ps.test_updates['passed'] = True # Case C8266 - 009 - Teacher | Drop a student @pytest.mark.skipif(str(8266) not in TESTS, reason='Excluded') def test_teacher_drop_a_student_8266(self): """Drop a student. Steps: Click on the user menu in the upper right corner of the page Click "Course Roster" Click "Drop" for a student under the Roster section Click "Drop" in the box that pops up Expected Result: A student is dropped from the course and is put under the Dropped Students section """ self.ps.test_updates['name'] = 't1.42.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.009', '8266'] self.ps.test_updates['passed'] = False # Test steps and verification assertions student_name = self.teacher.find( By.XPATH, '//div[@class="roster"]//td').text self.teacher.find( By.XPATH, '//a[@aria-describedby="drop-student"]').click() self.teacher.find( By.XPATH, '//div[@class="popover-content"]//button').click() self.teacher.sleep(1) # check that student was droped self.teacher.find( By.XPATH, '//div[contains(@class,"dropped-students")]' + '//td[contains(text(),"%s")]' % student_name ) self.ps.test_updates['passed'] = True # Case C8267 - 010 - Teacher | Readd a dropped student @pytest.mark.skipif(str(8267) not in TESTS, reason='Excluded') def test_teacher_readd_a_dropped_student_8267(self): """Readd a dropped student. Steps: Click "Add Back to Active Roster" for a student under the Dropped Students section Click "Add" on the box that pops up Expected Result: A student is added back to the course """ self.ps.test_updates['name'] = 't1.42.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.010', '8267'] self.ps.test_updates['passed'] = False # drop a student (to make sure there is someone to add back) student_name = self.teacher.find( By.XPATH, '//div[@class="roster"]//td').text self.teacher.find( By.XPATH, '//a[@aria-describedby="drop-student"]').click() self.teacher.find( By.XPATH, '//div[@class="popover-content"]//button').click() self.teacher.sleep(1) # add a student back (not necessarily the same student) element = self.teacher.find( By.XPATH, '//div[contains(@class,"dropped-students")]' + '//span[contains(text(),"Add Back to Active Roster")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', element) self.teacher.driver.execute_script('window.scrollBy(0, -80);') element.click() self.teacher.find( By.XPATH, '//div[@class="popover-content"]//button').click() # check that student was added back self.teacher.find( By.XPATH, '//div[@class="roster"]//td[contains(text(),"%s")]' % student_name) self.ps.test_updates['passed'] = True # Case C58356 - 011 - Teacher | Unarchive an empty period @pytest.mark.skipif(str(58356) not in TESTS, reason='Excluded') def test_teacher_unarchive_an_empty_period_58356(self): """Unarchive an empty period. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account [ teacher001 ] and password in the boxes Click on the 'Sign in' button If the user has more than one course, click on a Tutor course name Click on the user menu in the upper right corner of the page Click "Course Settings and Roster" Click "View Archived Period(s)" Click Unarchived period next to selected course Expected Result: Period is made active. """ self.ps.test_updates['name'] = 't1.42.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.011', '58356'] self.ps.test_updates['passed'] = False # create a period period_name = 'automated_011_' + str(randint(0, 999)) self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button').click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@class,"form-control")]') ) ).send_keys(period_name) self.teacher.find( By.XPATH, '//button[contains(@class,"edit-period-confirm")]' ).click() self.teacher.sleep(1) # archive the period self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"'+period_name+'")]') ) ).click() self.teacher.find( By.XPATH, '//a[contains(@class,"archive-period")]').click() self.teacher.find( By.XPATH, '//div[contains(@class,"popover-content")]' + '//button[contains(@class,"archive")]').click() self.teacher.sleep(2) archived_period = self.teacher.find_all( By.XPATH, '//a[contains(text(),"'+period_name+'")]') assert(len(archived_period) == 0), 'period not archived' # unarchive the period self.teacher.find( By.XPATH, '//div[contains(@class,"view-archived-periods")]//button' ).click() self.teacher.sleep(1) rows = self.teacher.find_all( By.XPATH, '//div[@class="modal-content"]//tbody/tr') for row in rows: temp_name = row.find_element(By.XPATH, "./td[1]").text if temp_name == period_name: row.find_element( By.XPATH, "./td[3]//button[contains(@class,'unarchive-section')]" ).click() self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() break # check that period is no longer archived self.teacher.find( By.XPATH, '//a[contains(text(),"'+period_name+'")]') self.ps.test_updates['passed'] = True
class TestEditCourseSettingsAndRoster(unittest.TestCase): """T1.42 - Edit Course Settings and Roster.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.teacher = Teacher(use_env_vars=True) self.teacher.login() def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass # Case 162189 - 002 - Teacher | Move, Drop, and Readd a Student @pytest.mark.skipif(str(162189) not in TESTS, reason='Excluded') def test_teacher_mover_a_student_to_another_period_162189(self): """ #STEPS Go to Tutor Click on the 'Login' button Enter the teacher username [ ] in the username text box Click 'Next' Enter the teacher password [ ] in the password text box Click on the 'Login' button Click on a Tutor course name ***The user selects a course and is presented with the calendar dashboard.*** Click on the user menu in the upper right corner of the page Click "Course Settings and Roster" Click "Change Section" for a student under the student section Click the desired section to move a student Click the section the student was moved to ***A student is moved to another section*** Click "Drop" for a student under the student section Click "Drop" in the box that pops up ***A student is dropped from the course and is put under the Dropped Students section*** Click "Add Back to Active Roster" for a student under the Dropped Students section Click "Add" on the box that pops up # EXPECTED RESULT ***A student is added back to the course*** """ # Test steps and verification assertions self.ps.test_updates['name'] = 't1.42.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.008', '162189'] self.ps.test_updates['passed'] = False # Select a course and see the calendar dashboard self.teacher.select_course(appearance='intro_sociology') self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster'))).click() self.teacher.page.wait_for_page_load() # Move Students self.teacher.find(By.XPATH, '//a[@aria-describedby="change-period"]').click() student_name = self.teacher.find(By.XPATH, '//div[@class="roster"]//td').text element = self.teacher.find(By.XPATH, '//div[@class="popover-content"]//a') period_name = element.text element.click() self.teacher.sleep(1) self.teacher.find(By.XPATH, '//a/h2[contains(text(),"' + period_name + '")]').click() self.teacher.driver.find_element( By.XPATH, '//td[contains(text(),"%s")]' % student_name) # Drop Student student_name = self.teacher.find(By.XPATH, '//div[@class="roster"]//td').text self.teacher.find(By.XPATH, '//a[@aria-describedby="drop-student"]').click() self.teacher.find(By.XPATH, '//div[@class="popover-content"]//button').click() self.teacher.sleep(1) # check that student was dropped self.teacher.find( By.XPATH, '//div[contains(@class,"dropped-students")]' + '//td[contains(text(),"%s")]' % student_name) # Readd Student # add a student back (not necessarily the same student) self.teacher.find( By.XPATH, '//a[@aria-describedby="drop-student-popover-1216"]').click() self.teacher.find(By.XPATH, '//div[@class="popover-content"]//button').click() self.teacher.sleep(1) # check that student was added back self.teacher.find( By.XPATH, '//div[@class="roster"]//td[contains(text(),"%s")]' % student_name) self.ps.test_updates['passed'] = True
class TestTeacherViews(unittest.TestCase): """CC1.13 - Teacher Views.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C7609 - 001 - Teacher | View the Concept Coach dashboard @pytest.mark.skipif(str(7609) not in TESTS, reason='Excluded') def test_teacher_view_the_concept_coach_dashboard_7609(self): """View the Concept Coach dashboard. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: The user is presented with the Concept Coach dashbaord """ self.ps.test_updates['name'] = 'cc1.13.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.001', '7609'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('cc-dashboard' in self.teacher.current_url()), \ 'not at Concept Coach Dashboard' self.ps.test_updates['passed'] = True # Case C7610 - 002 - Teacher | Switch between concurrently running courses @pytest.mark.skipif(str(7610) not in TESTS, reason='Excluded') def test_teacher_switch_between_concurrently_running_courses_7610(self): """Able to switch between concurrently running courses. Steps: Click on the OpenStax logo in the left corner of the header Expected Result: The user is presented with a list of Concept Coach courses Is able to switch to another course """ self.ps.test_updates['name'] = 'cc1.13.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.002', '7610'] self.ps.test_updates['passed'] = False # Test steps and verification assertions url1 = self.teacher.current_url().split('courses')[1] self.teacher.driver.find_element( By.XPATH, '//a//i[@class="ui-brand-logo"]' ).click() try: self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard") ' + 'and not(contains(@href,"'+str(url1)+'"))]' ).click() except NoSuchElementException: print('Only one CC course, cannot go to another') raise Exception assert('cc-dashboard' in self.teacher.current_url()), \ 'not at Concept Coach Dashboard' assert(url1 != self.teacher.current_url()), \ 'went to same course' self.ps.test_updates['passed'] = True # Case C7611 - 003 - Teacher | View links on dashboard to course materials @pytest.mark.skipif(str(7611) not in TESTS, reason='Excluded') def test_teacher_view_links_on_dashboard_to_course_materials_7611(self): """View links on dashboard to course materials. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: On header there is a link to 'Homework PDF', and 'Online Book' """ self.ps.test_updates['name'] = 'cc1.13.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.003', '7611'] self.ps.test_updates['passed'] = False # HW pdf self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Homework PDF")]' ).click() coursename = self.teacher.driver.find_element( By.XPATH, '//div[@class="cc-dashboard"]/div' ).get_attribute('data-appearance') coursename = coursename.replace('_', '-') home = os.getenv("HOME") files = os.listdir(home + '/Downloads') for i in range(len(files)): if (coursename in files[i]) and (files[i][-4:] == '.pdf'): break else: if i == len(files)-1: raise Exception # online book self.teacher.driver.find_element( By.XPATH, '//a//span[contains(text(),"Online Book")]' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('cnx' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' self.teacher.driver.switch_to_window( self.teacher.driver.window_handles[0]) # assignment links self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Assignment Links")]' ).click() assert('assignment-links' in self.teacher.current_url()), \ 'not viewing Assignment Links' self.ps.test_updates['passed'] = True # Case C7612 - 004 - Teacher | Able to copy a system-generated message # with a student code, links, and other information @pytest.mark.skipif(str(7612) not in TESTS, reason='Excluded') def test_able_to_copy_a_system_generated_message_with_a_student_7612(self): """Copy a system-generated message with a student code, links, etc. Steps: Click on the user menu in the right corner of the header Click "Course Roster" Click "Get Student Enrollment Code" Copy the system generated message Expected Result: The user is able to copy the system generated message """ self.ps.test_updates['name'] = 'cc1.13.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.004', '7612'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Course Settings and Roster")]' ).click() self.teacher.driver.find_element( By.XPATH, '//span[contains(text(),"student enrollment code")]' ).click() self.teacher.driver.find_element( By.XPATH, '//*[contains(text(),"Send the following enrollment instruction")]' ) element = self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"enrollment-code-modal")]' ) element.find_element( By.XPATH, './/*[contains(text(),"To register for Concept Coach:")]' ) self.ps.test_updates['passed'] = True # Case C7613 - 005 - Teacher | Periods are relabeled as sections for all # courses @pytest.mark.skipif(str(7613) not in TESTS, reason='Excluded') def test_teacher_periods_are_relabeled_as_sections_for_all_cour_7613(self): """Period is relabeled as section for college courses. Steps: Go to user menu Click on course roster Check that there is an '+ add section' button instead of an '+ add period' button Expected Result: There is an '+ add section' button instead of an '+ add period' button """ self.ps.test_updates['name'] = 'cc1.13.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.005', '7613'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Course Settings and Roster")]' ).click() self.teacher.driver.find_element( By.XPATH, '//li[contains(@class,"add-period")]//span[text()="Section"]' ) self.ps.test_updates['passed'] = True # Case C7614 - 006 - Teacher | View a score report @pytest.mark.skipif(str(7614) not in TESTS, reason='Excluded') def test_teacher_view_a_score_report_7614(self): """View a score report. Steps: Click the user menu in the right corner of the header Click "Student Scores" Expected Result: The user is presented with a score report """ self.ps.test_updates['name'] = 'cc1.13.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.006', '7614'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.ps.test_updates['passed'] = True # Case C7615 - 007 - Teacher | View a report showing an individual # student's work pages @pytest.mark.skipif(str(7615) not in TESTS, reason='Excluded') def test_teacher_view_a_report_showing_an_individual_students_7615(self): """View a report showing an individual student's work pages. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on the percentage in the "Score" column Expected Result: Individual student's work is shown """ self.ps.test_updates['name'] = 'cc1.13.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.007', '7614'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() assert('steps' in self.teacher.current_url()), \ "Not taken to individual student's work for assignment" self.ps.test_updates['passed'] = True # Case C7616 - 008 - Teacher | View a summary report showing a class's work # pages @pytest.mark.skipif(str(7616) not in TESTS, reason='Excluded') def test_teacher_view_a_summary_report_showing_a_class_work_pag_7616(self): """View a summary report showing a class's work pages. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on the desired period tab Expected Result: The user is presented with a summary report """ self.ps.test_updates['name'] = 'cc1.13.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.008', '7616'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) periods = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"tab-item-period-name")]' ) for period in periods: period.click() self.ps.test_updates['passed'] = True # Case C7617 - 009 - Teacher | View the aggregate student scores @pytest.mark.skipif(str(7617) not in TESTS, reason='Excluded') def test_teacher_view_the_aggregate_student_scores_7617(self): """View the aggregate student scores. Steps: Click the user menu in the right corner of the header Click "Student Scores" Expected Result: The user is presented with Student scores """ self.ps.test_updates['name'] = 'cc1.13.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.009', '7617'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"course-scores-container")]') self.ps.test_updates['passed'] = True # Case C7618 - 010 - Teacher | View scores for an individual student's # scores @pytest.mark.skipif(str(7618) not in TESTS, reason='Excluded') def test_teacher_view_scores_for_an_individual_student_scores_7618(self): """View scores for an individual student's scores. Steps: Click the user menu in the right corner of the header Click "Student Scores" Scroll to the desired student Expected Result: The user is presented with scores for an individual student """ self.ps.test_updates['name'] = 'cc1.13.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.010', '7618'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"name-cell")]' ) self.ps.test_updates['passed'] = True # Case C7619 - 011 - Teacher | View an individual student's question set # for an assignment @pytest.mark.skipif(str(7619) not in TESTS, reason='Excluded') def test_teacher_view_an_individual_student_question_set_7619(self): """View an individual student's question set for an assignment. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on a student's score for the desired assignment Expected Result: The user is presented with a student's question set for the assignment """ self.ps.test_updates['name'] = 'cc1.13.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.011', '7619'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() breadcrumbs = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]' ) for i in range(len(breadcrumbs)-1): self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")' + 'and contains(@data-reactid,"step-' + str(i) + '")]' ).click() self.ps.test_updates['passed'] = True # Case C7620 - 012 - Teacher | View an assignment summary @pytest.mark.skipif(str(7620) not in TESTS, reason='Excluded') def test_teacher_view_an_assignment_summary_7620(self): """View an assignment summary. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on a student's score for the desired assignment Click "Summary" Expected Result: The user is presented with an assignmnent summary """ self.ps.test_updates['name'] = 'cc1.13.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.012', '7620'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")' + 'and contains(@data-reactid,"-end-")]' ).click() self.teacher.sleep(0.5) breadcrumbs_answered = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")' + 'and contains(@class,"completed")]' ) question_cards = self.teacher.driver.find_elements( By.XPATH, '//div[contains(@class,"openstax-exercise-card")]' ) assert(len(question_cards) == len(breadcrumbs_answered)), \ 'all answered questions not in summary' self.ps.test_updates['passed'] = True # Case C7622 - 013 - Teacher | Download student scores @pytest.mark.skipif(str(7622) not in TESTS, reason='Excluded') def test_teacher_download_student_scores_7622(self): """Download student scores. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click "Export" Expected Result: Student scores are downloaded in an excel spreadsheet """ self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"export-button")]//button' ).click() # wait for it to export. It says generating when still not done self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"export-button")]//button' + '//span[text()="Export"]') ) ) # check that it was downloaded coursename = self.teacher.driver.find_element( By.XPATH, '//div[@class="course-name"]').text coursename = coursename.replace(' ', '_') + "_Scores" home = os.getenv("HOME") files = os.listdir(home + '/Downloads') for i in range(len(files)): if (coursename in files[i]) and (files[i][-5:] == '.xlsx'): break else: if i == len(files)-1: raise Exception self.ps.test_updates['passed'] = True # Case C7624 - 014 - Teacher | Exercise IDs are shown for each assessment @pytest.mark.skipif(str(7624) not in TESTS, reason='Excluded') def test_teacher_exercise_ids_are_shown_for_each_assessment_7624(self): """Exercise IDs are shown for each assessment. Steps: Click the user menu in the right corner of the header Click "Question Library" Select a chapter Click "Show Questions" Expected Result: Exercise IDs are shown for each assessment in the bottom right hand corner of the box holding the question. """ self.ps.test_updates['name'] = 'cc1.13.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.014', '7624'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() breadcrumbs = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]' ) for i in range(len(breadcrumbs)-1): self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"exercise-identifier-link")]' + '//span[contains(text(),"ID")]' ) self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")' + 'and contains(@data-reactid,"step-' + str(i) + '")]' ).click() self.ps.test_updates['passed'] = True
class TestIImproveQuestionManagement(unittest.TestCase): """CC2.11 - Improve Question Management.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.student = Student(use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.teacher = Teacher(use_env_vars=True) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, ) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) self.student = None try: self.teacher.delete() except: pass # 14851 - 001 - Teacher | Review all questions @pytest.mark.skipif(str(14851) not in TESTS, reason='Excluded') def test_teacher_review_all_questions_14851(self): """Review all questions. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Expected Result: The user is presented with all the questions for the section or chapter """ self.ps.test_updates['name'] = 'cc2.11.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.001', '14851'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Question Library').click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.1"]').click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find(By.XPATH, '//button[text()="Show Questions"]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]'))) self.ps.test_updates['passed'] = True # 14852 - 002 - Teacher | Exclude certain questions @pytest.mark.skipif(str(14852) not in TESTS, reason='Excluded') def test_teacher_exclude_certain_questions_14852(self): """Exclude certain quesitons. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Hover over the desired question and click "Exclude question" Expected Result: Question is grayed out """ self.ps.test_updates['name'] = 'cc2.11.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.002', '14852'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Question Library').click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]').click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find(By.XPATH, '//button[text()="Show Questions"]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]'))) self.teacher.sleep(1) i = 1 question = None # loop finding a question that is not yet excleded # there are 9 question in the exact textbook and chpater this test # is searching. limiting loop at 7 incase questions are removed. while i < 8: question = self.teacher.find( By.XPATH, '//div[@class="exercises"]/div[' + str(i) + ']') if ('is-selected' not in question.get_attribute('class')): break i += 1 Assignment.scroll_to(self.teacher.driver, question) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(question) # way to stall because not sure how to add wait in action chain for _ in range(50): actions.move_by_offset(-1, 0) actions.click() actions.move_by_offset(-50, -300) actions.perform() self.teacher.sleep(0.5) question_excluded = self.teacher.find( By.XPATH, '//div[@class="exercises"]/div[' + str(i) + ']').get_attribute('class') assert ('is-selected' in question_excluded), 'question not excluded' self.ps.test_updates['passed'] = True ''' # 14855 - 003 - Teacher | Pin tabs on top of screen when scrolled @pytest.mark.skipif(str(14855) not in TESTS, reason='Excluded') def test_teacher_pin_tabs_on_top_of_screen_when_scrolled_14855(self): """Pin tabs on top of screen when scrolled. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Scroll down Expected Result: Tabs are pinned to top of the screen when scrolled """ self.ps.test_updates['name'] = 'cc2.11.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.003', '14855'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Question Library' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]' ).click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find( By.XPATH, '//button[text()="Show Questions"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]') ) ) self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="pinned-header"]') ) ) self.ps.test_updates['passed'] = True ''' # 14856 - 004 - Teacher | Make section links jumpable @pytest.mark.skipif(str(14856) not in TESTS, reason='Excluded') def test_teacher_make_section_links_jumpable_14856(self): """Make section links jumpable. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Click on the section links at the top of the screen Expected Result: The screen scrolls to the selected questions """ self.ps.test_updates['name'] = 'cc2.11.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.004', '14856'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Question Library').click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]').click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.1"]').click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find(By.XPATH, '//button[text()="Show Questions"]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]'))) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="pinned-header"]' '//div[@class="section" and text()="1.2"]'))).click() self.teacher.sleep(1) # click the heading as simple way to find that it is on screen # and not just visible but scrolled off screen self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercise-sections"]' + '//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]'))).click() self.ps.test_updates['passed'] = True # 14858 - 005 - Teacher | Report errata about assessments in Concept Coach @pytest.mark.skipif(str(14858) not in TESTS, reason='Excluded') def test_teacher_report_errata_about_assessments_in_cc_14858(self): """Report errata about assessments in Concept Coach. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Hover over the desired question and click "Question details" Click "Report an error" Expected Result: A new tab with the assessment errata form appears, with the assessment ID already filled in """ self.ps.test_updates['name'] = 'cc2.11.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.005', '14858'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Question Library').click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]').click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find(By.XPATH, '//button[text()="Show Questions"]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]'))) self.teacher.sleep(1) question = self.teacher.find(By.XPATH, '//div[@class="exercises"]/div[1]') actions = ActionChains(self.teacher.driver) actions.move_to_element(question) # way to stall because not sure how to add wait in action chain for _ in range(50): actions.move_by_offset(1, 0) actions.click() actions.perform() self.teacher.sleep(0.5) exercise_id = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="exercise-tag" and contains(text(),"ID:")]' ))).text question = self.teacher.find( By.XPATH, '//div[@class="action report-error"]').click() window_with_form = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_form) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[text()="Report Content Errors"]'))) self.teacher.find(By.XPATH, '//input[@value="' + exercise_id[4:] + '"]') self.ps.test_updates['passed'] = True # 14859 - 006 - Student | Report errata about assessments in Concept Coach @pytest.mark.skipif(str(14859) not in TESTS, reason='Excluded') def test_student_report_errata_about_assessments_in_cc_14859(self): """Report errata about assessments in Concept Coach. Steps: Click on a CC course, if there are more than one Click on a non-introductory section Click "Jump to Concept Coach" Click "Launch Concept Coach" Click "Report an error" on an assessment Expected Result: A new tab with the assessment errata form appears, with the assessment ID already filled in """ self.ps.test_updates['name'] = 'cc2.11.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.006', '14859'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.teacher.find(By.XPATH, '//a[contains(@href,"cnx.org/contents/")]').click() # get to non-into section self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button//span[text()="Contents"]'))).click() self.student.sleep(0.5) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]'))).click() # open concept coach self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach'))).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]'))).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class,"core breadcrumb-exercise")]' ))).click() exercise_id = self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="exercise-identifier-link"]' + '/span[contains(text(),"@")]'))).text self.teacher.find(By.LINK_TEXT, 'Report an error').click() window_with_form = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_form) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[text()="Report Content Errors"]'))) self.teacher.find(By.XPATH, '//input[@value="' + exercise_id + '"]') self.ps.test_updates['passed'] = True # 100129 - 007 - Admin | View list of excluded assesments @pytest.mark.skipif(str(100129) not in TESTS, reason='Excluded') def test_admin_view_list_of_excluded_assesments_100129(self): """View list of excluded assesments. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc2.11.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc2', 'cc2.11', 'cc2.11.007', '100129' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 100130 - 008 - Admin | Export the list of excluded assesments to CSV @pytest.mark.skipif(str(100130) not in TESTS, reason='Excluded') def test_admin_export_the_list_of_excluded_assesments_to_csv_100130(self): """Export the list of excluded assesments to CSV. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc2.11.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc2', 'cc2.11', 'cc2.11.008', '100130' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
class TestImproveCourseManagement(unittest.TestCase): """T2.07 - Improve Course Management.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.admin = Admin( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities, existing_driver=self.teacher.driver ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.admin = None self.teacher.delete() except: pass # 14651 - 001 - Admin | View Student Use Statistics for Concept Coach # college assessments @pytest.mark.skipif(str(14651) not in TESTS, reason='Excluded') def test_admin_view_student_use_statistics_for_cc_college_asse_14651(self): """View Student Use Statistics for Concept Coach college assessments. Steps: Go to Tutor Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click "Admin" in the user menu Click "Stats" Click "Concept Coach" Expected Result: The user is presented with Concept Coach statistics """ self.ps.test_updates['name'] = 't2.07.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.001', '14651' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.goto_admin_control() self.admin.sleep(5) self.admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Stats') ) ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Concept Coach') ) ).click() assert('/stats/concept_coach' in self.admin.current_url()), \ 'Not viewing Concept Coach stats' self.ps.test_updates['passed'] = True # 14652 - 002 - Teacher | Delegate teaching tasks to supporting instructors @pytest.mark.skipif(str(14652) not in TESTS, reason='Excluded') def test_teacher_delegate_teaching_tasks_to_supporting_instruc_14652(self): """Delegate teaching tasks to supporting instructors. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.002', '14652' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 14653 - 003 - Teacher | Move a student and their data to a new section @pytest.mark.skipif(str(14653) not in TESTS, reason='Excluded') def test_teacher_move_a_student_and_their_data_to_new_section_14653(self): """Move a student and their data to a new section. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the user menu Click "Change Period" for the desired student and select a period Expected Result: Student is moved to new section with their data """ self.ps.test_updates['name'] = 't2.07.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.003', '14653' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Move the student to another period first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Change Period").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() self.teacher.sleep(5) # Verify the move, then move the student back to the original period self.teacher.find( By.XPATH, "//div[@class='roster']/div[@class='settings-section periods']" + "/ul[@class='nav nav-tabs']/li[2]/a").click() roster = self.teacher.driver.find_elements_by_xpath( "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr") index = 0 for student in roster: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Change Period")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() break index += 1 self.teacher.sleep(2) self.teacher.find( By.XPATH, "//div[@class='roster']/div[@class='settings-section periods']" + "/ul[@class='nav nav-tabs']/li[1]/a").click() roster = self.teacher.driver.find_elements_by_xpath( "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr") assert(first in roster[0].text and last in roster[0].text), \ 'error' self.ps.test_updates['passed'] = True # 14655 - 004 - Teacher | Drop a student from a section and hide their data @pytest.mark.skipif(str(14655) not in TESTS, reason='Excluded') def test_teacher_drop_student_from_section_and_hide_their_data_14655(self): """Drop a student from a section and hide their data. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the user menu Click "Drop" for the desired student Expected Result: The student appears under the "Dropped Students" section """ self.ps.test_updates['name'] = 't2.07.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.004', '14655' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Drop the student first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Drop").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-drop-student btn btn-danger']").click() self.teacher.sleep(5) # Verify the student was dropped and add back to active roster dropped = self.teacher.driver.find_elements_by_xpath( "//div[@class='settings-section dropped-students']/table[@class" + "='roster table table-striped table-bordered table-condensed " + "table-hover']/tbody/tr") index = 0 for student in dropped: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Add Back to Active Roster")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-undrop-student btn btn-success']" ).click() self.teacher.sleep(20) break index += 1 self.ps.test_updates['passed'] = True # 14656 - 005 - Teacher | Drop a student from a section and don't hide # their data @pytest.mark.skipif(str(14656) not in TESTS, reason='Excluded') def test_teacher_drop_a_student_from_section_and_dont_hide_dat_14656(self): """Drop a student from a section and don't hide their data. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.005', '14656' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 14657 - 006 - Teacher | In Student Scores dropped students are not # displayed @pytest.mark.skipif(str(14657) not in TESTS, reason='Excluded') def test_teacher_in_student_scores_dropped_students_are_not_14657(self): """In Student Scores dropped students are not displayed. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the calendar dashboard Click "Drop" for the desired student Click "Student Scores" from the user menu Click on the period from which you have dropped the student Expected Result: Dropped student should not be displayed in Student Scores """ self.ps.test_updates['name'] = 't2.07.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.006', '14657' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Drop the student first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Drop").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-drop-student btn btn-danger']").click() self.teacher.sleep(5) # Go to student scores, verify the student is not seen self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Student Scores").click() self.teacher.sleep(10) odd_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedData" + "TableRow_main public_fixedDataTableRow_even public_fixedDataTa" + "ble_bodyRow']/div[@class='fixedDataTableRowLayout_body']/div" + "[@class='fixedDataTableCellGroupLayout_cellGroupWrapper'][1]/d" + "iv[@class='fixedDataTableCellGroupLayout_cellGroup']/div[@clas" + "s='fixedDataTableCellLayout_main public_fixedDataTableCell_" + "main'][1]/div[@class='fixedDataTableCellLayout_wrap1 public_fi" + "xedDataTableCell_wrap1']/div[@class='fixedDataTableCellLayout_w" + "rap2 public_fixedDataTableCell_wrap2']/div[@class='fixedDataTab" + "leCellLayout_wrap3 public_fixedDataTableCell_wrap3']/div[@class" + "='name-cell']/a[@class='student-name public_fixedDataTableCell" + "_cellContent']") even_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedDataTab" + "leRow_main public_fixedDataTableRow_highlighted public_fixedDa" + "taTableRow_odd public_fixedDataTable_bodyRow']/div[@class='fix" + "edDataTableRowLayout_body']/div[@class='fixedDataTableCellGrou" + "pLayout_cellGroupWrapper'][1]/div[@class='fixedDataTableCellGr" + "oupLayout_cellGroup']/div[@class='fixedDataTableCellLayout_mai" + "n public_fixedDataTableCell_main'][1]/div[@class='fixedDataTab" + "leCellLayout_wrap1 public_fixedDataTableCell_wrap1']/div[@clas" + "s='fixedDataTableCellLayout_wrap2 public_fixedDataTableCell_wr" + "ap2']/div[@class='fixedDataTableCellLayout_wrap3 public_fixedD" + "ataTableCell_wrap3']/div[@class='name-cell']/a[@class='student" + "-name public_fixedDataTableCell_cellContent']") found = False for student in odd_scores: if student.text.find(first) >= 0 and student.text.find(last) >= 0: found = True break if not found: for stud in even_scores: if stud.text.find(first) >= 0 and stud.text.find(last) >= 0: found = True break # Add back to active roster self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() dropped = self.teacher.driver.find_elements_by_xpath( "//div[@class='settings-section dropped-students']/table[@class" + "='roster table table-striped table-bordered table-condensed ta" + "ble-hover']/tbody/tr") index = 0 for student in dropped: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Add Back to Active Roster")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-undrop-student btn btn-success']" ).click() self.teacher.sleep(20) break index += 1 if not found: self.ps.test_updates['passed'] = True # 14850 - 007 - Teacher | In Student Scores view moved students @pytest.mark.skipif(str(14850) not in TESTS, reason='Excluded') def test_teacher_in_student_scores_view_moved_students_14850(self): """In Student Scores view moved students. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the calendar dashboard Click "Change Period" for the desired student Click on the desired period Click "Student Scores" from the user menu Click on the period to which the student was moved Expected Result: The user is presented with the moved student under their new period """ self.ps.test_updates['name'] = 't2.07.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.007', '14850' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Move the student to another period first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Change Period").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() self.teacher.sleep(5) # Go to student scores, verify the student is seen self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Student Scores").click() self.teacher.sleep(10) self.teacher.find( By.XPATH, "//nav[@class='collapse in']/ul[@class='nav nav-tabs']/li[2]/a" ).click() odd_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedData" + "TableRow_main public_fixedDataTableRow_even public_fixedDataTa" + "ble_bodyRow']/div[@class='fixedDataTableRowLayout_body']/div" + "[@class='fixedDataTableCellGroupLayout_cellGroupWrapper'][1]/d" + "iv[@class='fixedDataTableCellGroupLayout_cellGroup']/div[@clas" + "s='fixedDataTableCellLayout_main public_fixedDataTableCell_" + "main'][1]/div[@class='fixedDataTableCellLayout_wrap1 public_fi" + "xedDataTableCell_wrap1']/div[@class='fixedDataTableCellLayout_w" + "rap2 public_fixedDataTableCell_wrap2']/div[@class='fixedDataTab" + "leCellLayout_wrap3 public_fixedDataTableCell_wrap3']/div[@class" + "='name-cell']/a[@class='student-name public_fixedDataTableCell" + "_cellContent']") even_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedDataTab" + "leRow_main public_fixedDataTableRow_highlighted public_fixedDa" + "taTableRow_odd public_fixedDataTable_bodyRow']/div[@class='fix" + "edDataTableRowLayout_body']/div[@class='fixedDataTableCellGrou" + "pLayout_cellGroupWrapper'][1]/div[@class='fixedDataTableCellGr" + "oupLayout_cellGroup']/div[@class='fixedDataTableCellLayout_mai" + "n public_fixedDataTableCell_main'][1]/div[@class='fixedDataTab" + "leCellLayout_wrap1 public_fixedDataTableCell_wrap1']/div[@clas" + "s='fixedDataTableCellLayout_wrap2 public_fixedDataTableCell_wr" + "ap2']/div[@class='fixedDataTableCellLayout_wrap3 public_fixedD" + "ataTableCell_wrap3']/div[@class='name-cell']/a[@class='student" + "-name public_fixedDataTableCell_cellContent']") found = False for student in odd_scores: if student.text.find(first) >= 0 and student.text.find(last) >= 0: found = True break if found: for stud in even_scores: if stud.text.find(first) >= 0 and stud.text.find(last) >= 0: found = True break # Add student back to original period self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(10) self.teacher.find( By.XPATH, "//div[@class='roster']/div[@class='settings-section periods']" + "/ul[@class='nav nav-tabs']/li[2]/a").click() roster = self.teacher.driver.find_elements_by_xpath( "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr") index = 0 for student in roster: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Change Period")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() break index += 1 if found: self.ps.test_updates['passed'] = True # 14658 - 008 - Teacher | Require emails for all students for roster import @pytest.mark.skipif(str(14658) not in TESTS, reason='Excluded') def test_teacher_require_emails_for_all_students_for_roster_14658(self): """Require emails for all students for roster imports. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.008', '14658' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 14660 - 009 - Teacher | Set time zone for a course @pytest.mark.skipif(str(14660) not in TESTS, reason='Excluded') def test_teacher_set_time_zone_for_a_course_14660(self): """Set time zone for a course. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" Click "Change Course Timezone" Select the desired timezone Click Save Expected Result: The time zone is set """ self.ps.test_updates['name'] = 't2.07.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.009', '14660' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Change the timezone self.teacher.driver.find_elements_by_xpath( "//button[@class='edit-course btn btn-link']")[1].click() self.teacher.sleep(2) self.teacher.find( By.XPATH, "//div[@class='tutor-radio']/label").click() self.teacher.find( By.XPATH, "//button[@class='async-button -edit-course-" + "confirm btn btn-default']").click() self.teacher.sleep(5) # Verify the change and change the time back to Central self.teacher.driver.find_elements_by_xpath( "//button[@class='edit-course btn btn-link']")[1].click() assert('Central Time' not in self.teacher.find( By.XPATH, "//div[@class='tutor-radio active']/label").text), \ 'Not viewing Concept Coach stats' self.teacher.sleep(2) options = self.teacher.driver.find_elements_by_xpath( "//div[@class='tutor-radio']/label") for timezone in options: if timezone.text.find('Central Time') >= 0: timezone.click() break self.teacher.find( By.XPATH, "//button[@class='async-button -edit-course-" + "confirm btn btn-default']").click() self.ps.test_updates['passed'] = True # 14661 - 010 - System | Distinguish between high school and college # courses @pytest.mark.skipif(str(14661) not in TESTS, reason='Excluded') def test_system_distinguish_between_hs_and_college_courses_14661(self): """Distinguish between high school and college courses. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.010', '14661' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
class TestTeacherViews(unittest.TestCase): """CC1.13 - Teacher Views.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) else: self.teacher = Teacher( use_env_vars=True ) self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//p[contains(text(),"OpenStax Concept Coach")]' ).click() def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C7609 - 001 - Teacher | View the Concept Coach dashboard @pytest.mark.skipif(str(7609) not in TESTS, reason='Excluded') def test_teacher_view_the_concept_coach_dashboard_7609(self): """View the Concept Coach dashboard. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: The user is presented with the Concept Coach dashbaord """ self.ps.test_updates['name'] = 'cc1.13.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.001', '7609'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.driver.find_element( By.XPATH, "//span[text()='Class Dashboard']" ) self.ps.test_updates['passed'] = True # Case C7610 - 002 - Teacher | Switch between concurrently running courses @pytest.mark.skipif(str(7610) not in TESTS, reason='Excluded') def test_teacher_switch_between_concurrently_running_courses_7610(self): """Able to switch between concurrently running courses. Steps: Click on the OpenStax logo in the left corner of the header Expected Result: The user is presented with a list of Concept Coach courses Is able to switch to another course """ self.ps.test_updates['name'] = 'cc1.13.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.002', '7610'] self.ps.test_updates['passed'] = False # Test steps and verification assertions url1 = self.teacher.current_url().split('course')[1] self.teacher.find( By.XPATH, '//a//i[@class="ui-brand-logo"]' ).click() try: self.teacher.find( By.XPATH, '//a[not(contains(@href,"' + url1 + '"))]' + '/p[contains(text(),"OpenStax Concept Coach")]' ).click() except NoSuchElementException: print('Only one CC course, cannot go to another') raise Exception # assert that user at cc dashboard self.teacher.driver.find_element( By.XPATH, "//span[text()='Class Dashboard']" ) assert(url1 != self.teacher.current_url()), \ 'went to same course' self.ps.test_updates['passed'] = True # Case C7611 - 003 - Teacher | View links on dashboard to course materials @pytest.mark.skipif(str(7611) not in TESTS, reason='Excluded') def test_teacher_view_links_on_dashboard_to_course_materials_7611(self): """View links on dashboard to course materials. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: On header there is a link to 'Homework PDF', and 'Online Book' """ self.ps.test_updates['name'] = 'cc1.13.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.003', '7611'] self.ps.test_updates['passed'] = False # HW pdf self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Homework PDF")]' ).click() coursename = self.teacher.driver.find_element( By.XPATH, '//div[@class="cc-dashboard"]/div[@data-appearance]' ).get_attribute('data-appearance') coursename = coursename.split('_') home = os.getenv("HOME") files = os.listdir(home + '/Downloads') for i in range(len(files)): match = True for word in coursename: if not ((word in files[i]) and (files[i][-4:] == '.pdf')): match = False break if match: break else: if i == len(files)-1: print("textbok pdf not downloaded") raise Exception # online book self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Online Book")]' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('cnx' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' self.teacher.driver.switch_to_window( self.teacher.driver.window_handles[0]) # assignment links self.teacher.driver.find_element( By.XPATH, '//a[contains(text(),"Assignment Links")]' ).click() assert('assignment-links' in self.teacher.current_url()), \ 'not viewing Assignment Links' self.ps.test_updates['passed'] = True # Case C7612 - 004 - Teacher | Able to copy a system-generated message # with a student code, links, and other information @pytest.mark.skipif(str(7612) not in TESTS, reason='Excluded') def test_able_to_copy_a_system_generated_message_with_a_student_7612(self): """Copy a system-generated message with a student code, links, etc. Steps: Click on the user menu in the right corner of the header Click "Course Roster" Click "Get Student Enrollment Code" Copy the system generated message Expected Result: The user is able to copy the system generated message """ self.ps.test_updates['name'] = 'cc1.13.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.004', '7612'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a/div[contains(text(),"Course Settings and Roster")]' ).click() self.teacher.driver.find_element( By.XPATH, '//span[contains(text(),"enrollment")]' ).click() self.teacher.find( By.XPATH, '//span[contains(text(),"Send enrollment instructions")]' ) self.ps.test_updates['passed'] = True # Case C7613 - 005 - Teacher | Periods are relabeled as sections for all # courses @pytest.mark.skipif(str(7613) not in TESTS, reason='Excluded') def test_teacher_periods_are_relabeled_as_sections_for_all_cour_7613(self): """Period is relabeled as section for college courses. Steps: Go to user menu Click on course roster Check that there is an '+ add section' button instead of an '+ add period' button Expected Result: There is an '+ add section' button instead of an '+ add period' button """ self.ps.test_updates['name'] = 'cc1.13.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.005', '7613'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Course Settings and Roster")]' ).click() self.teacher.find( By.XPATH, '//button[contains(@class,"add-period")]//span[text()="Section"]' ) self.ps.test_updates['passed'] = True # Case C7614 - 006 - Teacher | View a score report @pytest.mark.skipif(str(7614) not in TESTS, reason='Excluded') def test_teacher_view_a_score_report_7614(self): """View a score report. Steps: Click the user menu in the right corner of the header Click "Student Scores" Expected Result: The user is presented with a score report """ self.ps.test_updates['name'] = 'cc1.13.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.006', '7614'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.ps.test_updates['passed'] = True # Case C7615 - 007 - Teacher | View a report showing an individual # student's work pages @pytest.mark.skipif(str(7615) not in TESTS, reason='Excluded') def test_teacher_view_a_report_showing_an_individual_students_7615(self): """View a report showing an individual student's work pages. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on the percentage in the "Score" column Expected Result: Individual student's work is shown """ self.ps.test_updates['name'] = 'cc1.13.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.007', '7614'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() assert('step' in self.teacher.current_url()), \ "Not taken to individual student's work for assignment" self.ps.test_updates['passed'] = True # Case C7616 - 008 - Teacher | View a summary report showing a class's work # pages @pytest.mark.skipif(str(7616) not in TESTS, reason='Excluded') def test_teacher_view_a_summary_report_showing_a_class_work_pag_7616(self): """View a summary report showing a class's work pages. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on the desired period tab Expected Result: The user is presented with a summary report """ self.ps.test_updates['name'] = 'cc1.13.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.008', '7616'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) periods = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"tab-item-period-name")]' ) for period in periods: period.click() self.ps.test_updates['passed'] = True # Case C7617 - 009 - Teacher | View the aggregate student scores @pytest.mark.skipif(str(7617) not in TESTS, reason='Excluded') def test_teacher_view_the_aggregate_student_scores_7617(self): """View the aggregate student scores. Steps: Click the user menu in the right corner of the header Click "Student Scores" Expected Result: The user is presented with Student scores """ self.ps.test_updates['name'] = 'cc1.13.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.009', '7617'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"course-scores-container")]') self.ps.test_updates['passed'] = True # Case C7618 - 010 - Teacher | View scores for an individual student's # scores @pytest.mark.skipif(str(7618) not in TESTS, reason='Excluded') def test_teacher_view_scores_for_an_individual_student_scores_7618(self): """View scores for an individual student's scores. Steps: Click the user menu in the right corner of the header Click "Student Scores" Scroll to the desired student Expected Result: The user is presented with scores for an individual student """ self.ps.test_updates['name'] = 'cc1.13.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.010', '7618'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"name-cell")]' ) self.ps.test_updates['passed'] = True # Case C7619 - 011 - Teacher | View an individual student's question set # for an assignment @pytest.mark.skipif(str(7619) not in TESTS, reason='Excluded') def test_teacher_view_an_individual_student_question_set_7619(self): """View an individual student's question set for an assignment. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on a student's score for the desired assignment Expected Result: The user is presented with a student's question set for the assignment """ self.ps.test_updates['name'] = 'cc1.13.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.011', '7619'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() breadcrumbs = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]' ) for i in range(len(breadcrumbs)-1): self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]' + '[' + str(i + 1) + ']' ).click() self.ps.test_updates['passed'] = True # Case C7620 - 012 - Teacher | View an assignment summary @pytest.mark.skipif(str(7620) not in TESTS, reason='Excluded') def test_teacher_view_an_assignment_summary_7620(self): """View an assignment summary. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click on a student's score for the desired assignment Click "Summary" Expected Result: The user is presented with an assignmnent summary """ self.ps.test_updates['name'] = 'cc1.13.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.012', '7620'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.driver.find_element( By.XPATH, '//div[contains(@class,"scores-cell")]' + '/div[@class="score"]' ).click() self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"breadcrumb-end")]' ).click() self.teacher.sleep(0.5) breadcrumbs_answered = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")' + 'and contains(@class,"completed")]' ) question_cards = self.teacher.driver.find_elements( By.XPATH, '//div[contains(@class,"openstax-exercise-card")]' ) assert(len(question_cards) == len(breadcrumbs_answered)), \ 'all answered questions not in summary' self.ps.test_updates['passed'] = True # Case C7622 - 013 - Teacher | Download student scores @pytest.mark.skipif(str(7622) not in TESTS, reason='Excluded') def test_teacher_download_student_scores_7622(self): """Download student scores. Steps: Click the user menu in the right corner of the header Click "Student Scores" Click "Export" Expected Result: Student scores are downloaded in an excel spreadsheet """ self.ps.test_updates['name'] = 'cc1.13.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.013', '7622'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.find( By.XPATH, '//div[contains(@class,"export-button")]//button' ).click() # wait for it to export. It says generating when still not done self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"export-button")]//button') ) ) # sleep to make sure the contents is downloaded self.teacher.sleep(5) # check that it was downloaded coursename = self.teacher.driver.find_element( By.XPATH, '//div[@class="course-name"]').text coursename = coursename.split(' ')[0].replace(' ', '') home = os.getenv("HOME") files = os.listdir(home + '/Downloads') for i in range(len(files)): if (coursename in files[i]) and ('Scores' in files[i]) \ and (files[i][-5:] == '.xlsx'): break else: if i == len(files)-1: print(coursename) raise Exception self.ps.test_updates['passed'] = True # Case C7624 - 014 - Teacher | Exercise IDs are shown for each assessment @pytest.mark.skipif(str(7624) not in TESTS, reason='Excluded') def test_teacher_exercise_ids_are_shown_for_each_assessment_7624(self): """Exercise IDs are shown for each assessment. Steps: Click the user menu in the right corner of the header Click "Question Library" Select a chapter Click "Show Questions" Expected Result: Exercise IDs are shown for each assessment in the bottom right hand corner of the box holding the question. """ self.ps.test_updates['name'] = 'cc1.13.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.014', '7624'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="score"]') ) ).click() breadcrumbs = self.teacher.find_all( By.XPATH, '//span[contains(@class,"breadcrumb")]') for i in range(len(breadcrumbs)-1): self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"exercise-identifier-link")' + ' and contains(text(),"ID")]' ) self.teacher.driver.find_element( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]' + '[' + str(i + 2) + ']' ).click() self.ps.test_updates['passed'] = True # Case C111251 - 015 - Teacher | Student score columns do not show a due # date @pytest.mark.skipif(str(111251) not in TESTS, reason='Excluded') def test_teacher_student_score_columns_so_not_show_a_due_date_111251(self): """Student score columns do not show a due date. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.13.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.13', 'cc1.13.015', '111251' ] self.ps.test_updates['passed'] = False self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) assert(len(self.teacher.find_all(By.CSS_SELECTOR, 'div.Due')) == 0), \ 'Due date is present' # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.driver.find_element( By.XPATH, '//a/div[contains(text(),"Student Scores")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Student Scores"]') ) ) date_cells = self.teacher.find_all( By.XPATH, '//div[@class="header-cell-wrapper"]//div[@class="header-row"]' ) for i in range(len(date_cells)-1): assert(date_cells[i].text == ""), "date cell is not empty" self.ps.test_updates['passed'] = True
class TestGuideMonitorSupportAndTrainUsers(unittest.TestCase): """T2.18 - Guide, Monitor, Support, and Train Users.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) else: self.teacher = Teacher( use_env_vars=True ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, ) self.admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, ) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.student.driver = None self.admin.driver = None self.teacher.delete() except: pass # C14752 - 001 - User | In-app Notification of downtime @pytest.mark.skipif(str(14752) not in TESTS, reason='Excluded') def test_user_inapp_notification_of_downtime_14752(self): """In-app Notification of downtime. Steps: Go to Tutor Log in as admin Click "Admin" from the user menu Click "System Setting" Click "Notifications" Enter a new notification into the text box Click "Add" Log out of admin Log in as teacher01 Expected Result: An orange header with the notification pops up when you sign in """ self.ps.test_updates['name'] = 't2.18.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.001', '14752'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # create notification self.admin.login() self.admin.open_user_menu() self.admin.find(By.LINK_TEXT, 'Admin').click() self.admin.find(By.XPATH, '//a[text()="System Setting"]').click() self.admin.find(By.XPATH, '//a[text()="Notifications"]').click() self.admin.find(By.ID, 'message') \ .send_keys("test_notification") self.admin.find(By.XPATH, '//input[@value="Add"]').click() self.admin.find(By.XPATH, '//a[text()="admin "]').click() self.admin.find(By.XPATH, '//a[text()="Sign out!"]').click() # check that the notification appears self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//div[contains(@class,"notifications-bar")]' + '//span[text()="test_notification"]' )) ) self.teacher.find( By.XPATH, '//div[contains(@class,"notifications-bar")]' + '//span[text()="test_notification"]' ) self.teacher.logout() # remove notification self.admin.login() self.admin.open_user_menu() self.admin.find(By.LINK_TEXT, 'Admin').click() self.admin.find(By.XPATH, '//a[text()="System Setting"]').click() self.admin.find(By.XPATH, '//a[text()="Notifications"]').click() self.admin.find(By.XPATH, '//a[text()="Remove"]').click() self.admin.driver.switch_to_alert().accept() self.ps.test_updates['passed'] = True # C14751 - 002 - Teacher | Directed to a "No Courses" page when not in any # courses yet @pytest.mark.skipif(str(14751) not in TESTS, reason='Excluded') def test_teacher_directed_to_a_no_courses_page_when_not_in_any_14751(self): """Directed to a "No Courses" page when not in any courses yet. Steps: Go to Tutor Sign in as a teacher without a course Expected Result: The message "We cannot find an OpenStax course associated with your account" displays with help links below. """ self.ps.test_updates['name'] = 't2.18.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.002', '14751'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login( username='******', password=os.getenv('CONTENT_PASSWORD') ) self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//p[contains(text(),"cannot find an ' + 'OpenStax course associated")]' )) ) self.ps.test_updates['passed'] = True # C58279 - 003 - Teacher | View "Getting Started with Tutor" Guide @pytest.mark.skipif(str(58279) not in TESTS, reason='Excluded') def test_teacher_view_getting_started_with_tutor_guide_58279(self): """View "Getting Started with Tutor" Guide. Steps: Click "Tutor Instructors. Get help" Expected Result: Tutor Help Center opens in another tab with the Getting Started guide """ self.ps.test_updates['name'] = 't2.18.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.003', '58279'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('getting started') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() raise NotImplementedError(inspect.currentframe().f_code.co_name) self.teacher.find(By.XPATH, '//h1[contains(text(),"Getting Started")]') assert('articles' in self.teacher.current_url()), 'not at article' self.ps.test_updates['passed'] = True # C58280 - 004 - Teacher | Access Tutor Help Center after registering for # a course @pytest.mark.skipif(str(58280) not in TESTS, reason='Excluded') def test_teacher_access_tutor_help_center_after_registering_58280(self): """Access Tutor Help Center after registering for a course. Steps: Go to Tutor Sign in as teacher01 Click on a Tutor course if the user is in more than one Click "Get Help" from the user menu in the upper right corner of the screen Expected Result: The user is presented with the Tutor Help Center """ self.ps.test_updates['name'] = 't2.18.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.004', '58280'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Tutor Support")]' ) self.ps.test_updates['passed'] = True # C58284 - 005 - User | Submit a question @pytest.mark.skipif(str(58284) not in TESTS, reason='Excluded') def test_user_submit_a_question_58284(self): """Submit a question. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Expected Result: The user is presented with search results """ self.ps.test_updates['name'] = 't2.18.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.005', '58284'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'results') self.teacher.find(By.CSS_SELECTOR, 'div.article') self.ps.test_updates['passed'] = True # 58352 - 006 - User | View "Contact Us" button after submitting a # question @pytest.mark.skipif(str(58352) not in TESTS, reason='Excluded') def test_user_view_contact_us_button_after_submitting_question_58352(self): """View "Contact Us" button after submitting a question. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Scroll to the bottom of the screen Expected Result: "Contact Us" button exists """ self.ps.test_updates['name'] = 't2.18.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.006', '58352'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.XPATH, '//a[contains(text(),"Email Us")]') self.ps.test_updates['passed'] = True # C58288 - 007 - User | View an article after submitting a question @pytest.mark.skipif(str(58288) not in TESTS, reason='Excluded') def test_user_view_an_article_after_submitting_a_question_58288(self): """View an article after submitting a question. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Expected Result: The user is presented with an article containing answer to the question """ self.ps.test_updates['name'] = 't2.18.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.007', '58288'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, 'div.article a').click() self.teacher.find(By.ID, 'articleContainer') assert('articles' in self.teacher.current_url()), 'not at article' self.ps.test_updates['passed'] = True # C58313 - 008 - User | Indicate that the article was helpful @pytest.mark.skipif(str(58313) not in TESTS, reason='Excluded') def test_user_indicate_that_the_article_was_helpful_58313(self): """Indicate that the article was helpful. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "Yes" Expected Result: A message that says "Thanks for your feedback!" is displayed """ self.ps.test_updates['name'] = 't2.18.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.008', '58313'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() assert('articles' in self.teacher.current_url()), 'not at the article' self.teacher.find(By.CSS_SELECTOR, '#feedback [value="Yes"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//div[contains(text(),"Thanks for your feedback!")]' )) ) self.ps.test_updates['passed'] = True # C58314 - 009 - User | Negative feedback renders a feedback popup box @pytest.mark.skipif(str(58314) not in TESTS, reason='Excluded') def test_user_negative_feedback_renders_feedback_popup_box_58314(self): """Negative feedback renders a feedback popup box. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" Expected Result: The user is presented with a popup box that allows them to input feedback """ self.ps.test_updates['name'] = 't2.18.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.009', '58314'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() assert('articles' in self.teacher.current_url()), 'not at the article' self.teacher.find(By.CSS_SELECTOR, '#feedback [value="No"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.ID, 'feedbackDialog' )) ) self.ps.test_updates['passed'] = True # C58315 - 010 - User | Submit feedback for an article @pytest.mark.skipif(str(58315) not in TESTS, reason='Excluded') def test_user_submit_feedback_for_an_article_58315(self): """Submit feedback for an article. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" Enter feedback into the box that pops up Click "Submit" Expected Result: A message that says "Thanks for your feedback!" is displayed in the box """ self.ps.test_updates['name'] = 't2.18.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.010', '58315'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() assert('articles' in self.teacher.current_url()), 'not at the article' self.teacher.find(By.CSS_SELECTOR, '#feedback [value="No"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.ID, 'feedbackDialog' )) ) self.teacher.find(By.ID, 'feedbackTextArea') \ .send_keys('qa automated test feedback') self.teacher.find(By.CSS_SELECTOR, '[value="Submit"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//p[text()="Thanks for your feedback!"]' )) ) self.ps.test_updates['passed'] = True # C58322 - 011 - User | Close window after submitting feedback for an # article @pytest.mark.skipif(str(58322) not in TESTS, reason='Excluded') def test_user_close_window_after_submitting_feedback_for_58322(self): """Close window after submitting feedback for an article. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" Enter feedback into the box that pops up Click "Submit" Click "Close window" Expected Result: The popup box closes and the message "Thanks for your feedback" displays beneath "Feedback" """ self.ps.test_updates['name'] = 't2.18.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.011', '58322'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() assert('articles' in self.teacher.current_url()), 'not at the article' self.teacher.find(By.CSS_SELECTOR, '#feedback [value="No"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.ID, 'feedbackDialog' )) ) self.teacher.find(By.ID, 'feedbackTextArea') \ .send_keys('qa automated test feedback') self.teacher.find(By.CSS_SELECTOR, '[value="Submit"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//a[text()="close window"]' )) ).click() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//div[text()="Thanks for your feedback!"]' )) ) self.ps.test_updates['passed'] = True # C58316 - 012 - User | Cancel feedback @pytest.mark.skipif(str(58316) not in TESTS, reason='Excluded') def test_user_cancel_feedback_before_making_changes_58316(self): """Cancel feedback. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" [optional] Enter feedback into the text box Click "Cancel" Expected Result: The popup box closes """ self.ps.test_updates['name'] = 't2.18.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.012', '58316'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() assert('articles' in self.teacher.current_url()), 'not at the article' self.teacher.find(By.CSS_SELECTOR, '#feedback [value="No"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.ID, 'feedbackDialog' )) ) self.teacher.find(By.CSS_SELECTOR, '[value="Cancel"]').click() with self.assertRaises(ElementNotVisibleException): self.teacher.find(By.ID, 'feedbackDialog').click() self.ps.test_updates['passed'] = True # C58318 - 013 - User | View related articles @pytest.mark.skipif(str(58318) not in TESTS, reason='Excluded') def test_user_view_related_articles_58318(self): """View related articles. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Related Articles" Click on one of the articles (if any) Expected Result: The user is presented with the related article """ self.ps.test_updates['name'] = 't2.18.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.013', '58318'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.CSS_SELECTOR, '.article a').click() assert('articles' in self.teacher.current_url()), 'not at the article' self.teacher.find(By.XPATH, '//h2[text()="Related Articles"]') self.ps.test_updates['passed'] = True # C58319 - 014 - User | Submit a question to Customer Support @pytest.mark.skipif(str(58319) not in TESTS, reason='Excluded') def test_user_submit_a_question_to_customer_support_58319(self): """Submit a question to Customer Support. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine CLick "Search" or press enter Click on a search result Scroll to the bottom of the page CLick "Contact Us" Fill out the required fields Enter "Submit" Expected Result: The message "Thank you for your message! We'll be back to you within one business day" is displayed """ self.ps.test_updates['name'] = 't2.18.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.014', '58319'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//p[@data-is-beta="true"]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() self.teacher.sleep(1) window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find(By.ID, 'searchAskInput') \ .send_keys('question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.page.wait_for_page_load() contact = self.teacher.find( By.XPATH, '//a[contains(text(),"Email Us")]' ) Assignment.scroll_to(self.teacher.driver, contact) contact.click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//input[contains(@name,"contactUsForm:firstName")]' ).send_keys('qa_test_first_name') self.teacher.find( By.XPATH, '//input[contains(@name,"contactUsForm:lastName")]' ).send_keys('qa_test_last_name') self.teacher.find( By.XPATH, '//input[contains(@name,"contactUsForm:email")]' ).send_keys('*****@*****.**') self.teacher.find(By.CSS_SELECTOR, '[value="Submit"]').click() self.teacher.wait.until( expect.visibility_of_element_located(( By.XPATH, '//p[contains(text(),"Thank you for your message!")]' )) ) self.ps.test_updates['passed'] = True # C14755 - 015 - Teacher | View guided tutorials of Tutor @pytest.mark.skipif(str(14755) not in TESTS, reason='Excluded') def test_teacher_view_guided_tutorials_of_tutor_14755(self): """View guided tutorials of Tutor. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.18.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.015', '14755'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C14750 - 016 - Student | Directed to a "No Courses" page when not in any # courses yet @pytest.mark.skipif(str(14750) not in TESTS, reason='Excluded') def test_student_directed_to_a_no_courses_page_when_not_in_any_14750(self): """Directed to a "No Courses" page when not in any courses yet. Steps: Go to Tutor Log in as qa_student_37003 Expected Result: The message "We cannot find an OpenStax course associated with your account" displays with help links """ self.ps.test_updates['name'] = 't2.18.016' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.016', '14750'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login( username='******', password=os.getenv('CONTENT_PASSWORD') ) self.student.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located(( By.CSS_SELECTOR, '.panel-body .lead:first-of-type' )) ) self.ps.test_updates['passed'] = True # C58336 - 017 - Student | View "Getting Started with Tutor" Guide @pytest.mark.skipif(str(58336) not in TESTS, reason='Excluded') def test_student_view_getting_started_with_tutor_guide_58336(self): """View "Getting Started with Tutor" Guide. Steps: Click "Tutor Students. Get help" Expected Result: Tutor Help Center opens in another tab with the Getting Started guide """ self.ps.test_updates['name'] = 't2.18.017' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.017', '58336'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58337 - 018 - Student | Access Tutor Help Center after registering for a # course @pytest.mark.skipif(str(58337) not in TESTS, reason='Excluded') def test_student_access_tutor_help_center_after_registering_fo_58337(self): """Access Tutor Help Center after registering for a course. Steps: Go to Tutor Sign in as student01 Click on a Tutor course if the user is in more than one Click "Get Help" from the user menu in the upper right corner of the screen Expected Result: The user is presented with the Tutor Help Center """ self.ps.test_updates['name'] = 't2.18.018' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.018', '58337'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login( username='******', password=os.getenv('CONTENT_PASSWORD') ) self.student.page.wait_for_page_load() self.student.find(By.XPATH, '//a[p[@data-is-beta="true"]]').click() self.student.open_user_menu() self.student.find(By.LINK_TEXT, 'Get Help').click() self.student.sleep(0.5) window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//center[contains(text(),"Tutor Support")]' ) self.ps.test_updates['passed'] = True ''' # C58338 - 019 - Student | Submit a question @pytest.mark.skipif(str(58338) not in TESTS, reason='Excluded') def test_student_submit_a_question_58338(self): """Submit a question. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Expected Result: The user is presented with search results """ self.ps.test_updates['name'] = 't2.18.019' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.019', '58338'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58353 - 020 - Student | View "Contact Us" button after submitting a # question @pytest.mark.skipif(str(58353) not in TESTS, reason='Excluded') def test_student_view_contact_us_button_after_submitting_quest_58353(self): """View "Contact Us" button after submitting a question. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Scroll to the bottom of the page Expected Result: "Contact Us" button exists """ self.ps.test_updates['name'] = 't2.18.020' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.020', '58353'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58339 - 021 - Student | View an article after submitting a question @pytest.mark.skipif(str(58339) not in TESTS, reason='Excluded') def test_student_view_an_article_after_submitting_a_question_58339(self): """View an article after submitting a question. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Expected Result: The user is presented with an article containing answer to the question """ self.ps.test_updates['name'] = 't2.18.021' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.021', '58339'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58340 - 022 - Student | Indicate that the article was helpful @pytest.mark.skipif(str(58340) not in TESTS, reason='Excluded') def test_student_indicate_that_the_article_was_helpful_58340(self): """Indicate that the article was helpful. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "Yes" Expected Result: A message that says "Thanks for your feedback!" is displayed """ self.ps.test_updates['name'] = 't2.18.022' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.022', '58340'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58341 - 023 - Student | Negative feedback renders a feedback popup box @pytest.mark.skipif(str(58341) not in TESTS, reason='Excluded') def test_student_negative_feedback_renders_feedback_popup_box_58341(self): """Negative feedback renders a feedback popup box. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" Expected Result: The user is presented with a popup box that allows them to input feedback """ self.ps.test_updates['name'] = 't2.18.023' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.023', '58341'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58342 - 024 - Student | Submit feedback for an article @pytest.mark.skipif(str(58342) not in TESTS, reason='Excluded') def test_student_submit_feedback_for_an_article_58342(self): """Submit feedback for an article. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" Enter feedback into the box that pops up Click "Submit" Expected Result: A message that says "Thanks for your feedback!" is displayed in the box """ self.ps.test_updates['name'] = 't2.18.024' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.024', '58342'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58343 - 025 - Student | Close window after submitting feedback for an # article @pytest.mark.skipif(str(58343) not in TESTS, reason='Excluded') def test_student_close_window_after_submitting_feedback_for_58343(self): """Close window after submitting feedback for an article. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" Enter feedback into the box that pops up Click "Submit" Click "Close window" Expected Result: The popup box closes and the message "Thanks for your feedback" displays beneath "Feedback" """ self.ps.test_updates['name'] = 't2.18.025' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.025', '58343'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58344 - 026 - Student | Cancel feedback @pytest.mark.skipif(str(58344) not in TESTS, reason='Excluded') def test_student_cancel_feedback_58344(self): """Cancel feedback. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Feedback" Click "No" [optional] Enter feedback into text box Click "Cancel" Expected Result: The popup box closes """ self.ps.test_updates['name'] = 't2.18.026' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.026', '58344'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58346 - 027 - Student | View related articles @pytest.mark.skipif(str(58346) not in TESTS, reason='Excluded') def test_student_view_related_articles_58346(self): """View related articles. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to "Related Articles" Click on one of the articles (if any) Expected Result: The user is presented with the related article """ self.ps.test_updates['name'] = 't2.18.027' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.027', '58346'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C58347 - 028 - Student | Submit a question to Customer Support @pytest.mark.skipif(str(58347) not in TESTS, reason='Excluded') def test_student_submit_a_question_to_customer_support_58347(self): """Submit a question to Customer Support. Steps: Click "Get Help" from the user menu Enter a question or search words into the search engine Click "Search" or press enter Click on a search result Scroll to the bottom of the page Click "Contact Us" Fill out the required fields Enter "Submit" Expected Result: The message "Thank you for your message! We'll be back to you within one business day" is displayed """ self.ps.test_updates['name'] = 't2.18.028' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.028', '58347'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True ''' # C58348 - 029 - Student | View guided tutorials of Tutor @pytest.mark.skipif(str(58348) not in TESTS, reason='Excluded') def test_student_view_guided_tutorials_of_tutor_58348(self): """View guided tutorial of Tutor. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.18.029' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.029', '58348'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # C111250 - 030 - User | Faulty URL shows a styled 404 error page @pytest.mark.skipif(str(111250) not in TESTS, reason='Excluded') def test_user_faulty_url_shows_styled_404_page_111250(self): """Faulty URL shows a styled 404 error page. Steps: go to https://tutor-qa.openstax.org/not_a_real_page Expected Result: A styled error page is displayed """ self.ps.test_updates['name'] = 't2.18.030' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.030', '111250'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.get('https://tutor-qa.openstax.org/not_a_real_page') self.teacher.wait.until( expect.presence_of_element_located(( By.CSS_SELECTOR, '.invalid-page' )) ) self.ps.test_updates['passed'] = True
class TestTeacherLoginAndAuthentification(unittest.TestCase): """CC1.11 - Teacher Login and Authentification.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher.login() def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C7688 - 001 - Teacher | Log into Concept Coach @pytest.mark.skipif(str(7688) not in TESTS, reason='Excluded') def test_teacher_log_into_concept_coach_7688(self): """Log into Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: User is taken to the class dashboard. """ self.ps.test_updates['name'] = 'cc1.11.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.11', 'cc1.11.001', '7688' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.select_course(appearance='macro_economics') self.teacher.sleep(5) assert('cc-dashboard' in self.teacher.current_url()), \ 'Not viewing the cc dashboard' self.ps.test_updates['passed'] = True # Case C7689 - 002 - Teacher | Logging out returns to the login page @pytest.mark.skipif(str(7689) not in TESTS, reason='Excluded') def test_teacher_loggin_out_returns_to_the_login_page_7689(self): """Logging out returns to the login page. Steps: Click the user menu containing the user's name Click the 'Log Out' button Expected Result: User is taken to cc.openstax.org """ self.ps.test_updates['name'] = 'cc1.11.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.11', 'cc1.11.002', '7689' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.select_course(appearance='macro_economics') self.teacher.sleep(5) assert('dashboard' in self.teacher.current_url()), \ 'Not viewing the cc dashboard' self.teacher.open_user_menu() self.teacher.sleep(1) self.teacher.find(By.XPATH, "//a/form[@class='-logout-form']").click() assert('cc.openstax.org' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C7690 - 003 - Teacher | Can log into Tutor and be redirected to CC @pytest.mark.skipif(str(7690) not in TESTS, reason='Excluded') def test_teacher_can_log_into_tutor_and_be_redirected_to_cc_7690(self): """Can log into Tutor and be redirected to Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: User is taken to the class dashboard """ self.ps.test_updates['name'] = 'cc1.11.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.11', 'cc1.11.003', '7690' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.select_course(appearance='macro_economics') self.teacher.sleep(5) assert('cc-dashboard' in self.teacher.current_url()), \ 'Not viewing the cc dashboard' self.ps.test_updates['passed'] = True
class TestSimplifyAndImproveReadings(unittest.TestCase): """T2.13 - Simplify and Improve Readings.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) # create a reading for the student to work self.teacher.login() self.teacher.driver.execute_script("window.resizeTo(1920,1080)") self.teacher.select_course(appearance='ap_biology') self.assignment_name = 't1.18 reading-%s' % randint(100, 999) today = datetime.date.today() begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=randint(1, 10))) \ .strftime('%m/%d/%Y') self.teacher.add_assignment(assignment='reading', args={ 'title': self.assignment_name, 'description': chomsky(), 'periods': { 'all': (begin, end) }, 'reading_list': ['1.1'], 'status': 'publish', }) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"calendar-container")]'))) self.teacher.logout() # login as a student to work the reading self.student = Student(existing_driver=self.teacher.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.student.login() self.student.select_course(appearance='ap_biology') self.student.wait.until( expect.visibility_of_element_located((By.LINK_TEXT, 'This Week'))) reading = self.student.driver.find_element( By.XPATH, '//div[text()="%s"]' % self.assignment_name) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', reading) self.teacher.driver.execute_script('window.scrollBy(0, -80);') reading.click() self.student.driver.set_window_size(width=1300, height=1200) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) self.student = None try: self.teacher.delete() except: pass # 14745 - 001 - Student | Relative size and progress are displayed while # working a reading assignment @pytest.mark.skipif(str(14745) not in TESTS, reason='Excluded') def test_student_relative_size_and_progress_are_displayed_whil_14745(self): """Size and progress are displayed while working a reading. Steps: Go to Tutor Click on the 'Login' button Enter the student user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a Tutor course name Click on a reading assignment Click on the right arrow Expected Result: The progress bar at the top reflects how far along you are as you work through the reading assignment """ self.ps.test_updates['name'] = 't2.13.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.13', 't2.13.001', '14745'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.driver.find_element( By.XPATH, '//div[contains(@class,"progress-bar progress-bar-success")]') self.ps.test_updates['passed'] = True # 14746 - 002 - Student | Access prior milestones in the reading assignment # with breadcrumbs @pytest.mark.skipif(str(14746) not in TESTS, reason='Excluded') def test_student_access_prior_milestones_in_the_reading_assign_14746(self): """Access prior milestones in the reading assignment with breadcrumbs. Steps: If the user has more than one course, click on a Tutor course name Click on a reading assignment Click on the icon next to the calendar on the header Expected Result: The user is presented with prior milestones """ self.ps.test_updates['name'] = 't2.13.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.13', 't2.13.002', '14746'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click() self.student.sleep(1) self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click() self.student.sleep(1) self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click() self.student.sleep(1) self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click() self.student.sleep(5) self.student.driver.execute_script("window.scrollTo(0, 0);") element = self.student.find(By.XPATH, "//a[@class='milestones-toggle']") actions = ActionChains(self.student.driver) actions.move_to_element(element) actions.click() actions.perform() self.student.sleep(1) self.student.driver.execute_script("window.scrollTo(0, 0);") cards = self.student.find_all( By.XPATH, "//div[@class='milestone milestone-reading']") # preview = '' if not isinstance(cards, list): # preview = cards.find_element( # By.XPATH, # "//div[@class='milestone milestone-reading']" # ).text cards.click() else: card = randint(0, len(cards)) # preview = cards[card].find_element( # By.XPATH, # "//div[@class='milestone milestone-reading']" # ).text cards[card].click() string = "step/" + str(card + 1) assert(self.student.driver.current_url.find(string) >= 0), \ 'Something' self.ps.test_updates['passed'] = True # C85291 - 003 - Student | Reading Review card appears before the first # spaced practice question @pytest.mark.skipif(str(85291) not in TESTS, reason='Excluded') def test_student_reading_review_card_appears_before_first_spac_85291(self): """Reading Review card appears before first spaced practice question. Steps: Login as student Work the reading assignment After completing reading the sections you get a spaced practice problem Expected Result: The reading review card should appear before the first spaced practice question """ self.ps.test_updates['name'] = 't2.08.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.003', '85291'] self.ps.test_updates['passed'] = False # Test steps and verification assertions while (1): while ('paging-control next' in self.student.driver.page_source and 'Concept Coach' not in self.student.driver.page_source and 'exercise-multiple-choice' not in self.student.driver.page_source and 'textarea' not in self.student.driver.page_source): self.student.find(By.XPATH, "//a[@class='paging-control next']").click() # multiple choice case if ('exercise-multiple-choice' in self.student.driver.page_source): answers = self.student.driver.find_elements( By.CLASS_NAME, 'answer-letter') self.student.sleep(0.8) rand = randint(0, len(answers) - 1) answer = chr(ord('a') + rand) Assignment.scroll_to(self.student.driver, answers[0]) if answer == 'a': self.student.driver.execute_script( 'window.scrollBy(0, -160);') elif answer == 'd': self.student.driver.execute_script( 'window.scrollBy(0, 160);') answers[rand].click() self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"async-button")' + ' and contains(@class,"continue")]'))).click() self.student.sleep(5) page = self.student.driver.page_source assert('question-feedback bottom' in page), \ 'Did not submit MC' self.student.find( By.XPATH, "//button[@class='async-button continue btn btn-primary']" ).click() # free response case elif ('textarea' in self.student.driver.page_source): self.student.find( By.TAG_NAME, 'textarea').send_keys('An answer for this textarea') self.student.sleep(2) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"async-button")' + ' and contains(@class,"continue")]'))).click() self.student.wait.until( expect.visibility_of_element_located( (By.CLASS_NAME, 'exercise-multiple-choice'))) self.student.sleep(2) # Reached Concept Coach card if ('Spaced Practice' in self.student.driver.page_source and 'spaced-practice-intro' in self.student.driver.page_source): self.student.sleep(5) break self.student.sleep(2) self.ps.test_updates['passed'] = True # C100126 - 004 - Student | Section number is seen at the beginning of each # new section in a reading assignment @pytest.mark.skipif(str(100126) not in TESTS, reason='Excluded') def test_student_section_number_is_seen_st_the_beginning_of_e_100126(self): """Section number seen at beginning of each new section in a reading. Steps: Login as a student Click on a tutor course Click on a reading assignment Continue to work through reading assignment Expected Result: At the start of each new section, the section number is displayed """ self.ps.test_updates['name'] = 't2.08.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.004', '100126'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.find(By.XPATH, "//span[@class='section']") self.student.sleep(3) self.ps.test_updates['passed'] = True # C100127 - 005 - Teacher | Section numbers are listed at the top of each # section in reference view @pytest.mark.skipif(str(100127) not in TESTS, reason='Excluded') def test_student_section_numbers_listed_at_the_top_of_each_se_100127(self): """Section numbers listed at the top of each section in reference view. Steps: Login as teacher Click on a tutor course Click "Browse the Book" or select "Browse the Book" from the user menu Select a section from the contents Expected Result: Section number listed in header """ self.ps.test_updates['name'] = 't2.08.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.005', '100127'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.logout() self.teacher.login() self.teacher.select_course(appearance='ap_biology') self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, "Browse the Book").click() self.teacher.sleep(5) self.teacher.driver.switch_to_window( self.student.driver.window_handles[-1]) self.teacher.find(By.XPATH, "//li[3]/ul[@class='section']/li/a").click() self.teacher.find(By.XPATH, "//span[@class='section']") self.teacher.sleep(3) self.ps.test_updates['passed'] = True # C100128 - 006 - Student | Section numbers are listed at the top of each # section in reference view @pytest.mark.skipif(str(100128) not in TESTS, reason='Excluded') def test_student_section_numbers_listed_at_the_top_of_each_se_100128(self): """Section numbers listed at the top of each section in reference view. Steps: Login as student Click on a tutor course Click "Browse the Book" or select "Browse the Book" from the user menu Select a section from the contents Expected Result: Section number listed in header """ self.ps.test_updates['name'] = 't2.08.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.006', '100128'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.open_user_menu() self.student.find(By.LINK_TEXT, "Browse the Book").click() self.student.sleep(5) self.student.driver.switch_to_window( self.student.driver.window_handles[-1]) self.student.find(By.XPATH, "//li[3]/ul[@class='section']/li/a").click() self.student.find(By.XPATH, "//span[@class='section']") self.student.sleep(3) self.ps.test_updates['passed'] = True
class TestUserLogin(unittest.TestCase): """T1.36 - User login.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.admin = Admin(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.content = ContentQA(existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.student = Student(existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.teacher = Teacher(existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.admin = Admin(use_env_vars=True, ) self.content = ContentQA( existing_driver=self.admin.driver, use_env_vars=True, ) self.student = Student( existing_driver=self.admin.driver, use_env_vars=True, ) self.teacher = Teacher( existing_driver=self.admin.driver, use_env_vars=True, ) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.admin.driver.session_id), **self.ps.test_updates) try: self.teacher = None self.student = None self.content = None self.admin.delete() except: pass # Case C8238 - 001 - Admin | Log into Tutor @pytest.mark.skipif(str(8238) not in TESTS, reason='Excluded') def test_admin_log_into_tutor_8238(self): """Log into Tutor. Steps: Click on the 'Log in' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Expected Result: User is logged in """ self.ps.test_updates['name'] = 't1.36.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.001', '8238'] self.ps.test_updates['passed'] = False self.admin.get(self.admin.url) self.admin.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.admin.driver.get_window_size()['width'] <= \ self.admin.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.admin.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Log in'))).click() self.admin.page.wait_for_page_load() self.admin.find(By.ID, 'login_username_or_email') \ .send_keys(self.admin.username) self.admin.find(By.XPATH, "//input[@value='Next']").click() self.admin.find(By.ID, 'login_password') \ .send_keys(self.admin.password) # click on the sign in button self.admin.find(By.XPATH, "//input[@value='Log in']").click() self.admin.page.wait_for_page_load() assert('dashboard' in self.admin.current_url()), \ 'Not taken to dashboard: %s' % self.admin.current_url() self.ps.test_updates['passed'] = True # Case C8239 - 002 - Admin | Access the Admin Console @pytest.mark.skipif(str(8239) not in TESTS, reason='Excluded') def test_admin_access_the_admin_console_8239(self): """Access the Admin console. Steps: Click on the 'Log in' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click on the user menu Click on the Admin option Expected Result: User is presented with the admin console """ self.ps.test_updates['name'] = 't1.36.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.002', '8239'] self.ps.test_updates['passed'] = False self.admin.login() self.admin.open_user_menu() self.admin.wait.until( expect.element_to_be_clickable((By.LINK_TEXT, 'Admin'))).click() self.admin.page.wait_for_page_load() self.admin.find(By.XPATH, '//h1[contains(text(),"Admin Console")]') self.ps.test_updates['passed'] = True # Case C8240 - 003 - Admin | Log out @pytest.mark.skipif(str(8240) not in TESTS, reason='Excluded') def test_admin_log_out_8240(self): """Log out. Steps: Click on the 'Log in' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The User is signed out """ self.ps.test_updates['name'] = 't1.36.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.003', '8240'] self.ps.test_updates['passed'] = False self.admin.login() self.admin.open_user_menu() self.admin.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log out")]'))).click() self.admin.page.wait_for_page_load() self.admin.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C8241 - 004 - Content Analyst | Log into Tutor @pytest.mark.skipif(str(8241) not in TESTS, reason='Excluded') def test_content_analyst_log_into_tutor_8241(self): """Log into Tutor. Steps: Click on the 'Log in' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Expected Result: The user is signed in """ self.ps.test_updates['name'] = 't1.36.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.004', '8241'] self.ps.test_updates['passed'] = False self.content.get(self.content.url) self.content.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.content.driver.get_window_size()['width'] <= \ self.content.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.content.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.content.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Log in'))).click() self.content.page.wait_for_page_load() self.content.find(By.ID, 'login_username_or_email') \ .send_keys(self.content.username) self.content.find(By.XPATH, "//input[@value='Next']").click() self.content.find(By.ID, 'login_password') \ .send_keys(self.content.password) # click on the sign in button self.content.find(By.XPATH, "//input[@value='Log in']").click() self.content.page.wait_for_page_load() assert('dashboard' in self.content.current_url()), \ 'Not taken to dashboard: %s' % self.content.current_url() self.ps.test_updates['passed'] = True # Case C8242 - 005 - Content Analyst | Access the QA Viewer @pytest.mark.skipif(str(8242) not in TESTS, reason='Excluded') def test_content_analyst_access_the_qa_viewer_8242(self): """Access the QA Viewer. Steps: Click on the 'Log in' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the QA Content option Expected Result: The user is presented with the QA viewer """ self.ps.test_updates['name'] = 't1.36.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.005', '8242'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//div[contains(text(),"QA Content")]'))).click() self.content.page.wait_for_page_load() assert('/qa' in self.content.current_url()), \ 'Not taken to the QA viewer: %s' % self.content.current_url() self.ps.test_updates['passed'] = True # Case C8243 - 006 - Content Analyst | Access the Content Analyst Console @pytest.mark.skipif(str(8243) not in TESTS, reason='Excluded') def test_content_analyst_access_the_content_analyst_console_8243(self): """Access the Content Annalyst Console. Steps: Click on the 'Log in' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Content Analyst option Expected Result: The user is presented with the Content Analyst Console """ self.ps.test_updates['name'] = 't1.36.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.006', '8243'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//div[contains(text(),"Content Analyst")]'))).click() self.content.page.wait_for_page_load() self.content.find(By.XPATH, '//h1[contains(text(),"Content Analyst Console")]') self.ps.test_updates['passed'] = True # Case C8244 - 007 - Content Analyst | Log out @pytest.mark.skipif(str(8244) not in TESTS, reason='Excluded') def test_content_analyst_log_out_8244(self): """Log out. Steps: Click on the 'Log in' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.007', '8244'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log out")]'))).click() self.content.page.wait_for_page_load() self.content.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C8245 - 008 - Student | Log into Tutor @pytest.mark.skipif(str(8245) not in TESTS, reason='Excluded') def test_student_log_into_tutor_8245(self): """Log into Tutor. Steps: Click on the 'Log in' button Enter the student account in the username and password text boxes Click on the 'Sign in' button Expected Result: The user is logged in """ self.ps.test_updates['name'] = 't1.36.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.008', '8245'] self.ps.test_updates['passed'] = False self.student.get(self.student.url) self.student.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.student.driver.get_window_size()['width'] <= \ self.student.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.student.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.student.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Log in'))).click() self.student.page.wait_for_page_load() self.student.find(By.ID, 'login_username_or_email') \ .send_keys(self.student.username) self.student.find(By.XPATH, "//input[@value='Next']") \ .click() self.student.find(By.ID, 'login_password') \ .send_keys(self.student.password) # click on the sign in button self.student.find(By.XPATH, "//input[@value='Log in']").click() self.student.page.wait_for_page_load() assert('dashboard' in self.student.current_url()), \ 'Not taken to dashboard: %s' % self.student.current_url() self.ps.test_updates['passed'] = True # Case C8246 - 009 - Teacher | Log into Tutor @pytest.mark.skipif(str(8246) not in TESTS, reason='Excluded') def test_teacher_log_into_tutor_8246(self): """Log into Tutor. Steps: Click on the 'Log in' button Enter the teacher account in the username and password text boxes Click on the 'Sign in' button Expected Result: The user is logged in """ self.ps.test_updates['name'] = 't1.36.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.009', '8246'] self.ps.test_updates['passed'] = False self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Log in'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'login_username_or_email') \ .send_keys(self.teacher.username) self.teacher.find(By.XPATH, "//input[@value='Next']").click() self.teacher.find(By.ID, 'login_password') \ .send_keys(self.teacher.password) # click on the sign in button self.teacher.find(By.XPATH, "//input[@value='Log in']").click() self.teacher.page.wait_for_page_load() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C58271 - 010 - Student | Log out @pytest.mark.skipif(str(58271) not in TESTS, reason='Excluded') def test_content_analyst_log_out_58271(self): """Log out. Steps: Click on the 'Log in' button Enter the student account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.010', '58271'] self.ps.test_updates['passed'] = False self.student.login() self.student.open_user_menu() self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log out")]'))).click() self.student.page.wait_for_page_load() self.student.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C58272 - 011 - Teacher | Log out @pytest.mark.skipif(str(58272) not in TESTS, reason='Excluded') def test_teacher_log_out_58272(self): """Log out. Steps: Click on the 'Log in' button Enter the teacher account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.011', '58272'] self.ps.test_updates['passed'] = False self.teacher.login() self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log out")]'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C96962 - 012 - Content Reviewer | Log into Exercises @pytest.mark.skipif(str(96962) not in TESTS, reason='Excluded') def test_content_reviewer_log_into_exercises_96962(self): """Log into Exercises. Steps: Go to https://exercises-qa.openstax.org/ Click "SIGN IN" Enter the Content username into "Email or username" text box Click "Next" Enter the Content password into "password" text box Click "Login" Expected Result: User is logged in """ self.ps.test_updates['name'] = 't1.36.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.012', '96962'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.content.driver.get("https://exercises-qa.openstax.org/") self.content.sleep(3) self.content.find(By.LINK_TEXT, "SIGN IN").click() self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \ .send_keys(os.getenv('CONTENT_USER')) self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \ .send_keys(Keys.RETURN) self.content.sleep(2) self.content.find(By.XPATH, "//input[@id='login_password']") \ .send_keys(os.getenv('CONTENT_PASSWORD')) self.content.find(By.XPATH, "//input[@id='login_password']") \ .send_keys(Keys.RETURN) self.content.sleep(3) self.content.find(By.LINK_TEXT, "SIGN OUT") self.ps.test_updates['passed'] = True # Case C96963 - 013 - Content Reviewer | Access Reviewer Display @pytest.mark.skipif(str(96963) not in TESTS, reason='Excluded') def test_content_reviewer_access_reviewer_display_96963(self): """Access Reviewer Display. Steps: Expected Result: """ self.ps.test_updates['name'] = 't1.36.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.013', '96963'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C96964 - 014 - Content Reviewer | Log out @pytest.mark.skipif(str(96964) not in TESTS, reason='Excluded') def test_content_reviewer_log_out_96964(self): """Log out. Steps: go to https://exercises-qa.openstax.org/ Click "SIGN IN" Enter [content] into "Email or username" text box Click "Next" Enter [staxly16] into "password" text box Click "Login" Click "SIGN OUT" Expected Result: User is logged out. """ self.ps.test_updates['name'] = 't1.36.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.014', '96964'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.content.driver.get("https://exercises-qa.openstax.org/") self.content.sleep(3) self.content.find(By.LINK_TEXT, "SIGN IN").click() self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \ .send_keys(os.getenv('CONTENT_USER')) self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \ .send_keys(Keys.RETURN) self.content.sleep(2) self.content.find(By.XPATH, "//input[@id='login_password']") \ .send_keys(os.getenv('CONTENT_PASSWORD')) self.content.find(By.XPATH, "//input[@id='login_password']") \ .send_keys(Keys.RETURN) self.content.sleep(3) self.content.find(By.LINK_TEXT, "SIGN OUT").click() self.content.sleep(2) self.content.find(By.LINK_TEXT, "SIGN IN") self.ps.test_updates['passed'] = True # Case C96965 - 015 - Content Editor | Log into Exercises @pytest.mark.skipif(str(96965) not in TESTS, reason='Excluded') def test_content_editor_log_into_exercises_96965(self): """Log into Exercises. Steps: Expected Result: """ self.ps.test_updates['name'] = 't1.36.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.015', '96965'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C96962 - 016 - Content Editor | Access the Exercise Editor @pytest.mark.skipif(str(96966) not in TESTS, reason='Excluded') def test_content_editor_access_the_exercise_editor_96966(self): """Access the Exercise Editor. Steps: Expected Result: """ self.ps.test_updates['name'] = 't1.36.016' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.016', '96966'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C96967 - 017 - Content Editor | Log out @pytest.mark.skipif(str(96967) not in TESTS, reason='Excluded') def test_content_editor_log_out_96967(self): """Log out. Steps: Expected Result: """ self.ps.test_updates['name'] = 't1.36.017' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.017', '96967'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
class TestRecruitingTeachers(unittest.TestCase): """CC1.01 - Recruiting Teachers.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.CONDENSED_WIDTH = 1105 def tearDown(self): """Test destructor.""" self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass # Case C7751 - 001 - Admin | Recruitment and promo website is available @pytest.mark.skipif(str(7751) not in TESTS, reason='Excluded') def test_admin_recruitment_and_promo_website_is_available_7751(self): """Recruitment and promo website is available. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Expected Result: Recruitment website loads and renders """ self.ps.test_updates['name'] = 'cc1.01.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.001', '7751'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.ps.test_updates['passed'] = True # Case C7752 - 002 - Teacher | Information about Concept Coach and the # pilot are available on the demo site @pytest.mark.skipif(str(7752) not in TESTS, reason='Excluded') def test_teacher_information_about_cc_is_available_on_demo_site_7752(self): """Information about CC and pilot are available on the demo site. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Expected Result: Page loads several sections describing Concept Coach """ self.ps.test_updates['name'] = 'cc1.01.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.002', '7752'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'who-we-are') self.ps.test_updates['passed'] = True # Case C7753 - 003 - Teacher | Can interact with a Concept Coach wire frame # for each subject @pytest.mark.skipif(str(7753) not in TESTS, reason='Excluded') def test_teacher_can_interact_with_a_cc_wire_frame_for_subjects_7753(self): """Can interact with a Concept Coach wire frame for each subject. Steps: Go to the recruitment website ( http://cc.openstax.org/) Hover over "demos" in the header Click "Interactice Demo" CLick on a Concept Coach book title Expected Result: A new tab or window opens rendering the demo content for the selected book """ self.ps.test_updates['name'] = 'cc1.01.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.003', '7753'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() assert('http://cc.openstax.org/assets/demos/cc-mockup' in self.teacher.current_url()), \ 'not at demo book' self.ps.test_updates['passed'] = True # # NOT DONE # Case C7754 - 004 - Teacher | View a Concept Coach demo video @pytest.mark.skipif(str(7754) not in TESTS, reason='Excluded') def test_teacher_view_a_concept_coach_demo_video_7754(self): """View a Concept Coach demo video. Steps: Open recruitment website ( http://cc.openstax.org/ ) Hover over "demos" in the header Click "Interactive Demo" Click on a Concept Coach book title Scroll down until an embedded video pane is displayed Click on the right-pointing arrow to play the video Expected Result: The video loads and plays """ self.ps.test_updates['name'] = 'cc1.01.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.004', '7754'] self.ps.test_updates['passed'] = False raise NotImplementedError(inspect.currentframe().f_code.co_name) # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup-physics")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() self.teacher.sleep(2) # self.teacher.find( # By.XPATH, '//div[@id="player"]' # ).click() title = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Inelastic Collisions")]'))) # self.teacher.wait.until( # expect.presence_of_element_located( # (By.ID, 'player') # ) # ) actions = ActionChains(self.teacher.driver) actions.move_to_element(title) actions.move_by_offset(0, 300) actions.click() actions.perform() self.teacher.sleep(2) self.teacher.find(By.XPATH, '//div[contains(@class,"playing-mode")]') # actions.perform() self.teacher.find( By.XPATH, '//div[@id="player"]/div[contains(@class,"paused-mode")]') self.ps.test_updates['passed'] = True # Case C7755 - 005 - Teacher | Sample exercise questions are seen in # the wire frames @pytest.mark.skipif(str(7755) not in TESTS, reason='Excluded') def test_teacher_sample_exercise_questions_are_in_wire_frames_7755(self): """Sample exercise questions are seen in the wire frames. Steps: Open recruitment website ( http://cc.openstax.org/ ) Hover over "demos" in the header Click "Interactive Demo" Click on a Concept Coach book title Scroll down until the 'CONCEPT COACH' pane is displayed Expected Result: Demo exercises are rendered and can be answered along with showing feedback """ self.ps.test_updates['name'] = 'cc1.01.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.005', '7755'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup-physics")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//span[contains(text(),"JUMP TO CONCEPT COACH")]').click() self.teacher.find(By.XPATH, '//div[contains(@data-label,"q1-multiple-choice")]') self.teacher.sleep(2) answer = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@data-label,"choice-1b-text")]'))) actions = ActionChains(self.teacher.driver) actions.move_to_element(answer) actions.click() actions.perform() self.teacher.find(By.XPATH, "//div[@data-label='State2']").click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, "//div[@data-label='q1-answer-b']//div[@data-label='next']"))) self.ps.test_updates['passed'] = True # Case C7756 - 006 - Teacher | Access Concept Coach help and support before # the teacher's course is created @pytest.mark.skipif(str(7756) not in TESTS, reason='Excluded') def test_teacher_access_cc_support_before_course_is_created_7756(self): """Access CC help and support before the teacher's course is created. Steps: Open the recruitment website ( http://cc.openstax.org/ ) Click "Support" in the header Expected Result: A new tab opens with the CC Help Center """ self.ps.test_updates['name'] = 'cc1.01.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.006', '7756'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() if self.teacher.driver.get_window_size()['width'] < \ self.CONDENSED_WIDTH: self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//label[@for="mobileNavToggle" and ' + 'contains(@class,"fixed")]'))).click() self.teacher.sleep(1) self.teacher.find(By.XPATH, '//a[contains(text(),"support")]').click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') self.ps.test_updates['passed'] = True # Case C7757 - 007 - Teacher | Teacher registers to use a CC course @pytest.mark.skipif(str(7757) not in TESTS, reason='Excluded') def test_teacher_teacher_registers_to_use_a_cc_course_7757(self): """Teacher registers to use a Concept Coach course. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Expected Result: Web form renders """ self.ps.test_updates['name'] = 'cc1.01.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.007', '7757'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') self.ps.test_updates['passed'] = True # Case C7758 - 008 - Teacher | Teacher uses a web form to sign up for CC @pytest.mark.skipif(str(7758) not in TESTS, reason='Excluded') def test_teacher_teacher_uses_a_web_form_to_sign_up_for_cc_7758(self): """Teacher uses a web form to sign up for Concept Coach. Steps: Teacher fills out the form Expected Result: Preconditions pass. User is presented with a confirmation message """ self.ps.test_updates['name'] = 'cc1.01.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.008', '7758'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') self.teacher.find(By.ID, 'first_name').send_keys('first') self.teacher.find(By.ID, 'last_name').send_keys('last') self.teacher.find(By.ID, 'email').send_keys('*****@*****.**') self.teacher.find(By.ID, 'company').send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]').click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]').send_keys('25') self.teacher.find(By.XPATH, '//input[@type="submit"]').click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]'))) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7759 - 009 - Teacher | Receive error messages if required fields on # the sign up form are blank @pytest.mark.skipif(str(7759) not in TESTS, reason='Excluded') def test_teacher_receive_error_messages_if_required_fields_are_7759(self): """Receive error messages if required fields on the sign up form are blank. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Click on the 'sign up now' button Submit the form without changing any of the text fields Expected Result: Receive 'Please fill out this field' error messages in red for each blank required field """ self.ps.test_updates['name'] = 'cc1.01.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.009', '7759'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') submit = self.teacher.find(By.XPATH, '//input[@type="submit"]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', submit) self.teacher.sleep(0.5) submit.click() assert('/sign-up' in self.teacher.current_url()), \ 'moved from sign up when submitting with blank required fields' self.teacher.find( By.XPATH, '//div[contains(text(),"Please fill out this field.")]') self.ps.test_updates['passed'] = True # Case C7760 - 010 - Teacher | Submit a form to supply required course info @pytest.mark.skipif(str(7760) not in TESTS, reason='Excluded') def test_teacher_submit_a_form_to_supply_required_course_info_7760(self): """Submit a form to supply required course information. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Web form submits Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.010', '7760'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') self.teacher.find(By.ID, 'first_name').send_keys('first') self.teacher.find(By.ID, 'last_name').send_keys('last') self.teacher.find(By.ID, 'email').send_keys('*****@*****.**') self.teacher.find(By.ID, 'company').send_keys('school') # choose a book! menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]').click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]').send_keys('25') self.teacher.find(By.XPATH, '//input[@type="submit"]').click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]'))) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7761 - 011 - Teacher | Submit co-instructors, classes, names, etc. @pytest.mark.skipif(str(7761) not in TESTS, reason='Excluded') def test_teacher_submit_coinstructors_classes_names_etc_7761(self): """Submit co-instructors, classes, names and other data. Steps: Go to the recruitment and promo website ( http://cc.openstax.org/ ) Click on the 'sign up now' button Click on the 'Co-Teaching class with a colleague?' circle button Enter the co-instructor's (or co-instructors') information Enter text into other fields concerning classe, names, etc. Expected Result: Input box exists for instructor information, class details and other data. The user is able to input information. """ self.ps.test_updates['name'] = 'cc1.01.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.011', '7761'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') option = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="slide-checkbox"]/label'))) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', option) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) option.click() textarea = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@id="coteachcontact"]/textarea'))) textarea.send_keys('co teacher info') self.ps.test_updates['passed'] = True # Case C7762 - 012 - Teacher | Select the textbook to use in the course @pytest.mark.skipif(str(7762) not in TESTS, reason='Excluded') def test_teacher_select_the_textbook_to_use_in_the_course_7762(self): """Select the textbook to use in the course. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Select the course textbook from the 'Book' dropdown options Expected Result: Able to select any Concept Coach textbook """ self.ps.test_updates['name'] = 'cc1.01.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.012', '7762'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') menu = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]'))) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) book = self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]') title = book.text book.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//span[contains(@title,"' + title + '") and ' + 'contains(@class,"select2-selection__rendered")]') self.ps.test_updates['passed'] = True # Case C7763 - 013 - Teacher | Indicate whether the teacher was recruited # by OpenStax @pytest.mark.skipif(str(7763) not in TESTS, reason='Excluded') def test_teacher_indicate_whether_the_teacher_was_recruited_by_7763(self): """Indicate if the teacher was or was not recruited by OpenStax. Steps: Go to the recruitment and promo website ( http://cc.openstax.org/ ) Click on the 'sign up now' button ( http://cc.openstax.org/sign-up ) Enter recruitment information into the 'Anything else we need to know?' text box Expected Result: Able to input recruitment information """ self.ps.test_updates['name'] = 'cc1.01.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.013', '7763'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') textarea = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//textarea[@placeholder="Feedback"]'))) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', textarea) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) textarea.send_keys('recuitment info') self.ps.test_updates['passed'] = True # Case C7764 - 014 - Teacher | Presented a thank you page after registering # to use Concept Coach @pytest.mark.skipif(str(7764) not in TESTS, reason='Excluded') def test_teacher_presented_a_thank_you_page_after_registering_7764(self): """Presented a thank you page after registering to use Concept Coach. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.014', '7764'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') self.teacher.find(By.ID, 'first_name').send_keys('first') self.teacher.find(By.ID, 'last_name').send_keys('last') self.teacher.find(By.ID, 'email').send_keys('*****@*****.**') self.teacher.find(By.ID, 'company').send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]').click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]').send_keys('25') self.teacher.find(By.XPATH, '//input[@type="submit"]').click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]'))) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7765 - 015 - Teacher | Sign up for an OpenStax Accounts username @pytest.mark.skipif(str(7765) not in TESTS, reason='Excluded') def test_teacher_sign_up_for_an_openstax_accounts_username_7765(self): """Sign up for an OpenStax Accounts username. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.015', '7765'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]').click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'signup-form') self.teacher.find(By.ID, 'first_name').send_keys('first') self.teacher.find(By.ID, 'last_name').send_keys('last') self.teacher.find(By.ID, 'email').send_keys('*****@*****.**') self.teacher.find(By.ID, 'company').send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]').click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]').send_keys('25') self.teacher.find(By.XPATH, '//input[@type="submit"]').click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]'))) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7770 - 020 - Admin | Add co-instructors to a course @pytest.mark.skipif(str(7770) not in TESTS, reason='Excluded') def test_admin_add_coinstructors_to_a_course_7770(self): """Add co-instructors to a course. Steps: Log into Tutor as an admin From the user menu, select 'Admin' From the 'Course Organization' menu, select 'Courses' In the Courses table, find the correct course and click the 'Edit' button on the right side of that row Click on the 'Teachers' tab In the search box, enter the teacher's name or username Select the teacher in the list below the search bar or hit the down arrow followed by the enter/return key Expected Result: Co-instructor is linked to the affected course """ self.ps.test_updates['name'] = 'cc1.01.020' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.020', '7770'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login(username=os.getenv('ADMIN_USER'), password=os.getenv('ADMIN_PASSWORD')) self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a[@role="menuitem" and contains(text(),"Admin")]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Course Organization'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Courses'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Edit'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Teachers'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.ID, 'course_teacher'))).send_keys('teacher0') element = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//ul[contains(@class,"ui-autocomplete")]' + '//li[contains(text(),"(teacher0")]'))) teacher_name = element.text.split(' (')[0] element.click() # check that the teacher has been added to the table print(teacher_name) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//td[contains(text(),"' + teacher_name + '")]'))) self.ps.test_updates['passed'] = True # Case C7771 - 021 - Teacher | Login with an Existing OpenStax Account @pytest.mark.skipif(str(7771) not in TESTS, reason='Excluded') def test_teacher_login_with_an_existing_openstax_account_7771(self): """Log in with an Existing OpenStax Accounts username. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Click on faculty login You are redirected to the accounts page. Enter a username and password click on Login. Expected Result: Login should be successful. It should take you to the teacher course picker/dashboard page. """ self.ps.test_updates['name'] = 'cc1.01.021' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.021', '7771'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'auth_key').send_keys(self.teacher.username) self.teacher.find(By.ID, 'password').send_keys(self.teacher.password) # click on the sign in button self.teacher.find(By.XPATH, '//button[text()="Sign in"]').click() self.teacher.page.wait_for_page_load() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C7772 - 022 - Teacher | Access the Concept Coach course @pytest.mark.skipif(str(7772) not in TESTS, reason='Excluded') def test_teacher_access_the_cc_course_7772(self): """Access the Concept Coach course. Steps: Once you login you will be taken to a course picker page. Click on the course you want to check the dashboard Expected Result: At Concept Coach teacher dashboard """ self.ps.test_updates['name'] = 'cc1.01.022' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.022', '7772'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() assert('cc-dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C7773 - 023 - Admin | Distribute access codes for the course @pytest.mark.skipif(str(7773) not in TESTS, reason='Excluded') def test_admin_distribute_access_codes_for_the_course_7773(self): """Distribute access codes for the teacher's course. Steps: CC approves a faculty. Login as admin Click on user menu Click on Admin Click on Salesforce tab Click on import [Do not check the box] This will automatically create a course for the teacher created. Email is sent to the email id used when signing up with the unique course URL. Expected Result: Instructors are emailed the unique course url to the address provided when they signed up. """ self.ps.test_updates['name'] = 'cc1.01.023' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.023', '7773'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, # pasta_user=self.ps, # capabilities=self.desired_capabilities ) admin.login() admin.open_user_menu() admin.find(By.LINK_TEXT, 'Admin').click() admin.page.wait_for_page_load() admin.find(By.LINK_TEXT, 'Salesforce').click() admin.page.wait_for_page_load() admin.find(By.XPATH, '//input[@vale="Import Courses"]').click() self.ps.test_updates['passed'] = True # Case C7774 - 024 - Teacher | Access CC help and support during the course @pytest.mark.skipif(str(7774) not in TESTS, reason='Excluded') def test_teacher_acccess_cc_help_and_support_during_the_course_7774(self): """Access Concept Coach help and support during the course. Steps: Login as teacher Click on the course name On dashboard click on the name of the teacher It drops down and displays several options. Click on Get Help Expected Result: It should open a new tab which shows the openstax.force.com """ self.ps.test_updates['name'] = 'cc1.01.024' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.024', '7774'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Get Help").click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]').click() self.ps.test_updates['passed'] = True # Case C7775 - 025 - Teacher | Access CC help and support after course ends @pytest.mark.skipif(str(7775) not in TESTS, reason='Excluded') def test_teacher_access_cc_help_and_support_after_course_ends_7775(self): """Access Concept Coach help and support after the end of the course. Steps: Login as teacher Click on the course name On dashboard click on the name of the teacher It drops down and displays several options. Click on Get Help Expected Result: It should open a new tab which shows the CC help center """ self.ps.test_updates['name'] = 'cc1.01.025' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.025', '7775'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Get Help").click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]').click() self.ps.test_updates['passed'] = True
class TestImproveLoginRegistrationEnrollment(unittest.TestCase): """CC2.09 - Improve Login, Registration, Enrollment.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.student.delete() except: pass try: self.teacher.delete() except: pass def get_enrollemnt_code(self, number=0): """ Steps: Sign in as teacher Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Return value: code, enrollemnt_url code - enrollment code enrollemnt_url - url of book for course """ self.teacher.login() if number != 0: cc_courses = self.teacher.find_all( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ) cc_courses[number].click() else: self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Course Settings and Roster' ).click() self.teacher.find( By.XPATH, '//span[contains(text(),"Your student enrollment code")]' ).click() self.teacher.sleep(1) code = self.teacher.find( By.XPATH, '//p[@class="code"]' ).text enrollement_url = self.teacher.find( By.XPATH, '//textarea' ).text enrollement_url = enrollement_url.split('\n')[5] self.teacher.find( By.XPATH, '//button[@class="close"]' ).click() self.teacher.sleep(0.5) self.teacher.logout() return code, enrollement_url def create_user(self, start_num, end_num): """ creates a new user and return the username """ self.student.get("http://accounts-qa.openstax.org") num = str(randint(start_num, end_num)) self.student.find(By.LINK_TEXT, 'Sign up').click() self.student.find( By.ID, 'identity-login-button').click() self.student.find( By.ID, 'signup_first_name').send_keys('first_name_001') self.student.find( By.ID, 'signup_last_name').send_keys('last_name_001') self.student.find( By.ID, 'signup_email_address').send_keys('*****@*****.**') self.student.find( By.ID, 'signup_username').send_keys('automated_09_'+num) self.student.find( By.ID, 'signup_password' ).send_keys(os.getenv('STUDENT_PASSWORD')) self.student.find( By.ID, 'signup_password_confirmation' ).send_keys(os.getenv('STUDENT_PASSWORD')) self.student.find(By.ID, 'signup_i_agree').click() self.student.find( By.ID, 'create_account_submit').click() self.student.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Sign out') ) ).click() print('automated_09_'+num) return 'automated_09_'+num # 14820 - 001 - Teacher | Register for teaching a CC course as new faculty @pytest.mark.skipif(str(14820) not in TESTS, reason='Excluded') def test_teacher_register_for_teaching_cc_course_as_new_facult_14820(self): """Register for teaching a CC course as new faculty. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc2.09.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.001', '14820'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 14819 - 002 - Teacher | Register for teaching a CC course as # returning faculty for the same book @pytest.mark.skipif(str(14819) not in TESTS, reason='Excluded') def test_teacher_register_for_teaching_cc_course_as_returning_14819(self): """Register for teaching a CC course as returning faculty. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Click "Course Settings and Roster" from the user menu Click "Add Section" Create a name when prompted Click "Add" Click on the sections from previous semesters Click "Archive Section" Expected Result: A new section is added and the old sections are archived """ self.ps.test_updates['name'] = 'cc2.09.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.002', '14819'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # add a new section new_section_name = "new_section_" + str(randint(100, 999)) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"add-period")]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys(new_section_name) self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Add"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + new_section_name + '"]') ) ) # revove old section old_section_name = self.teacher.find(By.XPATH, '//a[@role="tab"]').text self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + old_section_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.sleep(2) archived = self.teacher.driver.find_elements( By.XPATH, '//li//a[@role="tab" and text()="' + old_section_name + '"]') assert(len(archived) == 0), ' not archived' # arhive new section and re-add old section as clean-up self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + new_section_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"view-archived-periods")]//button') ) ).click() periods = self.teacher.driver.find_elements( By.XPATH, '//div[@class="modal-content"]//tbody//tr' ) for period in periods: try: period.find_element( By.XPATH, ".//td[text()='" + old_section_name + "']") period.find_element( By.XPATH, ".//td//span[contains(@class,'restore-period')]//button" ).click() break except NoSuchElementException: if period == periods[-1]: raise Exception self.ps.test_updates['passed'] = True # 14759 - 003 - Student | Sign up and enroll in a CC course @pytest.mark.skipif(str(14759) not in TESTS, reason='Excluded') def test_teacher_sign_up_and_enroll_in_a_cc_course_14759(self): """Sign up and enroll in a CC course. Steps: Sign in as teacher Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Copy and paste the URL into an incognito window Click "Jump to Concept Coach" Click "Launch Concept Coach" Click Sign Up Click Sign up with a password Fill in the required fields Click "Create Account" Enter the numerical enrollment code you get from the teacher Click "Enroll" Enter school issued ID, OR skip this step for now Expected Result: The user is presented with a message that confirms enrollment Is redirected to the CC assignment """ self.ps.test_updates['name'] = 'cc2.09.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.003', '14759'] self.ps.test_updates['passed'] = False # Test steps and verification assertions code, enrollement_url = self.get_enrollemnt_code() rand_username = self.create_user(100, 999) self.student.get(enrollement_url) self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//div[text()="Sign in"]' ).click() self.student.sleep(0.5) login_window = self.student.driver.window_handles[1] cc_window = self.student.driver.window_handles[0] self.student.driver.switch_to_window(login_window) print(rand_username) self.student.find( By.ID, 'auth_key').send_keys(rand_username) print(self.student.password) self.student.find( By.ID, 'password').send_keys(self.student.password) self.student.find( By.XPATH, '//button[text()="Sign in"]').click() try: self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() except NoSuchElementException: pass self.student.driver.switch_to_window(cc_window) self.student.sleep(1) self.student.find( By.XPATH, '//input[@placeholder="enrollment code"]' ).send_keys(code) self.student.find( By.XPATH, '//button/span[text()="Enroll"]' ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[@class="skip"]') ) ).click() # check for confirmation message self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//*[contains(text(),"You have successfully joined")]') ) ) self.ps.test_updates['passed'] = True # 14862 - 004 - Student | Sign in and enroll in a CC course @pytest.mark.skipif(str(14862) not in TESTS, reason='Excluded') def test_teacher_sign_in_and_enroll_in_a_cc_course_14862(self): """Sign in and enroll in a CC course. Steps: Sign in as teacher100 Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Copy and paste the URL into an incognito window Click "Jump to Concept Coach" Click "Launch Concept Coach" Click Sign In Sign in as student71 Enter the numerical enrollment code you get from the teacher Click "Enroll" Enter school issued ID, OR skip this step for now Expected Result: The user is presented with a message that confirms enrollment Is redirected to the CC assignment """ self.ps.test_updates['name'] = 'cc2.09.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.004', '14862'] self.ps.test_updates['passed'] = False # Test steps and verification assertions code, enrollement_url = self.get_enrollemnt_code() # use a new student so that when run a second time no issues # with student already being enrolled in course rand_username = self.create_user(100, 999) self.student.get(enrollement_url) self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//div[text()="Sign in"]' ).click() self.student.sleep(0.5) login_window = self.student.driver.window_handles[1] cc_window = self.student.driver.window_handles[0] self.student.driver.switch_to_window(login_window) self.student.find( By.ID, 'auth_key').send_keys(rand_username) self.student.find( By.ID, 'password').send_keys(self.student.password) self.student.find( By.XPATH, '//button[text()="Sign in"]').click() try: self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() except NoSuchElementException: pass self.student.driver.switch_to_window(cc_window) self.student.sleep(1) self.student.find( By.XPATH, '//input[@placeholder="enrollment code"]' ).send_keys(code) self.student.find( By.XPATH, '//button/span[text()="Enroll"]' ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[@class="skip"]') ) ).click() # check for confirmation message self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//*[contains(text(),"You have successfully joined")]') ) ) self.ps.test_updates['passed'] = True # 14771 - 005 - User | View a message that says you need an enrollment code # before signing up @pytest.mark.skipif(str(14771) not in TESTS, reason='Excluded') def test_user_view_a_message_that_says_you_need_an_enrollment_14771(self): """View a message that says you need an enrollment code before signing up. Steps: Sign in as teacher100 Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Copy and paste the URL into an incognito window Click "Jump to Concept Coach" Click "Launch Concept Coach" Expected Result: The user is presented with a message that says "Sign up with your enrollment code. If you don't have an enrollment code, contact your instructor." """ self.ps.test_updates['name'] = 'cc2.09.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.005', '14771'] self.ps.test_updates['passed'] = False # Test steps and verification assertions code, enrollement_url = self.get_enrollemnt_code() self.student.get(enrollement_url) self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[@class="code-required"]') ) ) self.ps.test_updates['passed'] = True # 14821 - 006 - Student | Jump to CC from the top of the reading @pytest.mark.skipif(str(14821) not in TESTS, reason='Excluded') def test_student_jump_to_cc_from_the_top_of_the_reading_14821(self): """Jump to CC from the top of the reading. Steps: If the user has more than one course, click on a CC course name Click on a non-introductory section Click "Jump to Concept Coach" Expected Result: The screen jumps to the "Launch Concept Coach" button """ self.ps.test_updates['name'] = 'cc2.09.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.006', '14821'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.find( By.XPATH, '//a[contains(@href,"cnx")]' # possibly change ).click() self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button//span[text()="Contents"]') ) ).click() self.student.sleep(0.5) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]') ) ).click() self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ) self.ps.test_updates['passed'] = True # 14822 - 007 - Teacher | Jump to CC from the top of the reading @pytest.mark.skipif(str(14822) not in TESTS, reason='Excluded') def test_teacher_jump_to_cc_from_the_top_of_the_reading_14822(self): """Jump to CC from the top of the reading. Steps: If the user has more than one course, click on a CC course name Click "Online Book" Click on a non-introductory section Click "Jump to Concept Coach" Expected Result: The screen jumps to the "Launch Concept Coach" button """ self.ps.test_updates['name'] = 'cc2.09.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.007', '14822'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() # open book self.teacher.driver.find_element( By.XPATH, '//a//span[contains(text(),"Online Book")]' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('cnx' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' # get to non-introductory section of book self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button//span[text()="Contents"]') ) ).click() self.student.sleep(0.5) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]') ) ).click() self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ) self.ps.test_updates['passed'] = True
class TestImprovesScoresReporting(unittest.TestCase): """CC2.08 - Improves Scores Reporting.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities, ) self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # 14806 - 001 - Teacher | View student scores as percent complete @pytest.mark.skipif(str(14806) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_as_percent_complete_14806(self): """View student scores as percent complete. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click on the icon in the progress column Expected Result: Student Scores are presented as percent complete """ self.ps.test_updates['name'] = 'cc2.08.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.001', '14806'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//button[contains(text(),"percentage")]' ).click() self.teacher.find( By.XPATH, '//div[contains(@class,"score")]//a[contains(text(),"%")]') self.ps.test_updates['passed'] = True # 14807 - 002 - Teacher | View student scores as number of total @pytest.mark.skipif(str(14807) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_as_number_of_total_14807(self): """View student scores as number of total. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Number" Expected Result: Student Scores are presented as "Number of Total" """ self.ps.test_updates['name'] = 'cc2.08.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.002', '14807'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//button[contains(text(),"number")]' ).click() self.teacher.find( By.XPATH, '//div[contains(@class,"score")]//a[contains(text()," of ")]') self.ps.test_updates['passed'] = True # 14808 - 003 - Teacher | View tooltips on hover @pytest.mark.skipif(str(14808) not in TESTS, reason='Excluded') def test_teacher_view_tooltips_on_hover_14808(self): """View tooltips on hover. Steps: If the user has more than one course, click on a CC course name Hover over the info icons Expected Result: The user is presented with tooltips """ self.ps.test_updates['name'] = 'cc2.08.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.003', '14808'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//i[@type="info-circle"]').click() self.teacher.find( By.XPATH, '//h3[@class="popover-title" and ' + 'contains(text(), "Class and Overall Averages")]') self.ps.test_updates['passed'] = True # 14810 - 004 - Teacher | Sort student scores based on score @pytest.mark.skipif(str(14810) not in TESTS, reason='Excluded') def test_teacher_sort_student_scores_based_on_score_14810(self): """Sort student scores based on score. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Score" for the desired assignment Expected Result: Students are sorted based on score """ self.ps.test_updates['name'] = 'cc2.08.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.004', '14810'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//div[contains(@class,"sortable")]//div[text()="Score"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-descending")]//div[text()="Score"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-ascending")]//div[text()="Score"]' ) self.ps.test_updates['passed'] = True # 14811 - 005 - Teacher | Sort student scores based on number complete @pytest.mark.skipif(str(14811) not in TESTS, reason='Excluded') def test_teacher_sort_student_scores_based_on_number_completed_14811(self): """Sort student scores based on number complete. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Progress" for the desired assignment Expected Result: Students are sorted based on number completed """ self.ps.test_updates['name'] = 'cc2.08.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.005', '14811'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//div[contains(@class,"sortable")]//div[text()="Progress"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-descending")]//div[text()="Progress"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-ascending")]//div[text()="Progress"]' ) self.ps.test_updates['passed'] = True # 14668 - 006 - Teacher | All popups in the roster have an X button @pytest.mark.skipif(str(14668) not in TESTS, reason='Excluded') def test_teacher_all_popups_in_the_roster_have_an_x_button_14668(self): """All popups in the roster have an X button. Steps: If the user has more than one course, click on a CC course name Click "Course Settings and Roster" from the user menu Click "Rename Course," "Change Course Timezone," "View Archived Period," "Add Period," "Rename," and "Get Student Enrollment Code" Expected Result: All pop ups have an X button """ self.ps.test_updates['name'] = 'cc2.08.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.006', '14668'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a[text()="Course Settings and Roster"]' ).click() self.teacher.sleep(1) # rename couse self.teacher.find( By.XPATH, '//button//span[contains(text(),"Rename Course")]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() self.teacher.sleep(0.75) # course timezone self.teacher.find( By.XPATH, '//button//span[contains(text(),"Change Course Timezone")]' ).click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() self.teacher.sleep(0.75) # add period/section self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() self.teacher.sleep(0.75) # rename period self.teacher.find( By.XPATH, '//span[contains(@class,"rename-period")]//button' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() self.teacher.sleep(0.75) # student enrollemnt code self.teacher.find( By.XPATH, '//button//span[contains(text(),"Your student enrollment code")]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() self.teacher.sleep(0.75) # View Archived periods self.teacher.find( By.XPATH, '//button//span[contains(text(),"View Archived ")]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ).click() self.ps.test_updates['passed'] = True # 14670 - 007 - Teacher | Close popup with X button @pytest.mark.skipif(str(14670) not in TESTS, reason='Excluded') def test_teacher_close_popup_with_x_button_14670(self): """Close popup with X button. Steps: If the user has more than one course, click on a CC course name Click "Course Settings and Roster" from the user menu Click ONE of the following: * Rename Course * Change Course Timezone * View Archived Period * Add Period * Rename * Get Student Enrollment Code Click the X on the pop up Expected Result: Popup is closed """ self.ps.test_updates['name'] = 'cc2.08.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.007', '14670'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a[text()="Course Settings and Roster"]' ).click() self.teacher.sleep(1) # rename couse self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button//span[contains(text(),"Rename Course")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]') ) ).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find( By.XPATH, '//div[@class="modal-content"]') # course timezone self.teacher.find( By.XPATH, '//button//span[contains(text(),"Change Course Timezone")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]') ) ).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find( By.XPATH, '//div[@class="modal-content"]') # add period/section self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]') ) ).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find( By.XPATH, '//div[@class="modal-content"]') # rename period self.teacher.find( By.XPATH, '//span[contains(@class,"rename-period")]//button' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]') ) ).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find( By.XPATH, '//div[@class="modal-content"]') # student enrollemnt code self.teacher.find( By.XPATH, '//button//span[contains(text(),"Your student enrollment code")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]') ) ).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find( By.XPATH, '//div[@class="modal-content"]') # View Archived Periods self.teacher.find( By.XPATH, '//button//span[contains(text(),"View Archived")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]') ) ).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find( By.XPATH, '//div[@class="modal-content"]') self.ps.test_updates['passed'] = True # 14669 - 008 - Teacher | The icon in the progress column shows info on # percentage complete, attempted out of total possible questions, and # the date last worked @pytest.mark.skipif(str(14669) not in TESTS, reason='Excluded') def test_teacher_the_icon_in_the_progress_column_shows_info_14669(self): """The icon in the progress column shows info. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click on the icon in the progress column for a completed assignment Expected Result: Shows information on percentage complete, attempted out of total possible questions as well as the date last worked """ self.ps.test_updates['name'] = 'cc2.08.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.008', '14669'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) icon = self.teacher.find( By.XPATH, '//span[contains(@aria-describedby,"scores-cell-info-popover")]') actions = ActionChains(self.teacher.driver) actions.move_to_element(icon) actions.perform() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@id,"scores-cell-info-popover")]') ) ).click() # more on each individial thing self.ps.test_updates['passed'] = True # 14812 - 009 - Teacher | Import CC Student Scores export into an LMS @pytest.mark.skipif(str(14812) not in TESTS, reason='Excluded') def test_teacher_import_cc_student_scores_export_into_an_lms_14812(self): """Import CC student scores export into an LMS. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc2.08.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.009', '14812'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 14813 - 010 - Teacher | View zeros in exported scores instead of blank # cells for incomplete assignments @pytest.mark.skipif(str(14813) not in TESTS, reason='Excluded') def test_teacher_view_zeros_in_exported_scores_instead_of_blan_14813(self): """View zeros in exported scores for incomplete assignments. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Export" Open the excel file Expected Result: For incomplete assignments or assignments that are not started, there are zeros instead of blank cells """ self.ps.test_updates['name'] = 'cc2.08.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.010', '14813'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//div[@class="export-button"]//button' ).click() # wait until button return and no longer is loading self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="export-button"]//button' + '/span[text()="Export"]') ) ) self.teacher.sleep(2) coursename = self.teacher.find( By.XPATH, '//div[@class="course-name"]').text coursename = coursename.replace(' ', '_') + "_Scores" home = os.getenv("HOME") files = os.listdir(home + '/Downloads') file_name = '' for i in range(len(files)): if (coursename in files[i]) and (files[i][-5:] == '.xlsx'): file_name = files[i] break else: if i == len(files)-1: raise Exception period = self.teacher.find( By.XPATH, '//span[contains(@class,"tab-item-period-name")]').text wb = load_workbook(str(home + '/Downloads/' + file_name)) sheet = wb[period + ' - %'] rows = sheet.rows start_row = float("inf") for i in range(len(sheet.rows)): if rows[i][0].value == 'First Name': start_row = i if i >= start_row: if rows[i][4].value == 0: # found that 0% is being used istead of blanks break elif rows[i+1][4].value is None: print('empty cell instead of 0%') raise Exception self.ps.test_updates['passed'] = True # 14814 - 011 - Teacher | Green check icon is displayed for completed # assignments @pytest.mark.skipif(str(14814) not in TESTS, reason='Excluded') def test_teacher_green_check_icon_is_displayed_for_completed_14814(self): """Green check icon is displayed for completed assignments. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores Expected Result: Green check icon is displayed for completed assignments """ self.ps.test_updates['name'] = 'cc2.08.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.011', '14814'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) # scroll to find a green checkmark assignments = self.teacher.find_all( By.XPATH, "//span[contains(@aria-describedby,'header-cell-title')]") for i in range(len(assignments)//4): try: self.teacher.find( By.XPATH, '//span[contains(@class,"trig")]' + '//*[contains(@class,"finished")]') break except (NoSuchElementException, ElementNotVisibleException): if i >= (len(assignments)//4)-1: print("completed assignments for this period") raise Exception # try to drag scroll bar instead of scrolling scroll_bar = self.teacher.find( By.XPATH, '//div[contains(@class,"ScrollbarLayout_faceHorizontal")]') actions = ActionChains(self.teacher.driver) actions.move_to_element(scroll_bar) actions.click_and_hold() actions.move_by_offset(50, 0) actions.release() actions.perform() self.ps.test_updates['passed'] = True # 14815 - 012 - Teacher | The class average info icon displays a definition # about scores from completed assignments @pytest.mark.skipif(str(14815) not in TESTS, reason='Excluded') def test_teacher_class_average_info_icon_displays_definition_14815(self): """The class average info icon displays a definition. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores Click on the info icon next to "Class Average" Expected Result: The class average info icon displays a definition about scores from completed assignments """ self.ps.test_updates['name'] = 'cc2.08.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.012', '14815'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//i[@type="info-circle"]').click() self.teacher.find( By.XPATH, '//h3[@class="popover-title" and ' + 'contains(text(), "Class and Overall Averages")]') self.ps.test_updates['passed'] = True # 14816 - 013 - Teacher | View the overall score column @pytest.mark.skipif(str(14816) not in TESTS, reason='Excluded') def test_teacher_view_the_overall_score_column_14816(self): """View the overall score column. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores Expected Result: User is presented with the overall score column next to student names """ self.ps.test_updates['name'] = 'cc2.08.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.013', '14816'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//div[contains(@class,"overall-header-cell")]') self.ps.test_updates['passed'] = True
class TestUserLogin(unittest.TestCase): """T1.36 - User login.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.admin = Admin(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.content = ContentQA(existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.student = Student(existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.teacher = Teacher(existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) def tearDown(self): """Test destructor.""" self.ps.update_job(job_id=str(self.admin.driver.session_id), **self.ps.test_updates) try: self.teacher = None self.student = None self.content = None self.admin.delete() except: pass # Case C8238 - 001 - Admin | Log into Tutor @pytest.mark.skipif(str(8238) not in TESTS, reason='Excluded') def test_admin_log_into_tutor_8238(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Expected Result: User is logged in """ self.ps.test_updates['name'] = 't1.36.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.001', '8238'] self.ps.test_updates['passed'] = False self.admin.get(self.admin.url) self.admin.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.admin.driver.get_window_size()['width'] <= \ self.admin.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.admin.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login'))).click() self.admin.page.wait_for_page_load() self.admin.find(By.ID, 'auth_key').send_keys(self.admin.username) self.admin.find(By.ID, 'password').send_keys(self.admin.password) # click on the sign in button self.admin.find(By.XPATH, '//button[text()="Sign in"]').click() self.admin.page.wait_for_page_load() assert('dashboard' in self.admin.current_url()), \ 'Not taken to dashboard: %s' % self.admin.current_url() self.ps.test_updates['passed'] = True # Case C8239 - 002 - Admin | Access the Admin Console @pytest.mark.skipif(str(8239) not in TESTS, reason='Excluded') def test_admin_access_the_admin_console_8239(self): """Access the Admin console. Steps: Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click on the user menu Click on the Admin option Expected Result: User is presented with the admin console """ self.ps.test_updates['name'] = 't1.36.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.002', '8239'] self.ps.test_updates['passed'] = False # self.user = admin self.admin.login() self.admin.open_user_menu() self.admin.wait.until( expect.element_to_be_clickable((By.LINK_TEXT, 'Admin'))).click() self.admin.page.wait_for_page_load() self.admin.find(By.XPATH, '//h1[contains(text(),"Admin Console")]') self.ps.test_updates['passed'] = True # Case C8240 - 003 - Admin | Log out @pytest.mark.skipif(str(8240) not in TESTS, reason='Excluded') def test_admin_log_out_8240(self): """Log out. Steps: Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The User is signed out """ self.ps.test_updates['name'] = 't1.36.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.003', '8240'] self.ps.test_updates['passed'] = False self.admin.login() self.admin.open_user_menu() self.admin.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]'))).click() self.admin.page.wait_for_page_load() self.admin.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C8241 - 004 - Content Analyst | Log into Tutor @pytest.mark.skipif(str(8241) not in TESTS, reason='Excluded') def test_content_analyst_log_into_tutor_8241(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Expected Result: The user is signed in """ self.ps.test_updates['name'] = 't1.36.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.004', '8241'] self.ps.test_updates['passed'] = False self.content.get(self.content.url) self.content.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.content.driver.get_window_size()['width'] <= \ self.content.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.content.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.content.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login'))).click() self.content.page.wait_for_page_load() self.content.find(By.ID, 'auth_key').send_keys(self.content.username) self.content.find(By.ID, 'password').send_keys(self.content.password) # click on the sign in button self.content.find(By.XPATH, '//button[text()="Sign in"]').click() self.content.page.wait_for_page_load() assert('dashboard' in self.content.current_url()), \ 'Not taken to dashboard: %s' % self.content.current_url() self.ps.test_updates['passed'] = True # Case C8242 - 005 - Content Analyst | Access the QA Viewer @pytest.mark.skipif(str(8242) not in TESTS, reason='Excluded') def test_content_analyst_access_the_qa_viewer_8242(self): """Access the QA Viewer. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the QA Content option Expected Result: The user is presented with the QA viewer """ self.ps.test_updates['name'] = 't1.36.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.005', '8242'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"QA Content") and @role="menuitem"]' ))).click() self.content.page.wait_for_page_load() assert('/qa' in self.content.current_url()), \ 'Not taken to the QA viewer: %s' % self.content.current_url() self.ps.test_updates['passed'] = True # Case C8243 - 006 - Content Analyst | Access the Content Analyst Console @pytest.mark.skipif(str(8243) not in TESTS, reason='Excluded') def test_content_analyst_access_the_content_analyst_console_8243(self): """Access the Content Annalyst Console. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Content Analyst option Expected Result: The user is presented with the Content Analyst Console """ self.ps.test_updates['name'] = 't1.36.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.006', '8243'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"Content Analyst") and @role="menuitem"]' ))).click() self.content.page.wait_for_page_load() self.content.find(By.XPATH, '//h1[contains(text(),"Content Analyst Console")]') self.ps.test_updates['passed'] = True # Case C8244 - 007 - Content Analyst | Log out @pytest.mark.skipif(str(8244) not in TESTS, reason='Excluded') def test_content_analyst_log_out_8244(self): """Log out. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.007', '8244'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]'))).click() self.content.page.wait_for_page_load() self.content.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C8245 - 008 - Student | Log into Tutor @pytest.mark.skipif(str(8245) not in TESTS, reason='Excluded') def test_student_log_into_tutor_8245(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the student account in the username and password text boxes Click on the 'Sign in' button Expected Result: The user is logged in """ self.ps.test_updates['name'] = 't1.36.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.008', '8245'] self.ps.test_updates['passed'] = False self.student.get(self.student.url) self.student.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.student.driver.get_window_size()['width'] <= \ self.student.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.student.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.student.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login'))).click() self.student.page.wait_for_page_load() self.student.find(By.ID, 'auth_key').send_keys(self.student.username) self.student.find(By.ID, 'password').send_keys(self.student.password) # click on the sign in button self.student.find(By.XPATH, '//button[text()="Sign in"]').click() self.student.page.wait_for_page_load() assert('dashboard' in self.student.current_url()), \ 'Not taken to dashboard: %s' % self.student.current_url() self.ps.test_updates['passed'] = True # Case C8246 - 009 - Teacher | Log into Tutor @pytest.mark.skipif(str(8246) not in TESTS, reason='Excluded') def test_teacher_log_into_tutor_8246(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the teacher account in the username and password text boxes Click on the 'Sign in' button Expected Result: The user is logged in """ self.ps.test_updates['name'] = 't1.36.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.009', '8246'] self.ps.test_updates['passed'] = False self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'auth_key').send_keys(self.teacher.username) self.teacher.find(By.ID, 'password').send_keys(self.teacher.password) # click on the sign in button self.teacher.find(By.XPATH, '//button[text()="Sign in"]').click() self.teacher.page.wait_for_page_load() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C58271 - 010 - Student | Log out @pytest.mark.skipif(str(58271) not in TESTS, reason='Excluded') def test_content_analyst_log_out_58271(self): """Log out. Steps: Click on the 'Login' button Enter the student account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.010', '58271'] self.ps.test_updates['passed'] = False self.student.login() self.student.open_user_menu() self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]'))).click() self.student.page.wait_for_page_load() self.student.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C58272 - 011 - Teacher | Log out @pytest.mark.skipif(str(58272) not in TESTS, reason='Excluded') def test_teacher_log_out_58272(self): """Log out. Steps: Click on the 'Login' button Enter the teacher account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.011', '58272'] self.ps.test_updates['passed'] = False self.teacher.login() self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True
class TestUserLogin(unittest.TestCase): """T1.36 - User login.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.admin = Admin( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.content = ContentQA( existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher = Teacher( existing_driver=self.admin.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.admin.driver.session_id), **self.ps.test_updates ) try: self.teacher = None self.student = None self.content = None self.admin.delete() except: pass # Case C8238 - 001 - Admin | Log into Tutor @pytest.mark.skipif(str(8238) not in TESTS, reason='Excluded') def test_admin_log_into_tutor_8238(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Expected Result: User is logged in """ self.ps.test_updates['name'] = 't1.36.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.001', '8238'] self.ps.test_updates['passed'] = False self.admin.get(self.admin.url) self.admin.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.admin.driver.get_window_size()['width'] <= \ self.admin.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.admin.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]' ) # check if the menu is collapsed and, if yes, open it if('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login') ) ).click() self.admin.page.wait_for_page_load() self.admin.find( By.ID, 'auth_key' ).send_keys(self.admin.username) self.admin.find( By.ID, 'password' ).send_keys(self.admin.password) # click on the sign in button self.admin.find( By.XPATH, '//button[text()="Sign in"]' ).click() self.admin.page.wait_for_page_load() assert('dashboard' in self.admin.current_url()), \ 'Not taken to dashboard: %s' % self.admin.current_url() self.ps.test_updates['passed'] = True # Case C8239 - 002 - Admin | Access the Admin Console @pytest.mark.skipif(str(8239) not in TESTS, reason='Excluded') def test_admin_access_the_admin_console_8239(self): """Access the Admin console. Steps: Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click on the user menu Click on the Admin option Expected Result: User is presented with the admin console """ self.ps.test_updates['name'] = 't1.36.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.002', '8239'] self.ps.test_updates['passed'] = False # self.user = admin self.admin.login() self.admin.open_user_menu() self.admin.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Admin') ) ).click() self.admin.page.wait_for_page_load() self.admin.find( By.XPATH, '//h1[contains(text(),"Admin Console")]') self.ps.test_updates['passed'] = True # Case C8240 - 003 - Admin | Log out @pytest.mark.skipif(str(8240) not in TESTS, reason='Excluded') def test_admin_log_out_8240(self): """Log out. Steps: Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The User is signed out """ self.ps.test_updates['name'] = 't1.36.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.003', '8240'] self.ps.test_updates['passed'] = False self.admin.login() self.admin.open_user_menu() self.admin.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]') ) ).click() self.admin.page.wait_for_page_load() self.admin.find( By.XPATH, '//div[contains(@class,"tutor-home")]') self.ps.test_updates['passed'] = True # Case C8241 - 004 - Content Analyst | Log into Tutor @pytest.mark.skipif(str(8241) not in TESTS, reason='Excluded') def test_content_analyst_log_into_tutor_8241(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Expected Result: The user is signed in """ self.ps.test_updates['name'] = 't1.36.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.004', '8241'] self.ps.test_updates['passed'] = False self.content.get(self.content.url) self.content.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.content.driver.get_window_size()['width'] <= \ self.content.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.content.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]' ) # check if the menu is collapsed and, if yes, open it if('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.content.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login') ) ).click() self.content.page.wait_for_page_load() self.content.find( By.ID, 'auth_key' ).send_keys(self.content.username) self.content.find( By.ID, 'password' ).send_keys(self.content.password) # click on the sign in button self.content.find( By.XPATH, '//button[text()="Sign in"]' ).click() self.content.page.wait_for_page_load() assert('dashboard' in self.content.current_url()), \ 'Not taken to dashboard: %s' % self.content.current_url() self.ps.test_updates['passed'] = True # Case C8242 - 005 - Content Analyst | Access the QA Viewer @pytest.mark.skipif(str(8242) not in TESTS, reason='Excluded') def test_content_analyst_access_the_qa_viewer_8242(self): """Access the QA Viewer. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the QA Content option Expected Result: The user is presented with the QA viewer """ self.ps.test_updates['name'] = 't1.36.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.005', '8242'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable(( By.XPATH, '//a[contains(text(),"QA Content") and @role="menuitem"]' )) ).click() self.content.page.wait_for_page_load() assert('/qa' in self.content.current_url()), \ 'Not taken to the QA viewer: %s' % self.content.current_url() self.ps.test_updates['passed'] = True # Case C8243 - 006 - Content Analyst | Access the Content Analyst Console @pytest.mark.skipif(str(8243) not in TESTS, reason='Excluded') def test_content_analyst_access_the_content_analyst_console_8243(self): """Access the Content Annalyst Console. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Content Analyst option Expected Result: The user is presented with the Content Analyst Console """ self.ps.test_updates['name'] = 't1.36.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.006', '8243'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable(( By.XPATH, '//a[contains(text(),"Content Analyst") and @role="menuitem"]' )) ).click() self.content.page.wait_for_page_load() self.content.find( By.XPATH, '//h1[contains(text(),"Content Analyst Console")]' ) self.ps.test_updates['passed'] = True # Case C8244 - 007 - Content Analyst | Log out @pytest.mark.skipif(str(8244) not in TESTS, reason='Excluded') def test_content_analyst_log_out_8244(self): """Log out. Steps: Click on the 'Login' button Enter the content analyst account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.007', '8244'] self.ps.test_updates['passed'] = False self.content.login() self.content.open_user_menu() self.content.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]') ) ).click() self.content.page.wait_for_page_load() self.content.find( By.XPATH, '//div[contains(@class,"tutor-home")]' ) self.ps.test_updates['passed'] = True # Case C8245 - 008 - Student | Log into Tutor @pytest.mark.skipif(str(8245) not in TESTS, reason='Excluded') def test_student_log_into_tutor_8245(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the student account in the username and password text boxes Click on the 'Sign in' button Expected Result: The user is logged in """ self.ps.test_updates['name'] = 't1.36.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.008', '8245'] self.ps.test_updates['passed'] = False self.student.get(self.student.url) self.student.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.student.driver.get_window_size()['width'] <= \ self.student.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.student.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]' ) # check if the menu is collapsed and, if yes, open it if('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.student.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login') ) ).click() self.student.page.wait_for_page_load() self.student.find( By.ID, 'auth_key' ).send_keys(self.student.username) self.student.find( By.ID, 'password' ).send_keys(self.student.password) # click on the sign in button self.student.find( By.XPATH, '//button[text()="Sign in"]' ).click() self.student.page.wait_for_page_load() assert('dashboard' in self.student.current_url()), \ 'Not taken to dashboard: %s' % self.student.current_url() self.ps.test_updates['passed'] = True # Case C8246 - 009 - Teacher | Log into Tutor @pytest.mark.skipif(str(8246) not in TESTS, reason='Excluded') def test_teacher_log_into_tutor_8246(self): """Log into Tutor. Steps: Click on the 'Login' button Enter the teacher account in the username and password text boxes Click on the 'Sign in' button Expected Result: The user is logged in """ self.ps.test_updates['name'] = 't1.36.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.009', '8246'] self.ps.test_updates['passed'] = False self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]' ) # check if the menu is collapsed and, if yes, open it if('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login') ) ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'auth_key' ).send_keys(self.teacher.username) self.teacher.find( By.ID, 'password' ).send_keys(self.teacher.password) # click on the sign in button self.teacher.find( By.XPATH, '//button[text()="Sign in"]' ).click() self.teacher.page.wait_for_page_load() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C58271 - 010 - Student | Log out @pytest.mark.skipif(str(58271) not in TESTS, reason='Excluded') def test_content_analyst_log_out_58271(self): """Log out. Steps: Click on the 'Login' button Enter the student account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.010', '58271'] self.ps.test_updates['passed'] = False self.student.login() self.student.open_user_menu() self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]') ) ).click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//div[contains(@class,"tutor-home")]' ) self.ps.test_updates['passed'] = True # Case C58272 - 011 - Teacher | Log out @pytest.mark.skipif(str(58272) not in TESTS, reason='Excluded') def test_teacher_log_out_58272(self): """Log out. Steps: Click on the 'Login' button Enter the teacher account in the username and password boxes Click on the 'Sign in' button Click on the user menu Click on the Log out option Expected Result: The user is logged out """ self.ps.test_updates['name'] = 't1.36.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.011', '58272'] self.ps.test_updates['passed'] = False self.teacher.login() self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//input[contains(@value,"Log Out")]') ) ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//div[contains(@class,"tutor-home")]' ) self.ps.test_updates['passed'] = True
class TestCreateNewQuestionAndAssignmentTypes(unittest.TestCase): """T2.12 - Create New Question and Assignment Types.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) self.student = None try: self.teacher.delete() except: pass # 14739 - 001 - Teacher | Vocabulary question is a question type @pytest.mark.skipif(str(14739) not in TESTS, reason='Excluded') def test_teacher_vocabulary_question_is_a_question_type_14739(self): """Vocabulary question is a question type. Steps: Go to Tutor Click on the 'Login' button Enter the teacher account in the username and password text boxes Click on the 'Sign in' button Click "Write a new exercise" Click "New Vocabulary Term" Expected Result: The user is presented with a page where a new vocabulary question can be created """ self.ps.test_updates['name'] = 't2.12.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.001', '14739'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get("https://exercises-qa.openstax.org/") # login self.teacher.find( By.XPATH, '//div[@id="account-bar-content"]//a[text()="Sign in"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'auth_key' ).send_keys(self.teacher.username) self.teacher.find( By.ID, 'password' ).send_keys(self.teacher.password) self.teacher.find( By.XPATH, '//button[text()="Sign in"]' ).click() # create new vocab self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//a[@href="/exercises/new"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[text()="New Vocabulary Term"]') ) ).click() assert('/vocabulary/new' in self.teacher.current_url()), \ 'not at new vocab page' self.ps.test_updates['passed'] = True # 14741 - 002 - Teacher | True/False is a question type @pytest.mark.skipif(str(14741) not in TESTS, reason='Excluded') def test_teacher_truefalse_is_a_question_type_14741(self): """True/False is a question type. Steps: Click "Write a new exercise" Click on the "True/False" radio button Expected Result: The user is presented with a page where a True/False question can be created """ self.ps.test_updates['name'] = 't2.12.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.002', '14741'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get("https://exercises-qa.openstax.org/") # login self.teacher.find( By.XPATH, '//div[@id="account-bar-content"]//a[text()="Sign in"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'auth_key' ).send_keys(self.teacher.username) self.teacher.find( By.ID, 'password' ).send_keys(self.teacher.password) self.teacher.find( By.XPATH, '//button[text()="Sign in"]' ).click() # create new vocab self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//a[@href="/exercises/new"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//input[@label="True/False"]') ) ).click() self.teacher.find( By.XPATH, '//span[text()="True/False"]' ) self.ps.test_updates['passed'] = True # possibly changed implementation on site # no info icon found # 14742 - 003 - System | Display embedded videos with attribution and link # back to author @pytest.mark.skipif(str(14742) not in TESTS, reason='Excluded') def test_system_display_embedded_videos_with_attribution_14742(self): """Display embedded videos with attribution and a link back to author. Steps: Go to Tutor Click Login Sign in as student01 Click "HS AP Physics LG" Click on a homework assignment Click through it until you get to a video Click on the info icon on the video Expected Result: Attribution and links are displayed """ self.ps.test_updates['name'] = 't2.12.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.003', '14742'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # NOT DONE # create hw helper still not working # but works for manually created assignemnt, add assignemnt commented out # 14743 - 004 - Teacher | Each part of a multi-part question counts as a # seperate problem when scored @pytest.mark.skipif(str(14743) not in TESTS, reason='Excluded') def test_teacher_each_part_of_a_multipart_question_counts_as_14743(self): """Multi-part questions count as seperate problems when scored. Steps: Go to Tutor Click on the 'Login' button Log in as teacher03 Click "College Introduction to Sociology" Go to "Student Scores" Pick a homework that has multipart question Click "Review" Expected Result: There is a breadcrumb for each part of a multipart question """ self.ps.test_updates['name'] = 't2.12.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.004', '14743'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # create a hw with a multi part question, and gice it a randomized name # ID: 12061@6 is multi part self.teacher.login() self.teacher.find( By.XPATH, '//div[@data-appearance="intro_sociology"]' + '//a[not(contains(@href,"/cc-dashboard"))]' ).click() assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'problems': {'1.1': ['12024@10'], }, 'status': 'publish', } ) self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Student Scores' ).click() self.teacher.page.wait_for_page_load() # can just click the first review because assignemnt just created # and should be the most recent one self.teacher.find( By.LINK_TEXT, 'Review' ).click() cards = self.teacher.find_all( By.XPATH, '//div[contains(@class,"card-body")]') questions = self.teacher.find_all( By.XPATH, '//div[contains(@class,"openstax-question")]') breadcrumbs = self.teacher.find_all( By.XPATH, '//span[contains(@class,"openstax-breadcrumb")]') assert(len(questions) == len(breadcrumbs)), \ 'breadcrumbs and questions not equal' assert(len(cards) < len(breadcrumbs)), \ 'multipart question card has multiple questions,' + \ 'not matching up with breadcrumbs' self.ps.test_updates['passed'] = True # NOT DONE # same issue as above w/ add_homework helper # but works for manually created assignemnt # (add assignemnt gets commented out, manual assignemnt name added) # 14744 - 005 - Student | Each part of a multi-part question counts as a # seperate problem when scored @pytest.mark.skipif(str(14744) not in TESTS, reason='Excluded') def test_student_each_part_of_a_multipart_question_counts_as_14744(self): """Multi-part questions count as seperate problems when scored. Steps: Go to Tutor Click on the 'Login' button Log in as abarnes Click "College Introduction to Sociology" Click on a homework assignment Go through the questions Expected Result: There is a breadcrumb for each part in the multipart question and the progress/score is out of the total number of questions, rather than counting the multipart question as one question """ self.ps.test_updates['name'] = 't2.12.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.005', '14744'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # create a hw with a multi part question, and give it a randomized name # ID: 12252@5 is multi part self.teacher.login() self.teacher.find( By.XPATH, '//div[@data-appearance="intro_sociology"]' + '//a[not(contains(@href,"/cc-dashboard"))]' ).click() assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'problems': {'1.1': ['12024@10'], }, 'status': 'publish', } ) self.teacher.logout() # assignemnt name put here for manual testing # assignment_name = 'hw w/ video and multi part question' # login as student and go to same class self.student.login() self.teacher.find( By.XPATH, '//div[@data-appearance="intro_sociology"]' + '//a[not(contains(@href,"/cc-dashboard"))]' ).click() self.student.page.wait_for_page_load() # go to assignment (find my assignemnt_name) self.student.find( By.XPATH, '//a[contains(@class,"homework workable")]' + '//span[text()="' + assignment_name + '"]' ).click() # go through all questions breadcrumbs = self.teacher.find_all( By.XPATH, '//span[contains(@class,"openstax-breadcrumb")' + ' and not(contains(@class,"intro"))' + ' and not(contains(@class,"personalized"))' ' and not(contains(@class,"end"))]') total_questions = 0 found_multipart = False i = 0 while i < len(breadcrumbs): breadcrumbs[i].click() try: self.student.find( By.XPATH, '//span[text()="Multi-part question"]') found_multipart = True questions = self.teacher.find_all( By.XPATH, '//div[contains(@class,"openstax-question")]') total_questions += len(questions) i += len(questions) except NoSuchElementException: i += 1 questions = self.teacher.find_all( By.XPATH, '//div[contains(@class,"openstax-question")]') total_questions += len(questions) # check that everything worked out assert(found_multipart), 'no multipart question found' assert(total_questions == len(breadcrumbs)), \ 'breadcrumbs and questions not equal' self.ps.test_updates['passed'] = True
class TestRecruitingTeachers(unittest.TestCase): """CC1.01 - Recruiting Teachers.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.CONDENSED_WIDTH = 1105 def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C7751 - 001 - Admin | Recruitment and promo website is available @pytest.mark.skipif(str(7751) not in TESTS, reason='Excluded') def test_admin_recruitment_and_promo_website_is_available_7751(self): """Recruitment and promo website is available. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Expected Result: Recruitment website loads and renders """ self.ps.test_updates['name'] = 'cc1.01.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.001', '7751' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.ps.test_updates['passed'] = True # Case C7752 - 002 - Teacher | Information about Concept Coach and the # pilot are available on the demo site @pytest.mark.skipif(str(7752) not in TESTS, reason='Excluded') def test_teacher_information_about_cc_is_available_on_demo_site_7752(self): """Information about CC and pilot are available on the demo site. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Expected Result: Page loads several sections describing Concept Coach """ self.ps.test_updates['name'] = 'cc1.01.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.002', '7752' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'who-we-are') self.ps.test_updates['passed'] = True # Case C7753 - 003 - Teacher | Can interact with a Concept Coach wire frame # for each subject @pytest.mark.skipif(str(7753) not in TESTS, reason='Excluded') def test_teacher_can_interact_with_a_cc_wire_frame_for_subjects_7753(self): """Can interact with a Concept Coach wire frame for each subject. Steps: Go to the recruitment website ( http://cc.openstax.org/) Hover over "demos" in the header Click "Interactice Demo" CLick on a Concept Coach book title Expected Result: A new tab or window opens rendering the demo content for the selected book """ self.ps.test_updates['name'] = 'cc1.01.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.003', '7753' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() assert('http://cc.openstax.org/assets/demos/cc-mockup' in self.teacher.current_url()), \ 'not at demo book' self.ps.test_updates['passed'] = True # # NOT DONE # Case C7754 - 004 - Teacher | View a Concept Coach demo video @pytest.mark.skipif(str(7754) not in TESTS, reason='Excluded') def test_teacher_view_a_concept_coach_demo_video_7754(self): """View a Concept Coach demo video. Steps: Open recruitment website ( http://cc.openstax.org/ ) Hover over "demos" in the header Click "Interactive Demo" Click on a Concept Coach book title Scroll down until an embedded video pane is displayed Click on the right-pointing arrow to play the video Expected Result: The video loads and plays """ self.ps.test_updates['name'] = 'cc1.01.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.004', '7754' ] self.ps.test_updates['passed'] = False raise NotImplementedError(inspect.currentframe().f_code.co_name) # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup-physics")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() self.teacher.sleep(2) # self.teacher.find( # By.XPATH, '//div[@id="player"]' # ).click() title = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Inelastic Collisions")]') ) ) # self.teacher.wait.until( # expect.presence_of_element_located( # (By.ID, 'player') # ) # ) actions = ActionChains(self.teacher.driver) actions.move_to_element(title) actions.move_by_offset(0, 300) actions.click() actions.perform() self.teacher.sleep(2) self.teacher.find( By.XPATH, '//div[contains(@class,"playing-mode")]' ) # actions.perform() self.teacher.find( By.XPATH, '//div[@id="player"]/div[contains(@class,"paused-mode")]' ) self.ps.test_updates['passed'] = True # Case C7755 - 005 - Teacher | Sample exercise questions are seen in # the wire frames @pytest.mark.skipif(str(7755) not in TESTS, reason='Excluded') def test_teacher_sample_exercise_questions_are_in_wire_frames_7755(self): """Sample exercise questions are seen in the wire frames. Steps: Open recruitment website ( http://cc.openstax.org/ ) Hover over "demos" in the header Click "Interactive Demo" Click on a Concept Coach book title Scroll down until the 'CONCEPT COACH' pane is displayed Expected Result: Demo exercises are rendered and can be answered along with showing feedback """ self.ps.test_updates['name'] = 'cc1.01.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.005', '7755' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup-physics")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//span[contains(text(),"JUMP TO CONCEPT COACH")]' ).click() self.teacher.find( By.XPATH, '//div[contains(@data-label,"q1-multiple-choice")]') self.teacher.sleep(2) answer = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@data-label,"choice-1b-text")]') ) ) actions = ActionChains(self.teacher.driver) actions.move_to_element(answer) actions.click() actions.perform() self.teacher.find( By.XPATH, "//div[@data-label='State2']" ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, "//div[@data-label='q1-answer-b']//div[@data-label='next']") ) ) self.ps.test_updates['passed'] = True # Case C7756 - 006 - Teacher | Access Concept Coach help and support before # the teacher's course is created @pytest.mark.skipif(str(7756) not in TESTS, reason='Excluded') def test_teacher_access_cc_support_before_course_is_created_7756(self): """Access CC help and support before the teacher's course is created. Steps: Open the recruitment website ( http://cc.openstax.org/ ) Click "Support" in the header Expected Result: A new tab opens with the CC Help Center """ self.ps.test_updates['name'] = 'cc1.01.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.006', '7756' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() if self.teacher.driver.get_window_size()['width'] < \ self.CONDENSED_WIDTH: self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//label[@for="mobileNavToggle" and ' + 'contains(@class,"fixed")]') ) ).click() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//a[contains(text(),"support")]' ).click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) self.ps.test_updates['passed'] = True # Case C7757 - 007 - Teacher | Teacher registers to use a CC course @pytest.mark.skipif(str(7757) not in TESTS, reason='Excluded') def test_teacher_teacher_registers_to_use_a_cc_course_7757(self): """Teacher registers to use a Concept Coach course. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Expected Result: Web form renders """ self.ps.test_updates['name'] = 'cc1.01.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.007', '7757' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.ps.test_updates['passed'] = True # Case C7758 - 008 - Teacher | Teacher uses a web form to sign up for CC @pytest.mark.skipif(str(7758) not in TESTS, reason='Excluded') def test_teacher_teacher_uses_a_web_form_to_sign_up_for_cc_7758(self): """Teacher uses a web form to sign up for Concept Coach. Steps: Teacher fills out the form Expected Result: Preconditions pass. User is presented with a confirmation message """ self.ps.test_updates['name'] = 'cc1.01.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.008', '7758' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7759 - 009 - Teacher | Receive error messages if required fields on # the sign up form are blank @pytest.mark.skipif(str(7759) not in TESTS, reason='Excluded') def test_teacher_receive_error_messages_if_required_fields_are_7759(self): """Receive error messages if required fields on the sign up form are blank. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Click on the 'sign up now' button Submit the form without changing any of the text fields Expected Result: Receive 'Please fill out this field' error messages in red for each blank required field """ self.ps.test_updates['name'] = 'cc1.01.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.009', '7759' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) submit = self.teacher.find( By.XPATH, '//input[@type="submit"]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', submit) self.teacher.sleep(0.5) submit.click() assert('/sign-up' in self.teacher.current_url()), \ 'moved from sign up when submitting with blank required fields' self.teacher.find( By.XPATH, '//div[contains(text(),"Please fill out this field.")]' ) self.ps.test_updates['passed'] = True # Case C7760 - 010 - Teacher | Submit a form to supply required course info @pytest.mark.skipif(str(7760) not in TESTS, reason='Excluded') def test_teacher_submit_a_form_to_supply_required_course_info_7760(self): """Submit a form to supply required course information. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Web form submits Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.010', '7760' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') # choose a book! menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7761 - 011 - Teacher | Submit co-instructors, classes, names, etc. @pytest.mark.skipif(str(7761) not in TESTS, reason='Excluded') def test_teacher_submit_coinstructors_classes_names_etc_7761(self): """Submit co-instructors, classes, names and other data. Steps: Go to the recruitment and promo website ( http://cc.openstax.org/ ) Click on the 'sign up now' button Click on the 'Co-Teaching class with a colleague?' circle button Enter the co-instructor's (or co-instructors') information Enter text into other fields concerning classe, names, etc. Expected Result: Input box exists for instructor information, class details and other data. The user is able to input information. """ self.ps.test_updates['name'] = 'cc1.01.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.011', '7761' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) option = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="slide-checkbox"]/label') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', option) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) option.click() textarea = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@id="coteachcontact"]/textarea') ) ) textarea.send_keys('co teacher info') self.ps.test_updates['passed'] = True # Case C7762 - 012 - Teacher | Select the textbook to use in the course @pytest.mark.skipif(str(7762) not in TESTS, reason='Excluded') def test_teacher_select_the_textbook_to_use_in_the_course_7762(self): """Select the textbook to use in the course. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Select the course textbook from the 'Book' dropdown options Expected Result: Able to select any Concept Coach textbook """ self.ps.test_updates['name'] = 'cc1.01.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.012', '7762' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) menu = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) book = self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ) title = book.text book.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//span[contains(@title,"' + title + '") and ' + 'contains(@class,"select2-selection__rendered")]' ) self.ps.test_updates['passed'] = True # Case C7763 - 013 - Teacher | Indicate whether the teacher was recruited # by OpenStax @pytest.mark.skipif(str(7763) not in TESTS, reason='Excluded') def test_teacher_indicate_whether_the_teacher_was_recruited_by_7763(self): """Indicate if the teacher was or was not recruited by OpenStax. Steps: Go to the recruitment and promo website ( http://cc.openstax.org/ ) Click on the 'sign up now' button ( http://cc.openstax.org/sign-up ) Enter recruitment information into the 'Anything else we need to know?' text box Expected Result: Able to input recruitment information """ self.ps.test_updates['name'] = 'cc1.01.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.013', '7763' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) textarea = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//textarea[@placeholder="Feedback"]') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', textarea) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) textarea.send_keys('recuitment info') self.ps.test_updates['passed'] = True # Case C7764 - 014 - Teacher | Presented a thank you page after registering # to use Concept Coach @pytest.mark.skipif(str(7764) not in TESTS, reason='Excluded') def test_teacher_presented_a_thank_you_page_after_registering_7764(self): """Presented a thank you page after registering to use Concept Coach. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.014', '7764' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7765 - 015 - Teacher | Sign up for an OpenStax Accounts username @pytest.mark.skipif(str(7765) not in TESTS, reason='Excluded') def test_teacher_sign_up_for_an_openstax_accounts_username_7765(self): """Sign up for an OpenStax Accounts username. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.015', '7765' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True # Case C7770 - 020 - Admin | Add co-instructors to a course @pytest.mark.skipif(str(7770) not in TESTS, reason='Excluded') def test_admin_add_coinstructors_to_a_course_7770(self): """Add co-instructors to a course. Steps: Log into Tutor as an admin From the user menu, select 'Admin' From the 'Course Organization' menu, select 'Courses' In the Courses table, find the correct course and click the 'Edit' button on the right side of that row Click on the 'Teachers' tab In the search box, enter the teacher's name or username Select the teacher in the list below the search bar or hit the down arrow followed by the enter/return key Expected Result: Co-instructor is linked to the affected course """ self.ps.test_updates['name'] = 'cc1.01.020' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.020', '7770' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login( username=os.getenv('ADMIN_USER'), password=os.getenv('ADMIN_PASSWORD')) self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a[@role="menuitem" and contains(text(),"Admin")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Course Organization') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Courses') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Edit') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Teachers') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.ID, 'course_teacher') ) ).send_keys('teacher0') element = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//ul[contains(@class,"ui-autocomplete")]' + '//li[contains(text(),"(teacher0")]') ) ) teacher_name = element.text.split(' (')[0] element.click() # check that the teacher has been added to the table print(teacher_name) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//td[contains(text(),"' + teacher_name + '")]') ) ) self.ps.test_updates['passed'] = True # Case C7771 - 021 - Teacher | Login with an Existing OpenStax Account @pytest.mark.skipif(str(7771) not in TESTS, reason='Excluded') def test_teacher_login_with_an_existing_openstax_account_7771(self): """Log in with an Existing OpenStax Accounts username. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Click on faculty login You are redirected to the accounts page. Enter a username and password click on Login. Expected Result: Login should be successful. It should take you to the teacher course picker/dashboard page. """ self.ps.test_updates['name'] = 'cc1.01.021' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.021', '7771' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]' ) # check if the menu is collapsed and, if yes, open it if('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Login') ) ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'auth_key' ).send_keys(self.teacher.username) self.teacher.find( By.ID, 'password' ).send_keys(self.teacher.password) # click on the sign in button self.teacher.find( By.XPATH, '//button[text()="Sign in"]' ).click() self.teacher.page.wait_for_page_load() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C7772 - 022 - Teacher | Access the Concept Coach course @pytest.mark.skipif(str(7772) not in TESTS, reason='Excluded') def test_teacher_access_the_cc_course_7772(self): """Access the Concept Coach course. Steps: Once you login you will be taken to a course picker page. Click on the course you want to check the dashboard Expected Result: At Concept Coach teacher dashboard """ self.ps.test_updates['name'] = 'cc1.01.022' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.022', '7772' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() assert('cc-dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C7773 - 023 - Admin | Distribute access codes for the course @pytest.mark.skipif(str(7773) not in TESTS, reason='Excluded') def test_admin_distribute_access_codes_for_the_course_7773(self): """Distribute access codes for the teacher's course. Steps: CC approves a faculty. Login as admin Click on user menu Click on Admin Click on Salesforce tab Click on import [Do not check the box] This will automatically create a course for the teacher created. Email is sent to the email id used when signing up with the unique course URL. Expected Result: Instructors are emailed the unique course url to the address provided when they signed up. """ self.ps.test_updates['name'] = 'cc1.01.023' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.023', '7773' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, # pasta_user=self.ps, # capabilities=self.desired_capabilities ) admin.login() admin.open_user_menu() admin.find(By.LINK_TEXT, 'Admin').click() admin.page.wait_for_page_load() admin.find(By.LINK_TEXT, 'Salesforce').click() admin.page.wait_for_page_load() admin.find( By.XPATH, '//input[@vale="Import Courses"]' ).click() self.ps.test_updates['passed'] = True # Case C7774 - 024 - Teacher | Access CC help and support during the course @pytest.mark.skipif(str(7774) not in TESTS, reason='Excluded') def test_teacher_acccess_cc_help_and_support_during_the_course_7774(self): """Access Concept Coach help and support during the course. Steps: Login as teacher Click on the course name On dashboard click on the name of the teacher It drops down and displays several options. Click on Get Help Expected Result: It should open a new tab which shows the openstax.force.com """ self.ps.test_updates['name'] = 'cc1.01.024' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.024', '7774' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Get Help" ).click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ).click() self.ps.test_updates['passed'] = True # Case C7775 - 025 - Teacher | Access CC help and support after course ends @pytest.mark.skipif(str(7775) not in TESTS, reason='Excluded') def test_teacher_access_cc_help_and_support_after_course_ends_7775(self): """Access Concept Coach help and support after the end of the course. Steps: Login as teacher Click on the course name On dashboard click on the name of the teacher It drops down and displays several options. Click on Get Help Expected Result: It should open a new tab which shows the CC help center """ self.ps.test_updates['name'] = 'cc1.01.025' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.025', '7775' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Get Help" ).click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ).click() self.ps.test_updates['passed'] = True
class TestTrainingAndSupportingTeachersAndStudents(unittest.TestCase): """CC1.14 - Training and Supporting Teachers and Students.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.student = Student(use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities) def tearDown(self): """Test destructor.""" self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) self.student = None try: self.teacher.delete() except: pass # Case C7704 - 001 - System | Concept Coach Zendesk is web-accessible @pytest.mark.skipif(str(7704) not in TESTS, reason='Excluded') def test_system_concept_coach_zendesk_is_web_accessible_7704(self): """Concept Coach Zendesk is web-accesible. Steps: Log in to Tutor as teacher If more then one course, click on a concept coach course In user menu in top right of header, click 'Get Help' Expected Result: In a new window or tab, zendesk help is opened """ self.ps.test_updates['name'] = 'cc1.14.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.001', '7704'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7705 - 002 - Teacher | Can access user support @pytest.mark.skipif(str(7705) not in TESTS, reason='Excluded') def test_teacher_can_access_user_support_7705(self): """Can access user support. Steps: Click on the user menu Click on the Get Help option Expected Result: In a new tab or window Zendesk is opened """ self.ps.test_updates['name'] = 'cc1.14.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.002', '7705'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7706 - 003 - Student | Can access user support @pytest.mark.skipif(str(7706) not in TESTS, reason='Excluded') def test_student_can_access_user_support_7706(self): """Can access user support. Steps: Click on the user menu Click on the Get Help option Expected Result: In a new tab or window zendesk is opened """ self.ps.test_updates['name'] = 'cc1.14.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.003', '7706'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.open_user_menu() self.student.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.student.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7707 - 004 - Non-user | Submit support questions @pytest.mark.skipif(str(7707) not in TESTS, reason='Excluded') def test_nonuser_submit_support_questions_7707(self): """Submit support questions. Steps: Go to the Concept Coach landing page click support in the header enter text into the search box click contact us fillout form click Submit Expected Result: 'Message sent' displayed in help box """ self.ps.test_updates['name'] = 'cc1.14.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.004', '7707'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.sleep(1) # number hardcoded because condenses at different size than tutor if self.teacher.driver.get_window_size()['width'] < 1105: element = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//label[@for="mobileNavToggle"]'))) actions = ActionChains(self.teacher.driver) # use action chain because it is clicking to the wrong elemnt actions.move_to_element(element) actions.click() actions.perform() support = self.teacher.find(By.LINK_TEXT, 'support') actions = ActionChains(self.teacher.driver) actions.move_to_element(support) actions.click() actions.perform() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'searchAskInput').send_keys('fake_question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.find(By.LINK_TEXT, 'Contact Us').click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]').send_keys('qa') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]').send_keys( 'test') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:email")]').send_keys( '*****@*****.**') self.teacher.find(By.XPATH, '//div[@class="submit-container"]//input').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[contains(text(),"Thank you")]'))) self.ps.test_updates['passed'] = True # Case C7708 - 005 - Teacher | Submit support questions @pytest.mark.skipif(str(7708) not in TESTS, reason='Excluded') def test_teacher_submit_support_questions_7708(self): """Submit support questions. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If user has more than one course, click on a Concept Coach course Click the user menu in the right corner of the header Click "Get Help" Click "Submit a request" Fill out all the necessary text fields Click "Submit" Expected Result: The user submits support questions """ self.ps.test_updates['name'] = 'cc1.14.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.005', '7708'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.teacher.current_url()), 'not at help center' self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'searchAskInput').send_keys('fake_question') self.teacher.find(By.ID, 'searchAskButton').click() self.teacher.find(By.LINK_TEXT, 'Contact Us').click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]').send_keys('qa') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]').send_keys( 'test') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:email")]').send_keys( '*****@*****.**') self.teacher.find(By.XPATH, '//div[@class="submit-container"]//input').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[contains(text(),"Thank you")]'))) self.ps.test_updates['passed'] = True # Case C7709 - 006 - Student | Submit support questions @pytest.mark.skipif(str(7709) not in TESTS, reason='Excluded') def test_student_submit_support_questions_7709(self): """Submit support questions. Steps: Go to Tutor Click on the 'Login' button Enter the student user account in the username and password text boxes Click on the 'Sign in' button Click the user menu in the right corner of the header Click "Get Help" Click "Submit a request" Fill out all the necessary text fields Click "Submit" Expected Result: The user submits support questions """ self.ps.test_updates['name'] = 'cc1.14.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.006', '7709'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.open_user_menu() self.student.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.student.current_url()), 'not at help center' self.student.page.wait_for_page_load() self.student.find(By.ID, 'searchAskInput').send_keys('fake_question') self.student.find(By.ID, 'searchAskButton').click() self.student.find(By.LINK_TEXT, 'Contact Us').click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]').send_keys('qa') self.student.find( By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]').send_keys( 'test') self.student.find( By.XPATH, '//input[contains(@id,"contactUsForm:email")]').send_keys( '*****@*****.**') self.student.find(By.XPATH, '//div[@class="submit-container"]//input').click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[contains(text(),"Thank you")]'))) self.ps.test_updates['passed'] = True # Case C7710 - 007 - Teacher | View instructions on how to use CC @pytest.mark.skipif(str(7710) not in TESTS, reason='Excluded') def test_teacher_view_instructions_on_how_to_use_cc_7710(self): """View instructions on how to use Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If user has more than one course, click on a Concept Coach course Click the user menu in the right corner of the header Click "Get Help" Click "Getting Started Guide" * Click on the pdf link OR * Click "Getting Started" from the user menu Expected Result: The user is presented with a guide to use CC """ self.ps.test_updates['name'] = 'cc1.14.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.007', '7710'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Getting Started').click() self.teacher.find(By.XPATH, '//h3[contains(text(),"Getting Started")]').click() assert ('help' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7711 - 008 - Student | View instructions on how to use CC @pytest.mark.skipif(str(7711) not in TESTS, reason='Excluded') def test_student_view_instructions_on_how_to_use_cc_7711(self): """View instructions on how to use Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the student user account in the username and password text boxes Click on the 'Sign in' button Click the user menu in the right corner of the header Click "Get Help" Scroll down to the questions under "Students" Expected Result: The user is presented with instructions on how to use CC """ self.ps.test_updates['name'] = 'cc1.14.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.008', '7711'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.open_user_menu() self.student.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.student.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7712 - 009 - Teacher | View instructions on how to assign CC @pytest.mark.skipif(str(7712) not in TESTS, reason='Excluded') def test_teacher_view_instructions_on_how_to_assign_cc_7712(self): """View instructions on how to use Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If user has more than one course, click on a Concept Coach course Click the user menu in the right corner of the header Click "Get Help" Expected Result: Taken to Zendesk in a new window or tab Assorted help is displayed """ self.ps.test_updates['name'] = 'cc1.14.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.009', '7712'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click() self.teacher.open_user_menu() self.teacher.find(By.LINK_TEXT, 'Get Help').click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]') assert ('support' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7713 - 010 - Student | Get help during account registration @pytest.mark.skipif(str(7713) not in TESTS, reason='Excluded') def test_student_get_help_during_account_registration_7713(self): """View instructions on how to use Concept Coach. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.14.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.010', '7713'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C7714 - 011 - Teacher | View instructions for Legacy users # transitioning to Concept Coach @pytest.mark.skipif(str(7714) not in TESTS, reason='Excluded') def test_teacher_view_instructions_for_legacy_users_transition_7714(self): """View instructions for Legacy users transitioning to Concept Coach. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.14.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.14', 'cc1.14.011', '7714'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
class TestAdminAndTeacherCourseSetup(unittest.TestCase): """CC1.10 - Admin and Teacher Course Setup.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.admin.driver = None self.teacher.delete() except: pass # Case C7715 - 001 - Admin | Send course setup data from Sales Force @pytest.mark.skipif(str(7715) not in TESTS, reason='Excluded') def test_admin_send_course_setup_data_from_sales_force_7715(self): """Send course setup data from Sales Force. Steps: Go to tutor-staging.openstax.org and login as admin Click on the user menu Select the Admin option Click on Salesforce on the header Expected Result: """ self.ps.test_updates['name'] = 'cc1.10.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.001', '7715' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Admin' ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Salesforce') ) ).click() assert('salesforce' in self.admin.current_url()), 'not at salesforce' self.ps.test_updates['passed'] = True # Case C7716 - 002 - System | Course registration codes are emailed to the # teacher once the course is set up @pytest.mark.skipif(str(7716) not in TESTS, reason='Excluded') def test_system_registration_codes_are_emailed_to_teacher_7716(self): """Registration codes are emailed to teacher once the course is set up. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.10.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.002', '7716' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C7717 - 003 - Teacher | Use a teacher registration code to access # their course @pytest.mark.skipif(str(7717) not in TESTS, reason='Excluded') def test_teacher_use_teacher_registration_code_to_access_course_7717(self): """Use a teacher registration code to access their course. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.10.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.003', '7717' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C7718 - 004 - Teacher | Create course periods @pytest.mark.skipif(str(7718) not in TESTS, reason='Excluded') def test_teacher_create_course_periods_7718(self): """Create course periods. Steps: go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click "+ Add section" Enter a section name into the section Name text box Expected Result: New course section created """ self.ps.test_updates['name'] = 'cc1.10.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.004', '7718' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"add-period")]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys('test_period') self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Add"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="test_period"]') ) ) self.ps.test_updates['passed'] = True # Case C7719 - 005 - Teacher | View student enrollment code for # course period @pytest.mark.skipif(str(7719) not in TESTS, reason='Excluded') def test_teacher_view_student_enrollment_code_for_course_period_7719(self): """View the student enrollment code for a course period. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on tab for selected section Click 'Get Student Enrollment Code' Expected Result: Student Enrollment code displayed along with instruction teacher can send to students on how to use enrollment code """ self.ps.test_updates['name'] = 'cc1.10.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.005', '7719' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"show-enrollment-code")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="enrollment-code"]') ) ) self.ps.test_updates['passed'] = True # Case C7720 - 006 - Teacher | Rename a course period @pytest.mark.skipif(str(7720) not in TESTS, reason='Excluded') def test_teacher_rename_a_course_period_7720(self): """Rename a course period. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on tab for selected section Click 'Rename section' Enter new section name into the section Name text box Click on the 'Rename' button Expected Result: Section is renamed """ self.ps.test_updates['name'] = 'cc1.10.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.006', '7720' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() period_name = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab"]') ) ).text self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class,"rename-period")]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys('_EDIT') self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Rename"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '_EDIT"]') ) ) # then set it back to what it was before self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class,"rename-period")]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys(Keys.BACK_SPACE * 5) self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Rename"]' ).click() self.ps.test_updates['passed'] = True # Case C7721 - 007 - Teacher | Archive an empty period @pytest.mark.skipif(str(7721) not in TESTS, reason='Excluded') def test_teacher_remove_an_empty_period_7721(self): """Remove an empty period. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on tab for selected empty section Click 'Archive section' Click on the 'Archive' button Expected Result: Section is archived """ self.ps.test_updates['name'] = 'cc1.10.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.007', '7721' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions section_name = 'test_' + str(randint(0, 1000)) self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # create an empty section self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"add-period")]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys(section_name) self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Add"]' ).click() # archive the section just created self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + section_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.sleep(2) archived = self.teacher.driver.find_elements( By.XPATH, '//li//a[@role="tab" and text()="' + section_name + '"]') assert(len(archived) == 0), ' not archived' self.ps.test_updates['passed'] = True # Case C7722 - 008 - Teacher | Archive a non-empty period @pytest.mark.skipif(str(7722) not in TESTS, reason='Excluded') def test_teacher_archive_a_nonempty_periods_7722(self): """Error message displayed if attempting to remove a non-empty period. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on tab for selected non-empty section Click 'Archive section' Click Archive Expected Result: Section is archived """ self.ps.test_updates['name'] = 'cc1.10.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.008', '7722' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # name of period to archive (first tab) period_name = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab"]') ) ).text # archive the section self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.sleep(2) archived = self.teacher.driver.find_elements( By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '"]') assert(len(archived) == 0), ' not archived' # add the archived period back self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"view-archived-periods")]//button') ) ).click() periods = self.teacher.driver.find_elements( By.XPATH, '//div[@class="modal-content"]//tbody//tr' ) for period in periods: try: period.find_element( By.XPATH, ".//td[text()='" + period_name + "']") period.find_element( By.XPATH, ".//td//span[contains(@class,'restore-period')]//button" ).click() break except NoSuchElementException: if period == periods[-1]: raise Exception self.teacher.sleep(2) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '"]') ) ) self.ps.test_updates['passed'] = True # Case C58354 - 009 - Teacher | Unarchive a section @pytest.mark.skipif(str(58354) not in TESTS, reason='Excluded') def test_teacher_unarchive_a_section_58354(self): """Unarchive a section. Steps: go to tutor-qa.openstax.org log in as a teacher click on a Concept Coach book click on the user menu select course roster Click "View Archived Section" Click "Unarchive" for the desired section Expected Result: section is unarchived """ self.ps.test_updates['name'] = 'cc1.10.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.009', '58354' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # name of period to archive (first tab) period_name = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab"]') ) ).text # archive the section self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.sleep(2) archived = self.teacher.driver.find_elements( By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '"]') assert(len(archived) == 0), ' not archived' # add the archived period back self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"view-archived-periods")]//button') ) ).click() periods = self.teacher.driver.find_elements( By.XPATH, '//div[@class="modal-content"]//tbody//tr' ) for period in periods: try: period.find_element( By.XPATH, ".//td[text()='" + period_name + "']") period.find_element( By.XPATH, ".//td//span[contains(@class,'restore-period')]//button" ).click() break except NoSuchElementException: if period == periods[-1]: raise Exception self.teacher.sleep(2) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + period_name + '"]') ) ) self.ps.test_updates['passed'] = True # Case C7723 - 010 - Teacher | Rename the course @pytest.mark.skipif(str(7723) not in TESTS, reason='Excluded') def test_teacher_rename_the_course_7723(self): """Rename the course. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click 'Rename Course' Enter a new Course name into the Course Name text box Click on the 'Rename' button Expected Result: Course is renamed. """ self.ps.test_updates['name'] = 'cc1.10.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.010', '7723' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # rename section self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="-rename-course-link"]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys("_EDIT") self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Rename"]' ).click() # check that the name was changed self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="course-settings-title"]' + '//span[contains(text(),"_EDIT")]') ) ) # change it back self.teacher.sleep(1) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="-rename-course-link"]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys(Keys.BACK_SPACE * 5) self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Rename"]' ).click() self.ps.test_updates['passed'] = True # Case C7724 - 011 - Teacher | Remove other teachers from the course @pytest.mark.skipif(str(7724) not in TESTS, reason='Excluded') def test_teacher_remove_other_teachers_from_the_course_7724(self): """Remove other teachers from the course. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on 'Remove' on the same row as selected teacher Click on the 'Remove' button Expected Result: Instructor is removed from the course """ self.ps.test_updates['name'] = 'cc1.10.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.011', '7724' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.driver.get( 'https://tutor-qa.openstax.org/admin/courses/8/edit') self.admin.page.wait_for_page_load() teacher_name = 'Trent' self.admin.driver.find_element( By.XPATH, '//a[contains(text(),"Teachers")]').click() self.admin.driver.find_element( By.ID, 'course_teacher').send_keys(teacher_name) self.admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name) ) ).click() self.admin.sleep(1) self.admin.driver.find_element( By.LINK_TEXT, 'Main Dashboard').click() self.admin.page.wait_for_page_load() self.admin.logout() # redo set-up, but make sure to go to course 8 self.teacher.login() self.teacher.driver.get('https://tutor-qa.openstax.org/courses/8') self.teacher.open_user_menu() self.teacher.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster') ) ).click() self.teacher.page.wait_for_page_load() # delete teacher teachers_list = self.teacher.driver.find_elements( By.XPATH, '//div[@class="teachers-table"]//tbody//tr') for x in teachers_list: temp_first = x.find_element( By.XPATH, './td[1]' ).text if temp_first == teacher_name: x.find_element( By.XPATH, './/td//span[contains(text(),"Remove")]' ).click() self.teacher.sleep(1) self.teacher.driver.find_element( By.XPATH, '//div[@class="popover-content"]//button' ).click() break if x == teachers_list[-1]: print('added teacher was not found, and not deleted') raise Exception deleted_teacher = self.teacher.driver.find_elements( By.XPATH, '//td[contains(text(),"%s")]' % teacher_name) assert(len(deleted_teacher) == 0), 'teacher not deleted' self.ps.test_updates['passed'] = True # come back to this because adding teacher through admin first # Case C7725 - 012 - Teacher | Remove themself from the course @pytest.mark.skipif(str(7725) not in TESTS, reason='Excluded') def test_teacher_remove_themself_from_the_course_7725(self): """Remove themself from the course. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on 'Remove' on the same row as themselves Click on the 'Remove' button Expected Result: Teacher is removed from course and taken back to dashboard """ self.ps.test_updates['name'] = 'cc1.10.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.012', '7725' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.driver.get( 'https://tutor-qa.openstax.org/admin/courses/8/edit') self.admin.page.wait_for_page_load() teacher_name = 'Trent' self.admin.driver.find_element( By.XPATH, '//a[contains(text(),"Teachers")]').click() self.admin.driver.find_element( By.ID, 'course_teacher').send_keys(teacher_name) self.admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name) ) ).click() self.admin.sleep(1) self.admin.driver.find_element( By.LINK_TEXT, 'Main Dashboard').click() self.admin.page.wait_for_page_load() self.admin.logout() # redo set-up, but make sure to go to course 8 # login as the teacher just added to the course teacher2 = Teacher( username='******', password=os.getenv('TEACHER_PASSWORD'), existing_driver=self.teacher.driver ) teacher2.login() teacher2.driver.get('https://tutor-qa.openstax.org/courses/8') teacher2.open_user_menu() teacher2.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster') ) ).click() teacher2.page.wait_for_page_load() # delete teacher teachers_list = teacher2.driver.find_elements( By.XPATH, '//div[@class="teachers-table"]//tbody//tr') for x in teachers_list: temp_first = x.find_element( By.XPATH, './td[1]' ).text if temp_first == teacher_name: x.find_element( By.XPATH, './/td//span[contains(text(),"Remove")]' ).click() teacher2.sleep(1) teacher2.driver.find_element( By.XPATH, '//div[@class="popover-content"]//button' ).click() break if x == teachers_list[-1]: print('added teacher was not found, and not deleted') raise Exception # after removing self from course taken to dashboard # or course if only 1 other course assert('/courses/8' not in teacher2.current_url()), \ 'teacher not deleted' teacher2.delete() self.ps.test_updates['passed'] = True # Case C7726 - 013 - Teacher | Transfer a student to another period @pytest.mark.skipif(str(7726) not in TESTS, reason='Excluded') def test_teacher_transfer_a_student_to_another_period_7726(self): """Transfer a student to another period. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on tab for section selected student is currently enrolled in Click on 'Change Section' on the row of the selected student Click on section to move student to Expected Result: Student is moved to chosen section """ self.ps.test_updates['name'] = 'cc1.10.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.013', '7726' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # move student first_student = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="period"]//tbody/tr[1]') ) ) student_name = first_student.find_element( By.XPATH, './/td[1]').text first_student.find_element( By.XPATH, './/td[@class="actions"]/a[@aria-describedby="change-period"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="popover-content"]//li[1]') ) ).click() # check that student was moved self.teacher.sleep(2) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li[@tabindex="1"]//a[@role="tab"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="period"]//tbody/tr' + '//td[text()="' + student_name + '"]') ) ) self.ps.test_updates['passed'] = True # Case C7727 - 014 - Teacher | Remove a student from a course @pytest.mark.skipif(str(7727) not in TESTS, reason='Excluded') def test_teacher_remove_a_student_from_a_course_7727(self): """Remove a student from a course. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on tab for section selected student is currently enrolled in Click on 'Drop' on the row of the selected student Click on the 'Drop' button Expected Result: Student is dropped from the course """ self.ps.test_updates['name'] = 'cc1.10.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.014', '7727' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.page.wait_for_page_load() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # drop student first_student = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="period"]//tbody/tr[1]') ) ) student_name = first_student.find_element( By.XPATH, './/td[1]').text first_student.find_element( By.XPATH, './/td[@class="actions"]/a[@aria-describedby="drop-student"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@id="drop-student"]//button') ) ).click() # check that student was removed self.teacher.sleep(2) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"dropped-students")]//tbody/tr' + '//td[text()="' + student_name + '"]') ) ) self.ps.test_updates['passed'] = True # Case C7728 - 015 - Admin | Impersonate a teacher @pytest.mark.skipif(str(7728) not in TESTS, reason='Excluded') def test_admin_impersonate_a_teacher_7728(self): """Impersonate a teacher. Steps: Go to Tutor Click on the 'Login' button Enter the admin user account in the username and password text boxes Click on the 'Sign in' button Click on the user's name in the top right corner to open drop down menu Click on the 'Admin' option of the drop down menu Click on 'Users' on the bar across the top [optional] Enter a teacher name into the search here text box Click on the 'Search' button Click on the 'Sign in as' button next to chosen teacher Expected Result: Signs in as chosen chosen teacher. Goes to chosen teacher's initial screen after login If multiple courses list of textbooks If one course straight to dashboard """ self.ps.test_updates['name'] = 'cc1.10.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.015', '7728' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.open_user_menu() self.admin.driver.find_element( By.LINK_TEXT, 'Admin' ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Users') ) ).click() self.admin.page.wait_for_page_load() self.admin.driver.find_element(By.ID, 'query').send_keys('teacher01') self.admin.driver.find_element( By.XPATH, '//input[@value="Search"]').click() self.admin.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[contains(text(),"Sign in as")]') ) ).click() self.admin.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[contains(text(),"Charles Morris")]') ) ) self.ps.test_updates['passed'] = True # Case C7729 - 016 - Admin | Change a course ecosystem @pytest.mark.skipif(str(7729) not in TESTS, reason='Excluded') def test_admin_change_a_course_ecosystem_7729(self): """Change a course ecosystem. Steps: Go to Tutor Click on the 'Login' button Enter the admin user account in the username and password text boxes Click on the 'Sign in' button Click on the 'Admin' button from the user menu Open the drop down menu by clicking 'Course Organization' Click the 'Courses' option Click the 'Edit' link for the desired course Click on the 'Course content' tab Select a different option in the 'Ecosystem' drop down menu Click the 'Submit' button Expected Result: Course ecosystem change is put on a queue """ self.ps.test_updates['name'] = 'cc1.10.016' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.016', '7729' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Admin' ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Course Organization') ) ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Courses') ) ).click() self.admin.page.wait_for_page_load() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Edit') ) ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Course content') ) ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.ID, 'ecosystem_id') ) ).send_keys('1' + Keys.ENTER) # self.admin.wait.until( # expect.visibility_of_element_located( # (By.XPATH, '//select[@id="ecosystem_id"]//option[1]') # ) # ).click() self.admin.driver.find_element( By.XPATH, '//div[@id="content"]//input[@type="submit"]' ).click() self.admin.sleep(1) self.admin.driver.find_element( By.XPATH, '//div[contains(@class,"alert-info")]' ) self.ps.test_updates['passed'] = True # Case C7730 - 017 - Admin | Change multiple course ecosystems in bulk @pytest.mark.skipif(str(7730) not in TESTS, reason='Excluded') def test_admin_change_multiple_course_ecosystems_in_bulk_7730(self): """Change multiple course ecosystems in bulk. Steps: Go to Tutor Click on the 'Login' button Enter the admin user account in the username and password text boxes Click on the 'Sign in' button Click on the 'Admin' button from the user menu Open the drop down menu by clicking 'Course Organization' Click the 'Courses' option Check the checkboxes next to selected courses Select an option in the 'Select an ecosystem' drop down menu Click the 'Set Ecosystem' button Expected Result: Course ecosystem change is put on a queue """ self.ps.test_updates['name'] = 'cc1.10.017' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.017', '7730' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Admin' ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Course Organization') ) ).click() self.admin.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Courses') ) ).click() self.admin.page.wait_for_page_load() self.admin.wait.until( expect.visibility_of_element_located( (By.ID, 'courses_select_all') ) ).click() # click the checkmarks for two courses courses = self.admin.driver.find_elements( By.XPATH, '//input[@class="course_id_select"]') course_1 = courses[0] self.admin.driver.execute_script( 'return arguments[0].scrollIntoView();', course_1) self.admin.driver.execute_script('window.scrollBy(0, -120);') course_1.click() self.admin.sleep(0.5) course_2 = courses[1] self.admin.driver.execute_script( 'return arguments[0].scrollIntoView();', course_2) self.admin.driver.execute_script('window.scrollBy(0, -120);') course_2.click() self.admin.sleep(0.5) # scroll to bottom and set bulk ecosystems self.admin.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.admin.wait.until( expect.visibility_of_element_located( (By.ID, 'ecosystem_id') ) ).send_keys('1' + Keys.ENTER) self.admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"alert-info")]') ) ) self.ps.test_updates['passed'] = True # Case C7731 - 018 - Teacher | Receive a notice when students register @pytest.mark.skipif(str(7731) not in TESTS, reason='Excluded') def test_teacher_receive_a_notice_when_students_register_7731(self): """Receive a notice when students register. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.10.018' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.018', '7731' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
class TestTrainingAndSupportingTeachersAndStudents(unittest.TestCase): """CC1.14 - Training and Supporting Teachers and Students.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) self.student = None try: self.teacher.delete() except: pass # Case C7704 - 001 - System | Concept Coach Zendesk is web-accessible @pytest.mark.skipif(str(7704) not in TESTS, reason='Excluded') def test_system_concept_coach_zendesk_is_web_accessible_7704(self): """Concept Coach Zendesk is web-accesible. Steps: Log in to Tutor as teacher If more then one course, click on a concept coach course In user menu in top right of header, click 'Get Help' Expected Result: In a new window or tab, zendesk help is opened """ self.ps.test_updates['name'] = 'cc1.14.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.001', '7704' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7705 - 002 - Teacher | Can access user support @pytest.mark.skipif(str(7705) not in TESTS, reason='Excluded') def test_teacher_can_access_user_support_7705(self): """Can access user support. Steps: Click on the user menu Click on the Get Help option Expected Result: In a new tab or window Zendesk is opened """ self.ps.test_updates['name'] = 'cc1.14.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.002', '7705' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7706 - 003 - Student | Can access user support @pytest.mark.skipif(str(7706) not in TESTS, reason='Excluded') def test_student_can_access_user_support_7706(self): """Can access user support. Steps: Click on the user menu Click on the Get Help option Expected Result: In a new tab or window zendesk is opened """ self.ps.test_updates['name'] = 'cc1.14.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.003', '7706' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.open_user_menu() self.student.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.student.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7707 - 004 - Non-user | Submit support questions @pytest.mark.skipif(str(7707) not in TESTS, reason='Excluded') def test_nonuser_submit_support_questions_7707(self): """Submit support questions. Steps: Go to the Concept Coach landing page click support in the header enter text into the search box click contact us fillout form click Submit Expected Result: 'Message sent' displayed in help box """ self.ps.test_updates['name'] = 'cc1.14.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.004', '7707' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.sleep(1) # number hardcoded because condenses at different size than tutor if self.teacher.driver.get_window_size()['width'] < 1105: element = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//label[@for="mobileNavToggle"]') ) ) actions = ActionChains(self.teacher.driver) # use action chain because it is clicking to the wrong elemnt actions.move_to_element(element) actions.click() actions.perform() support = self.teacher.find( By.LINK_TEXT, 'support' ) actions = ActionChains(self.teacher.driver) actions.move_to_element(support) actions.click() actions.perform() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'searchAskInput' ).send_keys('fake_question') self.teacher.find( By.ID, 'searchAskButton' ).click() self.teacher.find( By.LINK_TEXT, 'Contact Us' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]' ).send_keys('qa') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]' ).send_keys('test') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:email")]' ).send_keys('*****@*****.**') self.teacher.find( By.XPATH, '//div[@class="submit-container"]//input' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[contains(text(),"Thank you")]') ) ) self.ps.test_updates['passed'] = True # Case C7708 - 005 - Teacher | Submit support questions @pytest.mark.skipif(str(7708) not in TESTS, reason='Excluded') def test_teacher_submit_support_questions_7708(self): """Submit support questions. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If user has more than one course, click on a Concept Coach course Click the user menu in the right corner of the header Click "Get Help" Click "Submit a request" Fill out all the necessary text fields Click "Submit" Expected Result: The user submits support questions """ self.ps.test_updates['name'] = 'cc1.14.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.005', '7708' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.teacher.current_url()), 'not at help center' self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'searchAskInput' ).send_keys('fake_question') self.teacher.find( By.ID, 'searchAskButton' ).click() self.teacher.find( By.LINK_TEXT, 'Contact Us' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]' ).send_keys('qa') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]' ).send_keys('test') self.teacher.find( By.XPATH, '//input[contains(@id,"contactUsForm:email")]' ).send_keys('*****@*****.**') self.teacher.find( By.XPATH, '//div[@class="submit-container"]//input' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[contains(text(),"Thank you")]') ) ) self.ps.test_updates['passed'] = True # Case C7709 - 006 - Student | Submit support questions @pytest.mark.skipif(str(7709) not in TESTS, reason='Excluded') def test_student_submit_support_questions_7709(self): """Submit support questions. Steps: Go to Tutor Click on the 'Login' button Enter the student user account in the username and password text boxes Click on the 'Sign in' button Click the user menu in the right corner of the header Click "Get Help" Click "Submit a request" Fill out all the necessary text fields Click "Submit" Expected Result: The user submits support questions """ self.ps.test_updates['name'] = 'cc1.14.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.006', '7709' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.open_user_menu() self.student.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.student.current_url()), 'not at help center' self.student.page.wait_for_page_load() self.student.find( By.ID, 'searchAskInput' ).send_keys('fake_question') self.student.find( By.ID, 'searchAskButton' ).click() self.student.find( By.LINK_TEXT, 'Contact Us' ).click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]' ).send_keys('qa') self.student.find( By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]' ).send_keys('test') self.student.find( By.XPATH, '//input[contains(@id,"contactUsForm:email")]' ).send_keys('*****@*****.**') self.student.find( By.XPATH, '//div[@class="submit-container"]//input' ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[contains(text(),"Thank you")]') ) ) self.ps.test_updates['passed'] = True # Case C7710 - 007 - Teacher | View instructions on how to use CC @pytest.mark.skipif(str(7710) not in TESTS, reason='Excluded') def test_teacher_view_instructions_on_how_to_use_cc_7710(self): """View instructions on how to use Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If user has more than one course, click on a Concept Coach course Click the user menu in the right corner of the header Click "Get Help" Click "Getting Started Guide" * Click on the pdf link OR * Click "Getting Started" from the user menu Expected Result: The user is presented with a guide to use CC """ self.ps.test_updates['name'] = 'cc1.14.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.007', '7710' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Getting Started' ).click() self.teacher.find( By.XPATH, '//h3[contains(text(),"Getting Started")]' ).click() assert('help' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7711 - 008 - Student | View instructions on how to use CC @pytest.mark.skipif(str(7711) not in TESTS, reason='Excluded') def test_student_view_instructions_on_how_to_use_cc_7711(self): """View instructions on how to use Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the student user account in the username and password text boxes Click on the 'Sign in' button Click the user menu in the right corner of the header Click "Get Help" Scroll down to the questions under "Students" Expected Result: The user is presented with instructions on how to use CC """ self.ps.test_updates['name'] = 'cc1.14.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.008', '7711' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.open_user_menu() self.student.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.student.driver.window_handles[1] self.student.driver.switch_to_window(window_with_help) self.student.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.student.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7712 - 009 - Teacher | View instructions on how to assign CC @pytest.mark.skipif(str(7712) not in TESTS, reason='Excluded') def test_teacher_view_instructions_on_how_to_assign_cc_7712(self): """View instructions on how to use Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If user has more than one course, click on a Concept Coach course Click the user menu in the right corner of the header Click "Get Help" Expected Result: Taken to Zendesk in a new window or tab Assorted help is displayed """ self.ps.test_updates['name'] = 'cc1.14.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.009', '7712' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard/")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Get Help' ).click() # change to window with help center window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ) assert('support' in self.teacher.current_url()), 'not at help center' self.ps.test_updates['passed'] = True # Case C7713 - 010 - Student | Get help during account registration @pytest.mark.skipif(str(7713) not in TESTS, reason='Excluded') def test_student_get_help_during_account_registration_7713(self): """View instructions on how to use Concept Coach. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.14.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.010', '7713' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # Case C7714 - 011 - Teacher | View instructions for Legacy users # transitioning to Concept Coach @pytest.mark.skipif(str(7714) not in TESTS, reason='Excluded') def test_teacher_view_instructions_for_legacy_users_transition_7714(self): """View instructions for Legacy users transitioning to Concept Coach. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc1.14.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.14', 'cc1.14.011', '7714' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
def test_teacher_remove_themself_from_the_course_7725(self): """Remove themself from the course. Steps: Go to Tutor Log in as a teacher Click on a Concept Coach book Click on the user menu Select course roster Click on 'Remove' on the same row as themselves Click on the 'Remove' button Expected Result: Teacher is removed from course and taken back to dashboard """ self.ps.test_updates['name'] = 'cc1.10.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.10', 'cc1.10.012', '7725' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.driver.get( 'https://tutor-qa.openstax.org/admin/courses/8/edit') self.admin.page.wait_for_page_load() teacher_name = 'Trent' self.admin.driver.find_element( By.XPATH, '//a[contains(text(),"Teachers")]').click() self.admin.driver.find_element( By.ID, 'course_teacher').send_keys(teacher_name) self.admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name) ) ).click() self.admin.sleep(1) self.admin.driver.find_element( By.LINK_TEXT, 'Main Dashboard').click() self.admin.page.wait_for_page_load() self.admin.logout() # redo set-up, but make sure to go to course 8 # login as the teacher just added to the course teacher2 = Teacher( username='******', password=os.getenv('TEACHER_PASSWORD'), existing_driver=self.teacher.driver ) teacher2.login() teacher2.driver.get('https://tutor-qa.openstax.org/courses/8') teacher2.open_user_menu() teacher2.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Course Settings and Roster') ) ).click() teacher2.page.wait_for_page_load() # delete teacher teachers_list = teacher2.driver.find_elements( By.XPATH, '//div[@class="teachers-table"]//tbody//tr') for x in teachers_list: temp_first = x.find_element( By.XPATH, './td[1]' ).text if temp_first == teacher_name: x.find_element( By.XPATH, './/td//span[contains(text(),"Remove")]' ).click() teacher2.sleep(1) teacher2.driver.find_element( By.XPATH, '//div[@class="popover-content"]//button' ).click() break if x == teachers_list[-1]: print('added teacher was not found, and not deleted') raise Exception # after removing self from course taken to dashboard # or course if only 1 other course assert('/courses/8' not in teacher2.current_url()), \ 'teacher not deleted' teacher2.delete() self.ps.test_updates['passed'] = True
class TestImproveLoginRegistrationEnrollment(unittest.TestCase): """CC2.09 - Improve Login, Registration, Enrollment.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) else: self.teacher = Teacher( use_env_vars=True ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, ) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) self.student = None try: self.teacher.delete() except: pass def get_enrollemnt_code(self, number=0): """ Steps: Sign in as teacher Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Return value: code, enrollemnt_url code - enrollment code enrollemnt_url - url of book for course """ self.teacher.login() if number != 0: cc_courses = self.teacher.find_all( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ) cc_courses[number].click() else: self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Course Settings and Roster' ).click() self.teacher.find( By.XPATH, '//span[contains(text(),"Your student enrollment code")]' ).click() self.teacher.sleep(1) code = self.teacher.find( By.XPATH, '//p[@class="code"]' ).text enrollement_url = self.teacher.find( By.XPATH, '//textarea' ).text enrollement_url = enrollement_url.split('\n')[5] self.teacher.find( By.XPATH, '//button[@class="close"]' ).click() self.teacher.sleep(0.5) self.teacher.logout() return code, enrollement_url def create_user(self, start_num, end_num): """ creates a new user and return the username """ self.student.get("http://accounts-qa.openstax.org") num = str(randint(start_num, end_num)) self.student.find(By.LINK_TEXT, 'Sign up').click() self.student.find( By.ID, 'identity-login-button').click() self.student.find( By.ID, 'signup_first_name').send_keys('first_name_001') self.student.find( By.ID, 'signup_last_name').send_keys('last_name_001') self.student.find( By.ID, 'signup_email_address').send_keys('*****@*****.**') self.student.find( By.ID, 'signup_username').send_keys('automated_09_'+num) self.student.find( By.ID, 'signup_password' ).send_keys(os.getenv('STUDENT_PASSWORD')) self.student.find( By.ID, 'signup_password_confirmation' ).send_keys(os.getenv('STUDENT_PASSWORD')) self.student.find(By.ID, 'signup_i_agree').click() self.student.find( By.ID, 'create_account_submit').click() self.student.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Sign out') ) ).click() print('automated_09_'+num) return 'automated_09_'+num ''' # 14820 - 001 - Teacher | Register for teaching a CC course as new faculty @pytest.mark.skipif(str(14820) not in TESTS, reason='Excluded') def test_teacher_register_for_teaching_cc_course_as_new_facult_14820(self): """Register for teaching a CC course as new faculty. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc2.09.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.001', '14820'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True ''' # 14819 - 002 - Teacher | Register for teaching a CC course as # returning faculty for the same book @pytest.mark.skipif(str(14819) not in TESTS, reason='Excluded') def test_teacher_register_for_teaching_cc_course_as_returning_14819(self): """Register for teaching a CC course as returning faculty. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Click "Course Settings and Roster" from the user menu Click "Add Section" Create a name when prompted Click "Add" Click on the sections from previous semesters Click "Archive Section" Expected Result: A new section is added and the old sections are archived """ self.ps.test_updates['name'] = 'cc2.09.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.002', '14819'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Course Settings and Roster' ).click() # add a new section new_section_name = "new_section_" + str(randint(100, 999)) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"add-period")]//button') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//input[@type="text"]') ) ).send_keys(new_section_name) self.teacher.driver.find_element( By.XPATH, '//div[@class="modal-content"]//button/span[text()="Add"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + new_section_name + '"]') ) ) # revove old section old_section_name = self.teacher.find(By.XPATH, '//a[@role="tab"]').text self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + old_section_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.sleep(2) archived = self.teacher.driver.find_elements( By.XPATH, '//li//a[@role="tab" and text()="' + old_section_name + '"]') assert(len(archived) == 0), ' not archived' # arhive new section and re-add old section as clean-up self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//li//a[@role="tab" and text()="' + new_section_name + '"]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(@class,"archive-period")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@role="tooltip"]//button' + '//span[contains(text(),"Archive")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"view-archived-periods")]//button') ) ).click() periods = self.teacher.driver.find_elements( By.XPATH, '//div[@class="modal-content"]//tbody//tr' ) for period in periods: try: period.find_element( By.XPATH, ".//td[text()='" + old_section_name + "']") period.find_element( By.XPATH, ".//td//span[contains(@class,'restore-period')]//button" ).click() break except NoSuchElementException: if period == periods[-1]: raise Exception self.ps.test_updates['passed'] = True # 14759 - 003 - Student | Sign up and enroll in a CC course @pytest.mark.skipif(str(14759) not in TESTS, reason='Excluded') def test_teacher_sign_up_and_enroll_in_a_cc_course_14759(self): """Sign up and enroll in a CC course. Steps: Sign in as teacher Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Copy and paste the URL into an incognito window Click "Jump to Concept Coach" Click "Launch Concept Coach" Click Sign Up Click Sign up with a password Fill in the required fields Click "Create Account" Enter the numerical enrollment code you get from the teacher Click "Enroll" Enter school issued ID, OR skip this step for now Expected Result: The user is presented with a message that confirms enrollment Is redirected to the CC assignment """ self.ps.test_updates['name'] = 'cc2.09.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.003', '14759'] self.ps.test_updates['passed'] = False # Test steps and verification assertions code, enrollement_url = self.get_enrollemnt_code() rand_username = self.create_user(100, 999) self.student.get(enrollement_url) self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//div[text()="Sign in"]' ).click() self.student.sleep(0.5) login_window = self.student.driver.window_handles[1] cc_window = self.student.driver.window_handles[0] self.student.driver.switch_to_window(login_window) print(rand_username) self.student.find( By.ID, 'auth_key').send_keys(rand_username) print(self.student.password) self.student.find( By.ID, 'password').send_keys(self.student.password) self.student.find( By.XPATH, '//button[text()="Sign in"]').click() try: self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() except NoSuchElementException: pass self.student.driver.switch_to_window(cc_window) self.student.sleep(1) self.student.find( By.XPATH, '//input[@placeholder="enrollment code"]' ).send_keys(code) self.student.find( By.XPATH, '//button/span[text()="Enroll"]' ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[@class="skip"]') ) ).click() # check for confirmation message self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//*[contains(text(),"You have successfully joined")]') ) ) self.ps.test_updates['passed'] = True # 14862 - 004 - Student | Sign in and enroll in a CC course @pytest.mark.skipif(str(14862) not in TESTS, reason='Excluded') def test_teacher_sign_in_and_enroll_in_a_cc_course_14862(self): """Sign in and enroll in a CC course. Steps: Sign in as teacher100 Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Copy and paste the URL into an incognito window Click "Jump to Concept Coach" Click "Launch Concept Coach" Click Sign In Sign in as student71 Enter the numerical enrollment code you get from the teacher Click "Enroll" Enter school issued ID, OR skip this step for now Expected Result: The user is presented with a message that confirms enrollment Is redirected to the CC assignment """ self.ps.test_updates['name'] = 'cc2.09.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.004', '14862'] self.ps.test_updates['passed'] = False # Test steps and verification assertions code, enrollement_url = self.get_enrollemnt_code() # use a new student so that when run a second time no issues # with student already being enrolled in course rand_username = self.create_user(100, 999) self.student.get(enrollement_url) self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.page.wait_for_page_load() self.student.find( By.XPATH, '//div[text()="Sign in"]' ).click() self.student.sleep(0.5) login_window = self.student.driver.window_handles[1] cc_window = self.student.driver.window_handles[0] self.student.driver.switch_to_window(login_window) self.student.find( By.ID, 'auth_key').send_keys(rand_username) self.student.find( By.ID, 'password').send_keys(self.student.password) self.student.find( By.XPATH, '//button[text()="Sign in"]').click() try: self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() self.student.find(By.ID, "i_agree").click() self.student.find(By.ID, "agreement_submit").click() except NoSuchElementException: pass self.student.driver.switch_to_window(cc_window) self.student.sleep(1) self.student.find( By.XPATH, '//input[@placeholder="enrollment code"]' ).send_keys(code) self.student.find( By.XPATH, '//button/span[text()="Enroll"]' ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[@class="skip"]') ) ).click() # check for confirmation message self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//*[contains(text(),"You have successfully joined")]') ) ) self.ps.test_updates['passed'] = True # 14771 - 005 - User | View a message that says you need an enrollment code # before signing up @pytest.mark.skipif(str(14771) not in TESTS, reason='Excluded') def test_user_view_a_message_that_says_you_need_an_enrollment_14771(self): """View a message that says you need an enrollment code before signing up. Steps: Sign in as teacher100 Click on a Concept Coach course Click on "Course Settings and Roster" from the user menu Click "Your Student Enrollment Code" Copy and paste the URL into an incognito window Click "Jump to Concept Coach" Click "Launch Concept Coach" Expected Result: The user is presented with a message that says "Sign up with your enrollment code. If you don't have an enrollment code, contact your instructor." """ self.ps.test_updates['name'] = 'cc2.09.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.005', '14771'] self.ps.test_updates['passed'] = False # Test steps and verification assertions code, enrollement_url = self.get_enrollemnt_code() self.student.get(enrollement_url) self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//p[@class="code-required"]') ) ) self.ps.test_updates['passed'] = True # 14821 - 006 - Student | Jump to CC from the top of the reading @pytest.mark.skipif(str(14821) not in TESTS, reason='Excluded') def test_student_jump_to_cc_from_the_top_of_the_reading_14821(self): """Jump to CC from the top of the reading. Steps: If the user has more than one course, click on a CC course name Click on a non-introductory section Click "Jump to Concept Coach" Expected Result: The screen jumps to the "Launch Concept Coach" button """ self.ps.test_updates['name'] = 'cc2.09.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.006', '14821'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.find( By.XPATH, '//a[contains(@href,"cnx")]' # possibly change ).click() self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button//span[text()="Contents"]') ) ).click() self.student.sleep(0.5) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]') ) ).click() self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ) self.ps.test_updates['passed'] = True # 14822 - 007 - Teacher | Jump to CC from the top of the reading @pytest.mark.skipif(str(14822) not in TESTS, reason='Excluded') def test_teacher_jump_to_cc_from_the_top_of_the_reading_14822(self): """Jump to CC from the top of the reading. Steps: If the user has more than one course, click on a CC course name Click "Online Book" Click on a non-introductory section Click "Jump to Concept Coach" Expected Result: The screen jumps to the "Launch Concept Coach" button """ self.ps.test_updates['name'] = 'cc2.09.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.007', '14822'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() # open book self.teacher.driver.find_element( By.XPATH, '//a//span[contains(text(),"Online Book")]' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('cnx' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' # get to non-introductory section of book self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button//span[text()="Contents"]') ) ).click() self.student.sleep(0.5) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]') ) ).click() self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ) self.ps.test_updates['passed'] = True # 107585 - 008 - Teacher | Register and enroll in a CC course without a # username @pytest.mark.skipif(str(107585) not in TESTS, reason='Excluded') def test_teacher_jump_to_cc_from_the_top_of_the_reading_107585(self): """Register and enroll in a CC course thout a username. Steps: [Get an enrollment link from a teacher in course settings and roster] Go to link Click orange "Jump to Concept Coach" button Click "Enroll in This Course" Click "sign Up and Enroll" [In the new window' Select 'Student' from the 'I am a' drop down menu Enter an email into the email text box Click 'Next' [an email with a pin is sent, log onto email and get pin] Enter Pin into text box Click 'Confirm' Enter password [staxly16] into password text box Re-Enter password in confirm password text box Click Submit Enter first name into the 'First Name' text box Enter last name into the 'Last Name' text box Enter school into 'School' text box Click the checkbox for 'I Agree' for the Terms of Use and the Privacy Policy Click 'Create Account' Click the checkbox and click 'I Agree' for the Terms of Use Click the checkbox and click 'I Agree' for the Privacy Policy Expected Result: Pop-up box for account creation is closed. New user is logged into Concept Coach. """ self.ps.test_updates['name'] = 'cc2.09.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc2', 'cc2.09', 'cc2.09.008', '107585' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True
class TestViewClassPerformance(unittest.TestCase): """T1.22 - View Class Performance.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher.login() self.teacher.select_course(appearance='biology') self.teacher.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click() def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C8148 - 001 - Teacher | View the period Performance Forecast @pytest.mark.skipif(str(8148) not in TESTS, reason='Excluded') def test_teacher_view_the_period_performance_forecast_8148(self): """View the period Performance Forecast. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR click on the user drop down menu then click on the "Performance Forecast" button Click on the desired period Expected Result: The period Performance Forecast is presented to the user """ self.ps.test_updates['name'] = 't1.22.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.001', '8148' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.ps.test_updates['passed'] = True # Case C8149 - 002 - Teacher | Info icon shows an explanation of the data @pytest.mark.skipif(str(8149) not in TESTS, reason='Excluded') def test_teacher_info_icon_shows_an_explanation_of_the_data_8149(self): """Info icon shows an explanation of the data. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR Click on the user drop down menu then click on the "Performance Forecast" button Hover the cursor over the info icon that is next to the "Performance Forecast" header Expected Result: Info icon shows an explanation of the data """ self.ps.test_updates['name'] = 't1.22.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.002', '8149' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.teacher.wait.until( expect.visibility_of_element_located( (By.CLASS_NAME, 'info-link') ) ).click() self.ps.test_updates['passed'] = True # Case C8150 - 003 - Teacher | View the performance color key @pytest.mark.skipif(str(8150) not in TESTS, reason='Excluded') def test_teacher_view_the_performance_color_key_8150(self): """View the performance color key. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR click on the user drop down menu click on the "Performance Forecast" button Expected Result: The performance color key is presented to the user (next to the 'Return to Dashboard' button) """ self.ps.test_updates['name'] = 't1.22.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.003', '8150' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.teacher.wait.until( expect.visibility_of_element_located( (By.CLASS_NAME, 'guide-key') ) ) self.ps.test_updates['passed'] = True # Case C8151 - 004 - Teacher | Return to Dashboard button returns to # the calendar @pytest.mark.skipif(str(8151) not in TESTS, reason='Excluded') def test_teacher_return_to_dashboard_button_returns_to_the_cal_8151(self): """Return to Dashboard button returns to the calendar. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR Click on the user drop down menu Click on the "Performance Forecast" button Expected Result: The calendar dashboard is presented to the user """ self.ps.test_updates['name'] = 't1.22.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.004', '8151' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.teacher.open_user_menu() self.teacher.wait.until( expect.presence_of_element_located( (By.LINK_TEXT, 'Dashboard') ) ).click() assert('calendar' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C8152 - 005 - Teacher | Periods tabs are shown @pytest.mark.skipif(str(8152) not in TESTS, reason='Excluded') def test_teacher_period_tabs_are_shown_8152(self): """Period tabs are shown. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR click on the user drop down menu click on the "Performance Forecast" button Expected Result: The period tabs are shown to the user (below the "Performance Forecast" header) """ self.ps.test_updates['name'] = 't1.22.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.005', '8152' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.teacher.find(By.CLASS_NAME, 'active') self.ps.test_updates['passed'] = True # Case C8153 - 006 - Teacher | A period with zero answers does not # show section breakdowns @pytest.mark.skipif(str(8153) not in TESTS, reason='Excluded') def test_teacher_a_period_w_zero_answers_does_not_show_breaks_8153(self): """A period with zero answers does not show section breakdowns. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR Click on the user drop down menu Click on the "Performance Forecast" button Click on the period with zero answers Expected Result: The user should see no section breakdowns as well as the words "There have been no questions worked for this period." """ self.ps.test_updates['name'] = 't1.22.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.006', '8153' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions # Create an empty period to use for the test period_name = "22_" + str(randint(100, 999)) self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, 'Course Settings and Roster').click() self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, "//div[@class='control add-period']/button").click() self.teacher.find( By.XPATH, "//input[@class='form-control empty']").send_keys(period_name) self.teacher.find( By.XPATH, "//button[contains(@class,'-edit-period-confirm')]" ).click() popup = self.teacher.find( By.XPATH, '//div[@class="teacher-edit-period-modal fade in modal"]') self.teacher.wait.until( expect.staleness_of( (popup) ) ) # Check the new empty period in Performance Forecast self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, 'Performance Forecast').click() assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, period_name) ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.CLASS_NAME, 'no-data-message') ) ) # Archive the new period as clean up self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Course Settings and Roster' ).click() self.teacher.wait.until( expect.visibility_of_element_located(( By.LINK_TEXT, period_name) ) ).click() self.teacher.find( By.XPATH, "//a[@class='control archive-period']").click() self.teacher.find( By.XPATH, "//button[@class='async-button archive-section btn btn-default']" ).click() self.ps.test_updates['passed'] = True # Case C8154 - 007 - Teacher | Weaker areas shows up to # four problematic sections @pytest.mark.skipif(str(8154) not in TESTS, reason='Excluded') def test_teacher_weaker_shows_up_to_four_problematic_sections_8154(self): """Weaker areas shows up to four problematic sections. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR click on the user drop down menu click on the "Performance Forecast" button Click on the desired period Expected Result: Weaker Areas show up to four problematic sections """ self.ps.test_updates['name'] = 't1.22.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.007', '8154' ] self.ps.test_updates['passed'] = False # Test steps and verification assertion assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' weak = self.teacher.find_all( By.XPATH, "//div[@class='chapter-panel weaker']/div[@class='sections']/div") assert(len(weak) <= 4), \ 'Not viewing performance forecast' self.ps.test_updates['passed'] = True # Case C8155 - 008 - Teacher | Chapters are listed on the left with # their sections to the right @pytest.mark.skipif(str(8155) not in TESTS, reason='Excluded') def test_teacher_chapters_listed_on_left_w_sections_on_right_8155(self): """Chapter are listed on the left with their sections to the right. Steps: On the calendar dashboard, click on the "Performance Forecast" button on the upper right corner of the calendar OR Click on the user drop down menu Click on the "Performance Forecast" button Click on the desired period Scroll to the "Individual Chapters" section Expected Result: Chapters are listed on the left with their sections to the right """ self.ps.test_updates['name'] = 't1.22.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't1', 't1.22', 't1.22.008', '8155' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions assert('guide' in self.teacher.current_url()), \ 'Not viewing performance forecast' self.teacher.page.wait_for_page_load() panels = self.teacher.find_all(By.CLASS_NAME, 'chapter-panel') for panel in panels: panel.find_elements_by_class_name('chapter') panel.find_elements_by_class_name('sections') self.ps.test_updates['passed'] = True
class TestTeacherLoginAndAuthentification(unittest.TestCase): """CC1.11 - Teacher Login and Authentification.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.teacher.login() def tearDown(self): """Test destructor.""" self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass # Case C7688 - 001 - Teacher | Log into Concept Coach @pytest.mark.skipif(str(7688) not in TESTS, reason='Excluded') def test_teacher_log_into_concept_coach_7688(self): """Log into Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: User is taken to the class dashboard. """ self.ps.test_updates['name'] = 'cc1.11.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.11', 'cc1.11.001', '7688'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.select_course(appearance='macro_economics') self.teacher.sleep(5) assert('cc-dashboard' in self.teacher.current_url()), \ 'Not viewing the cc dashboard' self.ps.test_updates['passed'] = True # Case C7689 - 002 - Teacher | Logging out returns to the login page @pytest.mark.skipif(str(7689) not in TESTS, reason='Excluded') def test_teacher_loggin_out_returns_to_the_login_page_7689(self): """Logging out returns to the login page. Steps: Click the user menu containing the user's name Click the 'Log Out' button Expected Result: User is taken to cc.openstax.org """ self.ps.test_updates['name'] = 'cc1.11.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.11', 'cc1.11.002', '7689'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.select_course(appearance='macro_economics') self.teacher.sleep(5) assert('dashboard' in self.teacher.current_url()), \ 'Not viewing the cc dashboard' self.teacher.open_user_menu() self.teacher.sleep(1) self.teacher.find(By.XPATH, "//a/form[@class='-logout-form']").click() assert('cc.openstax.org' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C7690 - 003 - Teacher | Can log into Tutor and be redirected to CC @pytest.mark.skipif(str(7690) not in TESTS, reason='Excluded') def test_teacher_can_log_into_tutor_and_be_redirected_to_cc_7690(self): """Can log into Tutor and be redirected to Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: User is taken to the class dashboard """ self.ps.test_updates['name'] = 'cc1.11.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.11', 'cc1.11.003', '7690'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.select_course(appearance='macro_economics') self.teacher.sleep(5) assert('cc-dashboard' in self.teacher.current_url()), \ 'Not viewing the cc dashboard' self.ps.test_updates['passed'] = True
class TestViewTheCalendarDashboard(unittest.TestCase): """T1.13 - View the calendar.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher.login() self.teacher.select_course(title='HS Physics') def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C7978 - 001 - Teacher | View the calendar dashboard @pytest.mark.skipif(str(7978) not in TESTS, reason='Excluded') def test_teacher_view_the_calendar_dashboard_7978(self): """View the calendar dashboard. Steps: If the user has more than one course, click on a Tutor course name Expected Result: The teacher is presented their calendar dashboard. """ self.ps.test_updates['name'] = 't1.13.001' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.001', '7978'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') assert('calendar' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C7979 - 002 - Teacher | View student scores using dashboard button @pytest.mark.skipif(str(7979) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_using_the_dashboard_button_7979(self): """View student scores using the dashboard button. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Student Scores' button Expected Result: The teacher is presented with the student scores """ self.ps.test_updates['name'] = 't1.13.002' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.002', '7979'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.find(By.LINK_TEXT, 'Student Scores').click() assert('scores' in self.teacher.current_url()), \ 'Not viewing student scores' self.ps.test_updates['passed'] = True # Case C7980 - 003 - Teacher | View student scores using the user menu link @pytest.mark.skipif(str(7980) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_using_the_user_menu_link_7980(self): """View student scores using the user menu link. Steps: If the user has more than one course, click on a Tutor course name Click on the user menu Click on the 'Student Scores' link Expected Result: The teacher is presented with the student scores """ self.ps.test_updates['name'] = 't1.13.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.003', '7980'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.open_user_menu() self.teacher.find(By.CLASS_NAME, 'viewScores'). \ find_element_by_tag_name('a'). \ click() assert('scores' in self.teacher.current_url()), \ 'Not viewing the student scores' self.ps.test_updates['passed'] = True # Case C7981 - 004 - Teacher | View performance forecast using the # dashboard button @pytest.mark.skipif(str(7981) not in TESTS, reason='Excluded') def test_teacher_view_performance_forecast_using_dash_button_7981(self): """View performance forecast using the dashboard button. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Performance Forecast' button on the dashboard Expected Result: The teacher is presented with the performance forecast """ self.ps.test_updates['name'] = 't1.13.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.004', '7981'] self.ps.test_updates['passed'] = False self.teacher.find(By.LINK_TEXT, 'Performance Forecast').click() self.teacher.page.wait_for_page_load() assert('guide' in self.teacher.current_url()), \ 'Not viewing the performance forecast' self.ps.test_updates['passed'] = True # Case C7982 - 005 - Teacher | View performace forecast using # the user menu link @pytest.mark.skipif(str(7982) not in TESTS, reason='Excluded') def test_teacher_view_performance_forecast_using_user_menu_link_7982(self): """View performance forecast using the user menu link. Steps: If the user has more than one course, click on a Tutor course name Click on the user menu Click on the 'Performance Forecast' link Expected Result: The teacher is presented with the performance forecast """ self.ps.test_updates['name'] = 't1.13.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.005', '7982'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.open_user_menu() self.teacher.find(By.CLASS_NAME, 'viewTeacherPerformanceForecast'). \ find_element_by_tag_name('a'). \ click() self.teacher.page.wait_for_page_load() assert('guide' in self.teacher.current_url()), \ 'Not viewing the performance forecast' self.ps.test_updates['passed'] = True # Case C7983 - 006 - Teacher | View a reading assignment summary @pytest.mark.skipif(str(7983) not in TESTS, reason='Excluded') def test_teacher_view_a_reading_assignment_summary_7983(self): """View a reading assignment summary. Steps: If the user has more than one course, click on a Tutor course name Create a reading assignment Click on the reading assignment on the calendar Expected Result: The teacher is presented with the reading assignment summary """ self.ps.test_updates['name'] = 't1.13.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.006', '7983'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') # create an assignment assignment_name = 'reading-%s' % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'reading_list': ['1.1'], 'status': 'publish', } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # Case C7984 - 007 - Teacher | View a homework assignment summary @pytest.mark.skipif(str(7984) not in TESTS, reason='Excluded') def test_teacher_view_a_homework_assignment_summary_7984(self): """View a homework assignment summary. Steps: create a homework assignment If the user has more than one course, click on a Tutor course name Click on a homework assignment on the calendar Expected Result: The teacher is presented with the homework assignment summary """ self.ps.test_updates['name'] = 't1.13.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.007', '7984'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') # create an assignment assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'problems': {'1.1': (2, 3), }, 'status': 'publish', 'feedback': 'immediate' } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # NOT DONE # Case C7985 - 008 - Teacher | View an external assignment summary @pytest.mark.skipif(str(7985) not in TESTS, reason='Excluded') def test_teacher_view_an_external_assignment_summary_7985(self): """View an external assignment summary. Steps: If the user has more than one course, click on a Tutor course name Click on an external assignment on the calendar Expected Result: The teacher is presented with the external assignment summary """ self.ps.test_updates['name'] = 't1.13.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.008', '7985'] self.ps.test_updates['passed'] = False # create an assignment assignment_name = 'external-%s' % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='external', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'url': 'google.com', 'status': 'publish' } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # Case C7986 - 009 - Teacher | View an event summary @pytest.mark.skipif(str(7986) not in TESTS, reason='Excluded') def test_teacher_view_an_event_summary_7986(self): """View an event summary. Steps: If the user has more than one course, click on a Tutor course name Click on an event on the calendar Expected Result: The teacher is presented with the event summary """ self.ps.test_updates['name'] = 't1.13.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.009', '7986'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') # create an assignment assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish' } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # Case C7987 - 010 - Teacher | Open the refrenece book using the dashboard # button @pytest.mark.skipif(str(7987) not in TESTS, reason='Excluded') def test_teacher_open_the_reference_book_using_dashboard_button_7987(self): """Open the refrenece book using the dashboard button. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Browse The Book'button Expected Result: The teacher is preseneted with the book in a new tab """ self.ps.test_updates['name'] = 't1.13.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.010', '7987'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.driver.find_element( By.LINK_TEXT, 'Browse The Book' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('book' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' self.ps.test_updates['passed'] = True # Case C7988 - 011 - Teacher | Open the refrenece book using user menu link @pytest.mark.skipif(str(7988) not in TESTS, reason='Excluded') def test_teacher_open_the_reference_book_using_user_menu_link_7988(self): """Open the refrenece book using the user menu link. Steps: If the user has more than one course, click on a Tutor course name Click on the user menu Click on the 'Browse the Book' link Expected Result: The teacher is presented with the book in a new tab """ self.ps.test_updates['name'] = 't1.13.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.011', '7988'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.open_user_menu() self.teacher.driver.find_element( By.LINK_TEXT, 'Browse the Book' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('book' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' self.ps.test_updates['passed'] = True # Case C7989 - 012 - Teacher | Click on the course name to return to # the dashboard @pytest.mark.skipif(str(7989) not in TESTS, reason='Excluded') def test_teacher_click_course_name_to_return_to_the_dashboard_7989(self): """Click on the course name to return to the dashboard. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Performance Forecast' button Click on the course name in the header Expected Result: The teacher is presented with their calendar dashboard """ self.ps.test_updates['name'] = 't1.13.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.012', '7989'] self.ps.test_updates['passed'] = False self.teacher.open_user_menu() self.teacher.driver.find_element( By.CLASS_NAME, 'viewTeacherPerformanceForecast' ).click() self.teacher.driver.find_element( By.CLASS_NAME, 'course-name' ).click() assert('calendar' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C7990 - 013 - Teacher | Cick on the OpenStax logo to return to # the course picker @pytest.mark.skipif(str(7990) not in TESTS, reason='Excluded') def test_teacher_click_openstax_logo_to_return_to_course_picker_7990(self): """Cick on the OpenStax logo to return to the course picker. Steps: If the user has more than one course, click on a Tutor course name Click in the OpenStax logo in the header Expected Result: The teacher is presented with the course picker """ self.ps.test_updates['name'] = 't1.13.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.013', '7990'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') self.teacher.driver.find_element( By.CLASS_NAME, 'ui-brand-logo' ).click() assert('dashboard' in self.teacher.current_url()), \ 'Not viewing the course picker' self.ps.test_updates['passed'] = True # Case C7991 - 014 - Teacher | CLick in the OpenStax logo to return to the # dashboard @pytest.mark.skipif(str(7991) not in TESTS, reason='Excluded') def test_teacher_clicks_openstax_logo_to_return_to_dashboard_7991(self): """CLick in the OpenStax logo to return to the dashboard. Steps: Click on the 'Performance Forecast' button Click on the OpenStax logo in the header Expected Result: The teacher is presented with their calendar dashboard """ self.ps.test_updates['name'] = 't1.13.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.014', '7991'] self.ps.test_updates['passed'] = False self.teacher.logout() teacher2 = Teacher( username=os.getenv('TEACHER_USER_ONE_COURSE'), password=os.getenv('TEACHER_PASSWORD'), site='https://tutor-qa.openstax.org', existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities, ) print(teacher2.username) print(teacher2.password) teacher2.login() self.teacher.open_user_menu() self.teacher.driver.find_element( By.CLASS_NAME, 'viewTeacherPerformanceForecast' ).click() self.teacher.driver.find_element( By.CLASS_NAME, 'ui-brand-logo' ).click() assert('calendar' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True
class TestExercisesTeacher(unittest.TestCase): """Tutor | Teacher""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.teacher = Teacher(use_env_vars=True) # self.teacher.login(url='http://exercises-qa.openstax.org') def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass @pytest.mark.skipif(str(162257) not in TESTS, reason='Excluded') def test_creating_true_and_false_question_162257(self): """ Go to exercises qa Log in as a teacher Click "Write a new exercise" Click "True/False" button Expected result: ***User is presented with a page where a True/False question can be created*** Corresponding test cases: T2.12 001, 002 https://trello.com/c/w4T1eqT4/66-creating-vocabulary-question-and-true-false """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162257' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162257'] self.ps.test_updates['passed'] = False # log into exercises self.teacher.login(url=os.getenv('EXERCISES_STAGING'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # Click "Write a new exercise" self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() # Click true false button self.teacher.find(By.CSS_SELECTOR, "#input-true-false").click() # Verify that user is presented with a page where they can make a true # false q self.teacher.find(By.CSS_SELECTOR, "textarea") self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162258) not in TESTS, reason='Excluded') def test_question_library_functionality_162258(self): """ Go to tutor qa Log in as a teacher Click on a course Upper right corner under user menu, click "Question Library" Select a section or chapter click "Show Questions" **User is presented with all the questions for the section or chapter** Scroll down to a question, click "Exclude Question" ***Observe that Question is excluded*** Click on the "Reading" tab ***Exercises that are only for Reading appear*** Click on the "Practice" tab @@@@@@@@@@@ Should this be Homework? ***Exercises that are only for Practice appear*** Scroll down **Observe that tabs are pinned to the top of the screen when scrolled** Click on the section links at the top of the screen ***Observe that the screen scrolls to the selected screen*** Hover over a question and click "Question details" Click "Report an error" Expected result: ***Observe that a new tab with the assessment errata form appears with the assessment ID already filled in*** Corresponding test cases: T2.11 001-007 https://trello.com/c/SchGDgfL/70-question-library-functionality """ self.ps.test_updates['name'] = \ 'exercises_question_library_teacher_162258' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'question_library', 'teacher', '162258'] self.ps.test_updates['passed'] = False self.teacher.login() # select random tutor course self.teacher.random_course() # if Tutor feedback pops up try: self.teacher.find( By.XPATH, ".//*[contains(text(),'I won’t be using it')]").click() except: pass # go to question library self.teacher.open_user_menu() self.teacher.wait.until( expect.visibility_of_element_located( (By.CSS_SELECTOR, "#menu-option-viewQuestionsLibrary"))) self.teacher.find(By.CSS_SELECTOR, "#menu-option-viewQuestionsLibrary").click() # 50/50 coin toss. 0 = chapter, 1 = section(s) coin = randint(0, 1) # reveal sections chaptertitles = self.teacher.find_all( By.CSS_SELECTOR, ".chapter-heading.panel-title>a") for num in range(1, len(chaptertitles) - 1): self.teacher.scroll_to(chaptertitles[num]) self.teacher.sleep(.2) chaptertitles[num].click() self.teacher.sleep(.2) # choose a random chapter and all its sections if coin == 0: chapters = self.teacher.find_all(By.CSS_SELECTOR, ".chapter-checkbox") chapternum = randint(0, len(chapters) - 1) self.teacher.scroll_to(chapters[chapternum]) self.teacher.sleep(0.5) chapters[chapternum].click() self.teacher.sleep(0.5) # choose randomly 1-5 sections from anywhere in the book elif coin == 1: sections = self.teacher.find_all(By.CSS_SELECTOR, ".section-checkbox") randomlist = random.sample(range(len(sections) - 1), k=randint(1, 5)) for num in randomlist: self.teacher.scroll_to(sections[num]) self.teacher.sleep(.5) sections[num].click() # click show questions self.teacher.find(By.CSS_SELECTOR, ".btn.btn-primary").click() self.teacher.sleep(5) # verify questions show up readingq = self.teacher.find_all(By.CSS_SELECTOR, ".controls-overlay") excludebutton = self.teacher.find_all(By.CSS_SELECTOR, ".action.exclude")[0] # exclude a random question self.teacher.scroll_to(excludebutton) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(excludebutton) self.teacher.sleep(1) actions.perform() self.teacher.sleep(2) excludebutton.click() self.teacher.sleep(.5) self.teacher.find(By.CSS_SELECTOR, ".action.include").click() # click reading button self.teacher.find(By.CSS_SELECTOR, ".reading.btn.btn-default").click() self.teacher.page.wait_for_page_load() totalq = self.teacher.find_all(By.CSS_SELECTOR, ".controls-overlay") # click homework button self.teacher.find(By.CSS_SELECTOR, ".homework.btn.btn-default").click() homeworkq = self.teacher.find_all(By.CSS_SELECTOR, ".controls-overlay") assert (len(totalq) > len(readingq)) assert (len(totalq) > len(homeworkq)) # Observe that tabs are pinned to the top of the screen when scrolled self.teacher.driver.execute_script("window.scrollTo(0, 0);") self.teacher.sleep(3) self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.sleep(3) self.teacher.find(By.XPATH, "//div[@class='section active']") self.teacher.find(By.CSS_SELECTOR, ".homework.btn.btn-default") self.teacher.find(By.CSS_SELECTOR, ".reading.btn.btn-default") # jumps jumps = self.teacher.find_all( By.XPATH, "//div[@class='sectionizer']/div[@class='section']") # Click the section links and verify the page is scrolled position = self.teacher.driver.execute_script("return window.scrollY;") for button in jumps: button.click() self.teacher.sleep(1) assert(position != self.teacher.driver.execute_script( "return window.scrollY;")), \ 'Section link did not jump to next section' position = \ self.teacher.driver.execute_script("return window.scrollY;") # details will lead to Question details details = self.teacher.find_all(By.CSS_SELECTOR, ".action.details")[0] self.teacher.scroll_to(details) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(details) self.teacher.sleep(1) actions.perform() self.teacher.sleep(2) details.click() self.teacher.find(By.CSS_SELECTOR, ".action.report-error").click() details_window = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(details_window) self.teacher.page.wait_for_page_load() self.teacher.sleep(2) self.teacher.find(By.CSS_SELECTOR, ".errata-page.page") self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162259) not in TESTS, reason='Excluded') def test_creating_multiple_choice_questions_162259(self): """ Go to exercises qa Log in as a teacher Click "Write a new exercise" Enter the video embed link into the Question Stem text box ***The video should appear in the box to the right*** Fill out the required fields Click on the box "Order Matters" ***User is able to preserve the order of choices*** Click "Tags" Click "Question Type", "DOK", "Blooms", and/or "Time" ***The user is able to pull out the dropdown tags*** Select a choice from the dropdown tags ***User is able to select a specific tag and the tag(s) appear in the box to the right*** Check the box that says "Requires Context" ***The user is able to specify whether context is required for a question and the tag "requires-context:true" appears in the box to the right*** Click "+" next to "CNX Module" Enter the CNX Module number Click "Save Draft" Click "Assets" Click "Add new image" Select an image ***The image and the options "Choose different image" and "Upload" should come up*** Click "Upload" ***There shoould be a URL and a "Delete" button)*** ***The user is presented with uploaded URL in the HTML snippet*** Click "Delete" ***The image is deleted*** Click "Save Draft", then click "Publish" ***Observe message: "Exercise [exercise ID] has published successfully")*** Click "Search" Enter the desired exercise ID Scroll down to "Detailed Solutions" Edit text in the "Detailed Solutions" text box Click "Publish" Expected Result: ***The user is able to edit detailed solutions and the changes are in the box to the right*** Corresponding test cases: T2.11 022-031 https://trello.com/c/n5VmmdyB/83-creating-multiple-choice-questions """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162259' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162259'] self.ps.test_updates['passed'] = False self.teacher.login(url=os.getenv('EXERCISES_QA'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # click create a new question self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() textboxes = self.teacher.find_all(By.CSS_SELECTOR, ".question>div>textarea") # put embed link into Question Stem text box embedlink = '<iframe width="560" height="315" ' + \ 'src="https://www.youtube.com/embed/' embedlink += 'QnQe0xW_JY4" frameborder="0" allowfullscreen></iframe>"' textboxes[0].send_keys(embedlink) # verify that the video appears in the box to the right self.teacher.find(By.CSS_SELECTOR, "iframe") # fill out the required fields answers = self.teacher.find_all(By.CSS_SELECTOR, ".correct-answer>textarea") answers[0].send_keys('answer numero uno') answers[1].send_keys('answer numero dos') # textboxes[1].send_keys('answer numero tres') # click on Order Matters checkbox self.teacher.find(By.CSS_SELECTOR, "#input-om").click() # Click on Tabs tag self.teacher.find(By.CSS_SELECTOR, "#exercise-parts-tab-tags").click() # verify that all the dropdowns are clickable tagoptions = self.teacher.find_all(By.CSS_SELECTOR, ".form-control") for num in range(len(tagoptions)): expect.element_to_be_clickable(tagoptions[num]) # choose an option from a dropdown tagoptions[1].click() self.teacher.find_all(By.CSS_SELECTOR, "option")[1].click() # verify that the tag appears in the box to the right self.teacher.find( By.XPATH, "//*[@class='exercise-tag' and contains(text(),'type')]") self.teacher.find(By.CSS_SELECTOR, ".tag>input").click() self.teacher.find( By.XPATH, "//*[@class='exercise-tag' and contains(text(),'context:true')]") # click "+" next to CNX Module self.teacher.find_all(By.CSS_SELECTOR, ".fa.fa-plus-circle")[2].click() # put in a CNX module self.teacher.find( By.XPATH, ".//*[@class='form-control' and @placeholder]").send_keys( '12345678-1234-5788-9123-456798123456') # click save draft self.teacher.find(By.CSS_SELECTOR, ".async-button.draft.btn.btn-info").click() # click assets tab self.teacher.find(By.CSS_SELECTOR, "#exercise-parts-tab-assets") \ .click() # Choose image. This is all local -- prob have to edit for diff # computer IMAGEPATH = "/Users/openstax10/desktop/bee_clip_art_18782.jpg" self.teacher.find(By.ID, "file").send_keys(IMAGEPATH) # check that Choose different image and Upload buttons are present self.teacher.find(By.XPATH, './/*[contains(text(),"Choose different image")]') self.teacher.find(By.XPATH, './/*[contains(text(),"Upload")]').click() self.teacher.page.wait_for_page_load() # check if uploaded url is present self.teacher.find(By.CSS_SELECTOR, ".copypaste") # check that delete button is present and click it self.teacher.find(By.XPATH, './/*[contains(text(),"Delete")]').click() self.teacher.sleep(1) # click publish self.teacher.find(By.CSS_SELECTOR, '.async-button.publish.btn.btn-primary').click() self.teacher.sleep(1) # confirm that you want to publish self.teacher.find( By.XPATH, './/*[@class="btn btn-primary" and contains(text(),"Publish")]' ).click() self.teacher.sleep(1) # close popup window tellign you ID # self.teacher.find( By.XPATH, './/*[@class="btn btn-primary" and contains(text(),"Close")]' ).click() # get id ID = self.teacher.current_url().split('/')[-1] # click search button self.teacher.find(By.CSS_SELECTOR, '.btn.btn-danger.back.btn.btn-default').click() # enter ID into field self.teacher.find(By.CSS_SELECTOR, '.form-control').send_keys(ID) self.teacher.find(By.CSS_SELECTOR, '.btn.btn-default.load').click() # edit detailed solution self.teacher.find(By.XPATH, "//div[4]/textarea") \ .send_keys('hello edited') detailedsol = self.teacher.find( By.CSS_SELECTOR, '.openstax-has-html.solution').get_attribute('innerHTML') # check that the text you inputted into detailed solution is in the # box to the right assert ('hello edited' == detailedsol) self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162260) not in TESTS, reason='Excluded') def test_creating_vocabulary_questions_162260(self): """ Go to exercises qa Log in with as a teacher Click "Write a new exercise" Click "New Vocabulary Term" from the header Fill out required fields Click "Save Draft" Click "Publish" ***The "Publish" button is whited out and the exercise ID appears in the box to the right*** Click "Search" Enter the desired exercise ID ***The vocabulary question loads and user is able to review it*** Enter next text into "Key Term", "Key Term Definition", and "Distractors" Click "Save Draft" Click "Publish" Expected result: ***The user is able to edit and save a vocabulary question*** Corresponding test cases: T2.11 035-037 https://trello.com/c/3j0K6fp0/89-creating-vocabulary-questions """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162260' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162260'] self.ps.test_updates['passed'] = False # logging in with these credentials self.teacher.login(url=os.getenv('EXERCISES_QA'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # click create a new question self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() # click New vocabulary question self.teacher.find(By.CSS_SELECTOR, ".btn.btn-success.vocabulary.blank").click() # enter testing as the key term self.teacher.find(By.CSS_SELECTOR, "#key-term").send_keys('testing') # enter 'ignore' as the definition self.teacher.find(By.CSS_SELECTOR, "#key-term-def").send_keys('ignore') # click save draft self.teacher.find(By.CSS_SELECTOR, ".async-button.draft.btn.btn-info").click() # click publish self.teacher.find(By.CSS_SELECTOR, ".async-button.publish.btn.btn-primary").click() self.teacher.sleep(1) # confirm publish self.teacher.find( By.XPATH, ".//*[@class='btn btn-primary' and contains(text(),'Publish')]" ).click() self.teacher.sleep(3) # get the exercise id exerciseid = self.teacher.find_all( By.CSS_SELECTOR, ".exercise-tag")[3].get_attribute('innerHTML')[4:] # go to search self.teacher.find(By.XPATH, ".//*[contains(text(),'Search')]").click() # search the exercise id self.teacher.find(By.CSS_SELECTOR, ".form-control") \ .send_keys(exerciseid) # click search self.teacher.find(By.CSS_SELECTOR, ".btn.btn-default.load").click() # confirm key term value is what was inputted originally keyterm = self.teacher.find(By.CSS_SELECTOR, "#key-term") \ .get_attribute('value') assert (keyterm == 'testing') # write something else for key term keyterm = self.teacher.find(By.CSS_SELECTOR, "#key-term") keyterm.send_keys(Keys.BACKSPACE * len('testing ')) self.teacher.sleep(0.2) keyterm.send_keys('test edit') # confirm key term def value is what was inputted oirignally keytermdef = self.teacher.find(By.CSS_SELECTOR, '#key-term-def') \ .get_attribute('value') assert (keytermdef == 'ignore') # write something else for key term def keytermdef = self.teacher.find(By.CSS_SELECTOR, "#key-term-def") keytermdef.send_keys(Keys.BACKSPACE * len('ignore ')) self.teacher.sleep(0.2) keytermdef.send_keys('ignore edit') # fill in value for distractor self.teacher.find_all(By.CSS_SELECTOR, ".form-control")[2].send_keys('im a distractor') self.teacher.sleep(3) # save as draft self.teacher.find(By.CSS_SELECTOR, ".async-button.draft.btn.btn-info").click() self.teacher.sleep(1) # publish self.teacher.find(By.CSS_SELECTOR, ".async-button.publish.btn.btn-primary").click() # confirm publish self.teacher.find( By.XPATH, './/*[@class="btn btn-primary" and contains(text(),"Publish")]' ).click() self.teacher.sleep(2) # get new exercise id exerciseid = self.teacher.find_all( By.CSS_SELECTOR, ".exercise-tag")[3].get_attribute('innerHTML')[4:] # click search self.teacher.find(By.XPATH, ".//*[contains(text(),'Search')]").click() # search the exercise id self.teacher.find(By.CSS_SELECTOR, ".form-control") \ .send_keys(exerciseid) self.teacher.find(By.CSS_SELECTOR, ".btn.btn-default.load").click() # verify that the value in key term is what was inputted previously keyterm = self.teacher.find(By.CSS_SELECTOR, "#key-term") \ .get_attribute('value') assert (keyterm == 'test edit') self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162261) not in TESTS, reason='Excluded') def test_creating_multipart_question_162261(self): """ Go to exercises qa Log in as a teacher Click "Write a new exercise" Check the box that says "Exercise contains multiple parts" Fill out the required fields Click "Publish" Expected result: ***The user gets a confirmation that says "Exercise [exercise ID] has published successfully"*** Corresponding test case: T2.11 045 https://trello.com/c/8LnE8Qml/162-creating-multi-part-question """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162261' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162261'] self.ps.test_updates['passed'] = False # logging in with these credentials self.teacher.login(url=os.getenv('EXERCISES_QA'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # click create a new question self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() # click "Exercise contains multiple parts" self.teacher.find(By.CSS_SELECTOR, '#mpq-toggle').click() # write in something for question stem self.teacher.find(By.CSS_SELECTOR, '.question>div>textarea') \ .send_keys('test') # write in something for Distractor self.teacher.find(By.CSS_SELECTOR, '.correct-answer>textarea') \ .send_keys('ignore') # click tab "question 2" self.teacher.find(By.CSS_SELECTOR, '#exercise-parts-tab-question-1') \ .click() self.teacher.sleep(1) # write in something for question stem self.teacher.find_all(By.CSS_SELECTOR, '.question>div>textarea')[2].send_keys('test2') # write in something for Distractor self.teacher.find_all( By.CSS_SELECTOR, '.correct-answer>textarea')[2].send_keys('ignore2') # click save draft self.teacher.find(By.CSS_SELECTOR, '.async-button.draft.btn.btn-info').click() # click publish self.teacher.find(By.CSS_SELECTOR, '.async-button.publish.btn.btn-primary').click() self.teacher.sleep(1) # confirm publish self.teacher.find( By.XPATH, ".//*[@class='btn btn-primary' and contains(text(),'Publish')]" ).click() # confirm message appears self.teacher.find(By.CSS_SELECTOR, '.modal-body>b') self.ps.test_updates['passed'] = True
class TestImproveCourseManagement(unittest.TestCase): """T2.07 - Improve Course Management.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.admin = Admin(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities, existing_driver=self.teacher.driver) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) self.admin = None try: self.teacher.delete() except: pass # 14651 - 001 - Admin | View Student Use Statistics for Concept Coach # college assessments @pytest.mark.skipif(str(14651) not in TESTS, reason='Excluded') def test_admin_view_student_use_statistics_for_cc_college_asse_14651(self): """View Student Use Statistics for Concept Coach college assessments. Steps: Go to Tutor Click on the 'Login' button Enter the admin account in the username and password text boxes Click on the 'Sign in' button Click "Admin" in the user menu Click "Stats" Click "Concept Coach" Expected Result: The user is presented with Concept Coach statistics """ self.ps.test_updates['name'] = 't2.07.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.001', '14651'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.goto_admin_control() self.admin.sleep(5) self.admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Stats'))).click() self.admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Concept Coach'))).click() assert('/stats/concept_coach' in self.admin.current_url()), \ 'Not viewing Concept Coach stats' self.ps.test_updates['passed'] = True ''' # 14652 - 002 - Teacher | Delegate teaching tasks to supporting instructors @pytest.mark.skipif(str(14652) not in TESTS, reason='Excluded') def test_teacher_delegate_teaching_tasks_to_supporting_instruc_14652(self): """Delegate teaching tasks to supporting instructors. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.002', '14652' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True ''' ''' # 14653 - 003 - Teacher | Move a student and their data to a new section @pytest.mark.skipif(str(14653) not in TESTS, reason='Excluded') def test_teacher_move_a_student_and_their_data_to_new_section_14653(self): """Move a student and their data to a new section. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the user menu Click "Change Period" for the desired student and select a period Expected Result: Student is moved to new section with their data """ self.ps.test_updates['name'] = 't2.07.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.003', '14653' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Move the student to another period first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Change Period").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() self.teacher.sleep(5) # Verify the move, then move the student back to the original period self.teacher.find( By.XPATH, "//div[@class='roster']/div[@class='settings-section periods']" + "/ul[@class='nav nav-tabs']/li[2]/a").click() roster = self.teacher.driver.find_elements_by_xpath( "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr") index = 0 for student in roster: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Change Period")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() break index += 1 self.teacher.sleep(2) self.teacher.find( By.XPATH, "//div[@class='roster']/div[@class='settings-section periods']" + "/ul[@class='nav nav-tabs']/li[1]/a").click() roster = self.teacher.driver.find_elements_by_xpath( "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr") assert(first in roster[0].text and last in roster[0].text), \ 'error' self.ps.test_updates['passed'] = True # 14655 - 004 - Teacher | Drop a student from a section and hide their data @pytest.mark.skipif(str(14655) not in TESTS, reason='Excluded') def test_teacher_drop_student_from_section_and_hide_their_data_14655(self): """Drop a student from a section and hide their data. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the user menu Click "Drop" for the desired student Expected Result: The student appears under the "Dropped Students" section """ self.ps.test_updates['name'] = 't2.07.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.004', '14655' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find( By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Drop the student first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Drop").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-drop-student btn btn-danger']").click() self.teacher.sleep(5) # Verify the student was dropped and add back to active roster dropped = self.teacher.driver.find_elements_by_xpath( "//div[@class='settings-section dropped-students']/table[@class" + "='roster table table-striped table-bordered table-condensed " + "table-hover']/tbody/tr") index = 0 for student in dropped: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Add Back to Active Roster")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-undrop-student btn btn-success']" ).click() self.teacher.sleep(20) break index += 1 self.ps.test_updates['passed'] = True # 14656 - 005 - Teacher | Drop a student from a section and don't hide # their data @pytest.mark.skipif(str(14656) not in TESTS, reason='Excluded') def test_teacher_drop_a_student_from_section_and_dont_hide_dat_14656(self): """Drop a student from a section and don't hide their data. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 't2', 't2.07', 't2.07.005', '14656' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True ''' # 14657 - 006 - Teacher | In Student Scores dropped students are not # displayed @pytest.mark.skipif(str(14657) not in TESTS, reason='Excluded') def test_teacher_in_student_scores_dropped_students_are_not_14657(self): """In Student Scores dropped students are not displayed. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the calendar dashboard Click "Drop" for the desired student Click "Student Scores" from the user menu Click on the period from which you have dropped the student Expected Result: Dropped student should not be displayed in Student Scores """ self.ps.test_updates['name'] = 't2.07.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.006', '14657'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Drop the student first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Drop").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-drop-student btn btn-danger']").click() self.teacher.sleep(5) # Go to student scores, verify the student is not seen self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Student Scores").click() self.teacher.sleep(10) odd_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedData" + "TableRow_main public_fixedDataTableRow_even public_fixedDataTa" + "ble_bodyRow']/div[@class='fixedDataTableRowLayout_body']/div" + "[@class='fixedDataTableCellGroupLayout_cellGroupWrapper'][1]/d" + "iv[@class='fixedDataTableCellGroupLayout_cellGroup']/div[@clas" + "s='fixedDataTableCellLayout_main public_fixedDataTableCell_" + "main'][1]/div[@class='fixedDataTableCellLayout_wrap1 public_fi" + "xedDataTableCell_wrap1']/div[@class='fixedDataTableCellLayout_w" + "rap2 public_fixedDataTableCell_wrap2']/div[@class='fixedDataTab" + "leCellLayout_wrap3 public_fixedDataTableCell_wrap3']/div[@class" + "='name-cell']/a[@class='student-name public_fixedDataTableCell" + "_cellContent']") even_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedDataTab" + "leRow_main public_fixedDataTableRow_highlighted public_fixedDa" + "taTableRow_odd public_fixedDataTable_bodyRow']/div[@class='fix" + "edDataTableRowLayout_body']/div[@class='fixedDataTableCellGrou" + "pLayout_cellGroupWrapper'][1]/div[@class='fixedDataTableCellGr" + "oupLayout_cellGroup']/div[@class='fixedDataTableCellLayout_mai" + "n public_fixedDataTableCell_main'][1]/div[@class='fixedDataTab" + "leCellLayout_wrap1 public_fixedDataTableCell_wrap1']/div[@clas" + "s='fixedDataTableCellLayout_wrap2 public_fixedDataTableCell_wr" + "ap2']/div[@class='fixedDataTableCellLayout_wrap3 public_fixedD" + "ataTableCell_wrap3']/div[@class='name-cell']/a[@class='student" + "-name public_fixedDataTableCell_cellContent']") found = False for student in odd_scores: if student.text.find(first) >= 0 and student.text.find(last) >= 0: found = True break if not found: for stud in even_scores: if stud.text.find(first) >= 0 and stud.text.find(last) >= 0: found = True break # Add back to active roster self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() dropped = self.teacher.driver.find_elements_by_xpath( "//div[@class='settings-section dropped-students']/table[@class" + "='roster table table-striped table-bordered table-condensed ta" + "ble-hover']/tbody/tr") index = 0 for student in dropped: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Add Back to Active Roster")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//button[@class='-undrop-student btn btn-success']" ).click() self.teacher.sleep(20) break index += 1 if not found: self.ps.test_updates['passed'] = True # 14850 - 007 - Teacher | In Student Scores view moved students @pytest.mark.skipif(str(14850) not in TESTS, reason='Excluded') def test_teacher_in_student_scores_view_moved_students_14850(self): """In Student Scores view moved students. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" from the calendar dashboard Click "Change Period" for the desired student Click on the desired period Click "Student Scores" from the user menu Click on the period to which the student was moved Expected Result: The user is presented with the moved student under their new period """ self.ps.test_updates['name'] = 't2.07.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.007', '14850'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Move the student to another period first = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]" ).text last = self.teacher.find( By.XPATH, "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]" ).text self.teacher.find(By.PARTIAL_LINK_TEXT, "Change Period").click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() self.teacher.sleep(5) # Go to student scores, verify the student is seen self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Student Scores").click() self.teacher.sleep(10) self.teacher.find( By.XPATH, "//nav[@class='collapse in']/ul[@class='nav nav-tabs']/li[2]/a" ).click() odd_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedData" + "TableRow_main public_fixedDataTableRow_even public_fixedDataTa" + "ble_bodyRow']/div[@class='fixedDataTableRowLayout_body']/div" + "[@class='fixedDataTableCellGroupLayout_cellGroupWrapper'][1]/d" + "iv[@class='fixedDataTableCellGroupLayout_cellGroup']/div[@clas" + "s='fixedDataTableCellLayout_main public_fixedDataTableCell_" + "main'][1]/div[@class='fixedDataTableCellLayout_wrap1 public_fi" + "xedDataTableCell_wrap1']/div[@class='fixedDataTableCellLayout_w" + "rap2 public_fixedDataTableCell_wrap2']/div[@class='fixedDataTab" + "leCellLayout_wrap3 public_fixedDataTableCell_wrap3']/div[@class" + "='name-cell']/a[@class='student-name public_fixedDataTableCell" + "_cellContent']") even_scores = self.teacher.driver.find_elements_by_xpath( "//div[@class='fixedDataTableRowLayout_main public_fixedDataTab" + "leRow_main public_fixedDataTableRow_highlighted public_fixedDa" + "taTableRow_odd public_fixedDataTable_bodyRow']/div[@class='fix" + "edDataTableRowLayout_body']/div[@class='fixedDataTableCellGrou" + "pLayout_cellGroupWrapper'][1]/div[@class='fixedDataTableCellGr" + "oupLayout_cellGroup']/div[@class='fixedDataTableCellLayout_mai" + "n public_fixedDataTableCell_main'][1]/div[@class='fixedDataTab" + "leCellLayout_wrap1 public_fixedDataTableCell_wrap1']/div[@clas" + "s='fixedDataTableCellLayout_wrap2 public_fixedDataTableCell_wr" + "ap2']/div[@class='fixedDataTableCellLayout_wrap3 public_fixedD" + "ataTableCell_wrap3']/div[@class='name-cell']/a[@class='student" + "-name public_fixedDataTableCell_cellContent']") found = False for student in odd_scores: if student.text.find(first) >= 0 and student.text.find(last) >= 0: found = True break if found: for stud in even_scores: if stud.text.find(first) >= 0 and stud.text.find(last) >= 0: found = True break # Add student back to original period self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(10) self.teacher.find( By.XPATH, "//div[@class='roster']/div[@class='settings-section periods']" + "/ul[@class='nav nav-tabs']/li[2]/a").click() roster = self.teacher.driver.find_elements_by_xpath( "//div[@class='period']/table[@class='roster table table-striped" + " table-bordered table-condensed table-hover']/tbody/tr") index = 0 for student in roster: if student.text.find(first) >= 0 and student.text.find(last) >= 0: self.teacher.driver.find_elements_by_partial_link_text( "Change Period")[index].click() self.teacher.sleep(1) self.teacher.find( By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click() break index += 1 if found: self.ps.test_updates['passed'] = True # 14658 - 008 - Teacher | Require emails for all students for roster import @pytest.mark.skipif(str(14658) not in TESTS, reason='Excluded') def test_teacher_require_emails_for_all_students_for_roster_14658(self): """Require emails for all students for roster imports. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.008', '14658'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 14660 - 009 - Teacher | Set time zone for a course @pytest.mark.skipif(str(14660) not in TESTS, reason='Excluded') def test_teacher_set_time_zone_for_a_course_14660(self): """Set time zone for a course. Steps: If the user has more than one course, click on a Tutor course name Click "Course Settings and Roster" Click "Change Course Timezone" Select the desired timezone Click Save Expected Result: The time zone is set """ self.ps.test_updates['name'] = 't2.07.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.009', '14660'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='physics') self.teacher.open_user_menu() self.teacher.find(By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click() self.teacher.sleep(5) # Change the timezone self.teacher.driver.find_elements_by_xpath( "//button[@class='edit-course btn btn-link']")[1].click() self.teacher.sleep(2) self.teacher.find(By.XPATH, "//div[@class='tutor-radio']/label").click() self.teacher.find( By.XPATH, "//button[@class='async-button -edit-course-" + "confirm btn btn-default']").click() self.teacher.sleep(5) # Verify the change and change the time back to Central self.teacher.driver.find_elements_by_xpath( "//button[@class='edit-course btn btn-link']")[1].click() assert('Central Time' not in self.teacher.find( By.XPATH, "//div[@class='tutor-radio active']/label").text), \ 'Not viewing Concept Coach stats' self.teacher.sleep(2) options = self.teacher.driver.find_elements_by_xpath( "//div[@class='tutor-radio']/label") for timezone in options: if timezone.text.find('Central Time') >= 0: timezone.click() break self.teacher.find( By.XPATH, "//button[@class='async-button -edit-course-" + "confirm btn btn-default']").click() self.ps.test_updates['passed'] = True # 14661 - 010 - System | Distinguish between high school and college # courses @pytest.mark.skipif(str(14661) not in TESTS, reason='Excluded') def test_system_distinguish_between_hs_and_college_courses_14661(self): """Distinguish between high school and college courses. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.010', '14661'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True # 116648 - 011 - Admin | View the start and end dates from the # admin console course list @pytest.mark.skipif(str(116648) not in TESTS, reason='Excluded') def test_admin_view_start_end_dates_from_course_list_116648(self): """View the start and end dates from the admin console course list. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.07.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.07', 't2.07.011', '116648'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.admin.login() self.admin.goto_admin_control() self.admin.sleep(5) self.admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Course Organization'))).click() self.admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Courses'))).click() self.admin.sleep(3) self.admin.find(By.XPATH, "//div[@class='course-duration']") self.ps.test_updates['passed'] = True
class TestViewTheCalendarDashboard(unittest.TestCase): """T1.13 - View the calendar.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) else: self.teacher = Teacher( use_env_vars=True ) self.teacher.login() self.teacher.select_course(appearance='college_physics') def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) try: self.teacher.delete() except: pass # Case C7978 - 001 - Teacher | View the calendar dashboard @pytest.mark.skipif(str(7978) not in TESTS, reason='Excluded') def test_teacher_view_the_calendar_dashboard_7978(self): """View the calendar dashboard. Steps: If the user has more than one course, click on a Tutor course name Expected Result: The teacher is presented their calendar dashboard. """ self.ps.test_updates['name'] = 't1.13.001' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.001', '7978'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') assert('course' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C7979 - 002 - Teacher | View student scores using dashboard button @pytest.mark.skipif(str(7979) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_using_the_dashboard_button_7979(self): """View student scores using the dashboard button. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Student Scores' button Expected Result: The teacher is presented with the student scores """ self.ps.test_updates['name'] = 't1.13.002' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.002', '7979'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.find(By.LINK_TEXT, 'Student Scores').click() assert('scores' in self.teacher.current_url()), \ 'Not viewing student scores' self.ps.test_updates['passed'] = True # Case C7980 - 003 - Teacher | View student scores using the user menu link @pytest.mark.skipif(str(7980) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_using_the_user_menu_link_7980(self): """View student scores using the user menu link. Steps: If the user has more than one course, click on a Tutor course name Click on the user menu Click on the 'Student Scores' link Expected Result: The teacher is presented with the student scores """ self.ps.test_updates['name'] = 't1.13.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.003', '7980'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.open_user_menu() self.teacher.find(By.CLASS_NAME, 'viewScores'). \ find_element_by_tag_name('a'). \ click() assert('scores' in self.teacher.current_url()), \ 'Not viewing the student scores' self.ps.test_updates['passed'] = True # Case C7981 - 004 - Teacher | View performance forecast using the # dashboard button @pytest.mark.skipif(str(7981) not in TESTS, reason='Excluded') def test_teacher_view_performance_forecast_using_dash_button_7981(self): """View performance forecast using the dashboard button. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Performance Forecast' button on the dashboard Expected Result: The teacher is presented with the performance forecast """ self.ps.test_updates['name'] = 't1.13.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.004', '7981'] self.ps.test_updates['passed'] = False self.teacher.find(By.LINK_TEXT, 'Performance Forecast').click() self.teacher.page.wait_for_page_load() assert('guide' in self.teacher.current_url()), \ 'Not viewing the performance forecast' self.ps.test_updates['passed'] = True # Case C7982 - 005 - Teacher | View performace forecast using # the user menu link @pytest.mark.skipif(str(7982) not in TESTS, reason='Excluded') def test_teacher_view_performance_forecast_using_user_menu_link_7982(self): """View performance forecast using the user menu link. Steps: If the user has more than one course, click on a Tutor course name Click on the user menu Click on the 'Performance Forecast' link Expected Result: The teacher is presented with the performance forecast """ self.ps.test_updates['name'] = 't1.13.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.005', '7982'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.open_user_menu() self.teacher.find( By.XPATH, '//a[@data-name="viewPerformanceGuide"]' ).click() self.teacher.page.wait_for_page_load() assert('guide' in self.teacher.current_url()), \ 'Not viewing the performance forecast' self.ps.test_updates['passed'] = True # Case C7983 - 006 - Teacher | View a reading assignment summary @pytest.mark.skipif(str(7983) not in TESTS, reason='Excluded') def test_teacher_view_a_reading_assignment_summary_7983(self): """View a reading assignment summary. Steps: If the user has more than one course, click on a Tutor course name Create a reading assignment Click on the reading assignment on the calendar Expected Result: The teacher is presented with the reading assignment summary """ self.ps.test_updates['name'] = 't1.13.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.006', '7983'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') # create an assignment assignment_name = 'reading-%s' % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'reading_list': ['1.1'], 'status': 'publish', } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # Case C7984 - 007 - Teacher | View a homework assignment summary @pytest.mark.skipif(str(7984) not in TESTS, reason='Excluded') def test_teacher_view_a_homework_assignment_summary_7984(self): """View a homework assignment summary. Steps: create a homework assignment If the user has more than one course, click on a Tutor course name Click on a homework assignment on the calendar Expected Result: The teacher is presented with the homework assignment summary """ self.ps.test_updates['name'] = 't1.13.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.007', '7984'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') # create an assignment assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'problems': {'1.1': (2, 3), }, 'status': 'publish', 'feedback': 'immediate' } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # NOT DONE # Case C7985 - 008 - Teacher | View an external assignment summary @pytest.mark.skipif(str(7985) not in TESTS, reason='Excluded') def test_teacher_view_an_external_assignment_summary_7985(self): """View an external assignment summary. Steps: If the user has more than one course, click on a Tutor course name Click on an external assignment on the calendar Expected Result: The teacher is presented with the external assignment summary """ self.ps.test_updates['name'] = 't1.13.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.008', '7985'] self.ps.test_updates['passed'] = False # create an assignment assignment_name = 'external-%s' % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='external', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'url': 'google.com', 'status': 'publish' } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # Case C7986 - 009 - Teacher | View an event summary @pytest.mark.skipif(str(7986) not in TESTS, reason='Excluded') def test_teacher_view_an_event_summary_7986(self): """View an event summary. Steps: If the user has more than one course, click on a Tutor course name Click on an event on the calendar Expected Result: The teacher is presented with the event summary """ self.ps.test_updates['name'] = 't1.13.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.009', '7986'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') # create an assignment assignment_name = "homework-%s" % randint(100, 999) today = datetime.date.today() begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish' } ) # click on assignment self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name) ) ).click() # check that it opened self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//*[@class="modal-title" and ' + 'contains(text(), "%s")]' % assignment_name) ) ) self.ps.test_updates['passed'] = True # Case C7987 - 010 - Teacher | Open the refrenece book using the dashboard # button @pytest.mark.skipif(str(7987) not in TESTS, reason='Excluded') def test_teacher_open_the_reference_book_using_dashboard_button_7987(self): """Open the refrenece book using the dashboard button. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Browse The Book'button Expected Result: The teacher is preseneted with the book in a new tab """ self.ps.test_updates['name'] = 't1.13.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.010', '7987'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.driver.find_element( By.CSS_SELECTOR, '.calendar-header .view-reference-guide' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('book' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' self.ps.test_updates['passed'] = True # Case C7988 - 011 - Teacher | Open the refrenece book using user menu link @pytest.mark.skipif(str(7988) not in TESTS, reason='Excluded') def test_teacher_open_the_reference_book_using_user_menu_link_7988(self): """Open the refrenece book using the user menu link. Steps: If the user has more than one course, click on a Tutor course name Click on the user menu Click on the 'Browse the Book' link Expected Result: The teacher is presented with the book in a new tab """ self.ps.test_updates['name'] = 't1.13.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.011', '7988'] self.ps.test_updates['passed'] = False # self.teacher.select_course(title='HS Physics') self.teacher.open_user_menu() self.teacher.find( By.CSS_SELECTOR, '.calendar-header .view-reference-guide' ).click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) assert('book' in self.teacher.current_url()), \ 'Not viewing the textbook PDF' self.ps.test_updates['passed'] = True # Case C7989 - 012 - Teacher | Click on the course name to return to # the dashboard @pytest.mark.skipif(str(7989) not in TESTS, reason='Excluded') def test_teacher_click_course_name_to_return_to_the_dashboard_7989(self): """Click on the course name to return to the dashboard. Steps: If the user has more than one course, click on a Tutor course name Click on the 'Performance Forecast' button Click on the course name in the header Expected Result: The teacher is presented with their calendar dashboard """ self.ps.test_updates['name'] = 't1.13.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.012', '7989'] self.ps.test_updates['passed'] = False self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Performance Forecast' ).click() self.teacher.find( By.CLASS_NAME, 'course-name' ).click() assert('course' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True # Case C7990 - 013 - Teacher | Cick on the OpenStax logo to return to # the course picker @pytest.mark.skipif(str(7990) not in TESTS, reason='Excluded') def test_teacher_click_openstax_logo_to_return_to_course_picker_7990(self): """Cick on the OpenStax logo to return to the course picker. Steps: If the user has more than one course, click on a Tutor course name Click in the OpenStax logo in the header Expected Result: The teacher is presented with the course picker """ self.ps.test_updates['name'] = 't1.13.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.013', '7990'] self.ps.test_updates['passed'] = False # self.teacher.select_course(appearance='physics') self.teacher.find( By.CLASS_NAME, 'ui-brand-logo' ).click() assert('dashboard' in self.teacher.current_url()), \ 'Not viewing the course picker' self.ps.test_updates['passed'] = True '''
class TestIImproveQuestionManagement(unittest.TestCase): """CC2.11 - Improve Question Management.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.teacher = Teacher( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.student = Student( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) def tearDown(self): """Test destructor.""" self.ps.update_job( job_id=str(self.teacher.driver.session_id), **self.ps.test_updates ) self.student = None try: self.teacher.delete() except: pass # 14851 - 001 - Teacher | Review all questions @pytest.mark.skipif(str(14851) not in TESTS, reason='Excluded') def test_teacher_review_all_questions_14851(self): """Review all questions. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Expected Result: The user is presented with all the questions for the section or chapter """ self.ps.test_updates['name'] = 'cc2.11.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.001', '14851'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Question Library' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.1"]' ).click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find( By.XPATH, '//button[text()="Show Questions"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]') ) ) self.ps.test_updates['passed'] = True # 14852 - 002 - Teacher | Exclude certain questions @pytest.mark.skipif(str(14852) not in TESTS, reason='Excluded') def test_teacher_exclude_certain_questions_14852(self): """Exclude certain quesitons. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Hover over the desired question and click "Exclude question" Expected Result: Question is grayed out """ self.ps.test_updates['name'] = 'cc2.11.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.002', '14852'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Question Library' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]' ).click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find( By.XPATH, '//button[text()="Show Questions"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]') ) ) self.teacher.sleep(1) i = 1 question = None # loop finding a question that is not yet excleded # there are 9 question in the exact textbook and chpater this test # is searching. limiting loop at 7 incase questions are removed. while i < 8: question = self.teacher.find( By.XPATH, '//div[@class="exercises"]/div[' + str(i) + ']' ) if ('is-selected' not in question.get_attribute('class')): break i += 1 Assignment.scroll_to(self.teacher.driver, question) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(question) # way to stall because not sure how to add wait in action chain for _ in range(50): actions.move_by_offset(-1, 0) actions.click() actions.move_by_offset(-50, -300) actions.perform() self.teacher.sleep(0.5) question_excluded = self.teacher.find( By.XPATH, '//div[@class="exercises"]/div[' + str(i) + ']' ).get_attribute('class') assert('is-selected' in question_excluded), 'question not excluded' self.ps.test_updates['passed'] = True # 14855 - 003 - Teacher | Pin tabs on top of screen when scrolled @pytest.mark.skipif(str(14855) not in TESTS, reason='Excluded') def test_teacher_pin_tabs_on_top_of_screen_when_scrolled_14855(self): """Pin tabs on top of screen when scrolled. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Scroll down Expected Result: Tabs are pinned to top of the screen when scrolled """ self.ps.test_updates['name'] = 'cc2.11.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.003', '14855'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Question Library' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]' ).click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find( By.XPATH, '//button[text()="Show Questions"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]') ) ) self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="pinned-header"]') ) ) self.ps.test_updates['passed'] = True # 14856 - 004 - Teacher | Make section links jumpable @pytest.mark.skipif(str(14856) not in TESTS, reason='Excluded') def test_teacher_make_section_links_jumpable_14856(self): """Make section links jumpable. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Click on the section links at the top of the screen Expected Result: The screen scrolls to the selected questions """ self.ps.test_updates['name'] = 'cc2.11.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.004', '14856'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Question Library' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.1"]' ).click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find( By.XPATH, '//button[text()="Show Questions"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]') ) ) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="pinned-header"]' '//div[@class="section" and text()="1.2"]') ) ).click() self.teacher.sleep(1) # click the heading as simple way to find that it is on screen # and not just visible but scrolled off screen self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercise-sections"]' + '//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]') ) ).click() self.ps.test_updates['passed'] = True # 14858 - 005 - Teacher | Report errata about assessments in Concept Coach @pytest.mark.skipif(str(14858) not in TESTS, reason='Excluded') def test_teacher_report_errata_about_assessments_in_cc_14858(self): """Report errata about assessments in Concept Coach. Steps: If the user has more than one course, click on a CC course name Click "Question Library" from the user menu Select a section or chapter Click "Show Questions" Hover over the desired question and click "Question details" Click "Report an error" Expected Result: A new tab with the assessment errata form appears, with the assessment ID already filled in """ self.ps.test_updates['name'] = 'cc2.11.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.005', '14858'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.find( By.XPATH, '//a[contains(@href,"/cc-dashboard")]' ).click() self.teacher.open_user_menu() self.teacher.find( By.LINK_TEXT, 'Question Library' ).click() self.teacher.find( By.XPATH, '//div[@class="section"]//span[@class="chapter-section" ' + 'and @data-chapter-section="1.2"]' ).click() self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.find( By.XPATH, '//button[text()="Show Questions"]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="exercises"]') ) ) self.teacher.sleep(1) question = self.teacher.find( By.XPATH, '//div[@class="exercises"]/div[1]' ) actions = ActionChains(self.teacher.driver) actions.move_to_element(question) # way to stall because not sure how to add wait in action chain for _ in range(50): actions.move_by_offset(1, 0) actions.click() actions.perform() self.teacher.sleep(0.5) exercise_id = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="exercise-tag" and contains(text(),"ID:")]') ) ).text question = self.teacher.find( By.XPATH, '//div[@class="action report-error"]' ).click() window_with_form = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_form) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[text()="Report Content Errors"]') ) ) self.teacher.find( By.XPATH, '//input[@value="' + exercise_id[4:] + '"]') self.ps.test_updates['passed'] = True # 14859 - 006 - Student | Report errata about assessments in Concept Coach @pytest.mark.skipif(str(14859) not in TESTS, reason='Excluded') def test_student_report_errata_about_assessments_in_cc_14859(self): """Report errata about assessments in Concept Coach. Steps: Click on a CC course, if there are more than one Click on a non-introductory section Click "Jump to Concept Coach" Click "Launch Concept Coach" Click "Report an error" on an assessment Expected Result: A new tab with the assessment errata form appears, with the assessment ID already filled in """ self.ps.test_updates['name'] = 'cc2.11.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.006', '14859'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # raise NotImplementedError(inspect.currentframe().f_code.co_name) self.student.login() self.teacher.find( By.XPATH, '//a[contains(@href,"cnx.org/contents/")]' ).click() # get to non-into section self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button//span[text()="Contents"]') ) ).click() self.student.sleep(0.5) self.student.wait.until( expect.element_to_be_clickable( (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]') ) ).click() # open concept coach self.student.wait.until( expect.element_to_be_clickable( (By.LINK_TEXT, 'Jump to Concept Coach') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[text()="Launch Concept Coach"]') ) ).click() self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class,"core breadcrumb-exercise")]') ) ).click() exercise_id = self.student.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="exercise-identifier-link"]' + '/span[contains(text(),"@")]') ) ).text self.teacher.find(By.LINK_TEXT, 'Report an error').click() window_with_form = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_form) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[text()="Report Content Errors"]') ) ) self.teacher.find( By.XPATH, '//input[@value="' + exercise_id + '"]') self.ps.test_updates['passed'] = True
class TestImprovesScoresReporting(unittest.TestCase): """CC2.08 - Improves Scores Reporting.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.teacher = Teacher(use_env_vars=True) self.teacher.login() self.teacher.find(By.XPATH, '//a[contains(@href,"/cc-dashboard")]').click() def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass # 14806 - 001 - Teacher | View student scores as percent complete @pytest.mark.skipif(str(14806) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_as_percent_complete_14806(self): """View student scores as percent complete. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click on the icon in the progress column Expected Result: Student Scores are presented as percent complete """ self.ps.test_updates['name'] = 'cc2.08.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.001', '14806'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find(By.XPATH, '//button[contains(text(),"percentage")]').click() self.teacher.find( By.XPATH, '//div[contains(@class,"score")]//a[contains(text(),"%")]') self.ps.test_updates['passed'] = True # 14807 - 002 - Teacher | View student scores as number of total @pytest.mark.skipif(str(14807) not in TESTS, reason='Excluded') def test_teacher_view_student_scores_as_number_of_total_14807(self): """View student scores as number of total. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Number" Expected Result: Student Scores are presented as "Number of Total" """ self.ps.test_updates['name'] = 'cc2.08.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.002', '14807'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find(By.XPATH, '//button[contains(text(),"number")]').click() self.teacher.find( By.XPATH, '//div[contains(@class,"score")]//a[contains(text()," of ")]') self.ps.test_updates['passed'] = True # 14808 - 003 - Teacher | View tooltips on hover @pytest.mark.skipif(str(14808) not in TESTS, reason='Excluded') def test_teacher_view_tooltips_on_hover_14808(self): """View tooltips on hover. Steps: If the user has more than one course, click on a CC course name Hover over the info icons Expected Result: The user is presented with tooltips """ self.ps.test_updates['name'] = 'cc2.08.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.003', '14808'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find(By.XPATH, '//i[@type="info-circle"]').click() self.teacher.find( By.XPATH, '//h3[@class="popover-title" and ' + 'contains(text(), "Class and Overall Averages")]') self.ps.test_updates['passed'] = True # 14810 - 004 - Teacher | Sort student scores based on score @pytest.mark.skipif(str(14810) not in TESTS, reason='Excluded') def test_teacher_sort_student_scores_based_on_score_14810(self): """Sort student scores based on score. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Score" for the desired assignment Expected Result: Students are sorted based on score """ self.ps.test_updates['name'] = 'cc2.08.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.004', '14810'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find( By.XPATH, '//div[contains(@class,"sortable")]//div[text()="Score"]').click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-descending")]//div[text()="Score"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-ascending")]//div[text()="Score"]') self.ps.test_updates['passed'] = True # 14811 - 005 - Teacher | Sort student scores based on number complete @pytest.mark.skipif(str(14811) not in TESTS, reason='Excluded') def test_teacher_sort_student_scores_based_on_number_completed_14811(self): """Sort student scores based on number complete. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Progress" for the desired assignment Expected Result: Students are sorted based on number completed """ self.ps.test_updates['name'] = 'cc2.08.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.005', '14811'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find( By.XPATH, '//div[contains(@class,"sortable")]//div[text()="Progress"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-descending")]//div[text()="Progress"]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[contains(@class,"is-ascending")]//div[text()="Progress"]') self.ps.test_updates['passed'] = True # 14668 - 006 - Teacher | All popups in the roster have an X button @pytest.mark.skipif(str(14668) not in TESTS, reason='Excluded') def test_teacher_all_popups_in_the_roster_have_an_x_button_14668(self): """All popups in the roster have an X button. Steps: If the user has more than one course, click on a CC course name Click "Course Settings and Roster" from the user menu Click "Rename Course," "Change Course Timezone," "View Archived Period," "Add Period," "Rename," and "Get Student Enrollment Code" Expected Result: All pop ups have an X button """ self.ps.test_updates['name'] = 'cc2.08.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.006', '14668'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.find(By.XPATH, '//a[text()="Course Settings and Roster"]').click() self.teacher.sleep(1) # rename couse self.teacher.find( By.XPATH, '//button//span[contains(text(),"Rename Course")]').click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]').click() self.teacher.sleep(0.75) # course timezone self.teacher.find( By.XPATH, '//button//span[contains(text(),"Change Course Timezone")]').click( ) self.teacher.sleep(1) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]').click() self.teacher.sleep(0.75) # add period/section self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button').click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]').click() self.teacher.sleep(0.75) # rename period self.teacher.find( By.XPATH, '//span[contains(@class,"rename-period")]//button').click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]').click() self.teacher.sleep(0.75) # student enrollemnt code self.teacher.find( By.XPATH, '//button//span[contains(text(),"Your student enrollment code")]' ).click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]').click() self.teacher.sleep(0.75) # View Archived periods self.teacher.find( By.XPATH, '//button//span[contains(text(),"View Archived ")]').click() self.teacher.sleep(0.75) self.teacher.find( By.XPATH, '//div[@class="modal-content"]//button[@class="close"]').click() self.ps.test_updates['passed'] = True # 14670 - 007 - Teacher | Close popup with X button @pytest.mark.skipif(str(14670) not in TESTS, reason='Excluded') def test_teacher_close_popup_with_x_button_14670(self): """Close popup with X button. Steps: If the user has more than one course, click on a CC course name Click "Course Settings and Roster" from the user menu Click ONE of the following: * Rename Course * Change Course Timezone * View Archived Period * Add Period * Rename * Get Student Enrollment Code Click the X on the pop up Expected Result: Popup is closed """ self.ps.test_updates['name'] = 'cc2.08.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.007', '14670'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.open_user_menu() self.teacher.find(By.XPATH, '//a[text()="Course Settings and Roster"]').click() self.teacher.sleep(1) # rename couse self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button//span[contains(text(),"Rename Course")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ))).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find(By.XPATH, '//div[@class="modal-content"]') # course timezone self.teacher.find( By.XPATH, '//button//span[contains(text(),"Change Course Timezone")]').click( ) self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ))).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find(By.XPATH, '//div[@class="modal-content"]') # add period/section self.teacher.find( By.XPATH, '//div[contains(@class,"add-period")]//button').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ))).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find(By.XPATH, '//div[@class="modal-content"]') # rename period self.teacher.find( By.XPATH, '//span[contains(@class,"rename-period")]//button').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ))).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find(By.XPATH, '//div[@class="modal-content"]') # student enrollemnt code self.teacher.find( By.XPATH, '//button//span[contains(text(),"Your student enrollment code")]' ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ))).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find(By.XPATH, '//div[@class="modal-content"]') # View Archived Periods self.teacher.find( By.XPATH, '//button//span[contains(text(),"View Archived")]').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="modal-content"]//button[@class="close"]' ))).click() self.teacher.sleep(1) with self.assertRaises(NoSuchElementException): self.teacher.find(By.XPATH, '//div[@class="modal-content"]') self.ps.test_updates['passed'] = True # 14669 - 008 - Teacher | The icon in the progress column shows info on # percentage complete, attempted out of total possible questions, and # the date last worked @pytest.mark.skipif(str(14669) not in TESTS, reason='Excluded') def test_teacher_the_icon_in_the_progress_column_shows_info_14669(self): """The icon in the progress column shows info. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click on the icon in the progress column for a completed assignment Expected Result: Shows information on percentage complete, attempted out of total possible questions as well as the date last worked """ self.ps.test_updates['name'] = 'cc2.08.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.008', '14669'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) icon = self.teacher.find( By.XPATH, '//span[contains(@aria-describedby,"scores-cell-info-popover")]') actions = ActionChains(self.teacher.driver) actions.move_to_element(icon) actions.perform() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@id,"scores-cell-info-popover")]'))).click() # more on each individial thing self.ps.test_updates['passed'] = True ''' # 14812 - 009 - Teacher | Import CC Student Scores export into an LMS @pytest.mark.skipif(str(14812) not in TESTS, reason='Excluded') def test_teacher_import_cc_student_scores_export_into_an_lms_14812(self): """Import CC student scores export into an LMS. Steps: Expected Result: """ self.ps.test_updates['name'] = 'cc2.08.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.009', '14812'] self.ps.test_updates['passed'] = False # Test steps and verification assertions raise NotImplementedError(inspect.currentframe().f_code.co_name) self.ps.test_updates['passed'] = True ''' # 14813 - 010 - Teacher | View zeros in exported scores instead of blank # cells for incomplete assignments @pytest.mark.skipif(str(14813) not in TESTS, reason='Excluded') def test_teacher_view_zeros_in_exported_scores_instead_of_blan_14813(self): """View zeros in exported scores for incomplete assignments. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores" Click "Export" Open the excel file Expected Result: For incomplete assignments or assignments that are not started, there are zeros instead of blank cells """ self.ps.test_updates['name'] = 'cc2.08.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.010', '14813'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find(By.XPATH, '//div[@class="export-button"]//button').click() # wait until button return and no longer is loading self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[@class="export-button"]//button' + '/span[text()="Export"]'))) self.teacher.sleep(2) coursename = self.teacher.find(By.XPATH, '//div[@class="course-name"]').text coursename = coursename.replace(' ', '_') + "_Scores" home = os.getenv("HOME") files = os.listdir(home + '/Downloads') file_name = '' for i in range(len(files)): if (coursename in files[i]) and (files[i][-5:] == '.xlsx'): file_name = files[i] break else: if i == len(files) - 1: raise Exception period = self.teacher.find( By.XPATH, '//span[contains(@class,"tab-item-period-name")]').text wb = load_workbook(str(home + '/Downloads/' + file_name)) sheet = wb[period + ' - %'] rows = sheet.rows start_row = float("inf") for i in range(len(sheet.rows)): if rows[i][0].value == 'First Name': start_row = i if i >= start_row: if rows[i][4].value == 0: # found that 0% is being used istead of blanks break elif rows[i + 1][4].value is None: print('empty cell instead of 0%') raise Exception self.ps.test_updates['passed'] = True # 14814 - 011 - Teacher | Green check icon is displayed for completed # assignments @pytest.mark.skipif(str(14814) not in TESTS, reason='Excluded') def test_teacher_green_check_icon_is_displayed_for_completed_14814(self): """Green check icon is displayed for completed assignments. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores Expected Result: Green check icon is displayed for completed assignments """ self.ps.test_updates['name'] = 'cc2.08.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.011', '14814'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) # scroll to find a green checkmark assignments = self.teacher.find_all( By.XPATH, "//span[contains(@aria-describedby,'header-cell-title')]") for i in range(len(assignments) // 4): try: self.teacher.find( By.XPATH, '//span[contains(@class,"trig")]' + '//*[contains(@class,"finished")]') break except (NoSuchElementException, ElementNotVisibleException): if i >= (len(assignments) // 4) - 1: print("completed assignments for this period") raise Exception # try to drag scroll bar instead of scrolling scroll_bar = self.teacher.find( By.XPATH, '//div[contains(@class,"ScrollbarLayout_faceHorizontal")]') actions = ActionChains(self.teacher.driver) actions.move_to_element(scroll_bar) actions.click_and_hold() actions.move_by_offset(50, 0) actions.release() actions.perform() self.ps.test_updates['passed'] = True ''' # 14815 - 012 - Teacher | The class average info icon displays a definition # about scores from completed assignments @pytest.mark.skipif(str(14815) not in TESTS, reason='Excluded') def test_teacher_class_average_info_icon_displays_definition_14815(self): """The class average info icon displays a definition. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores Click on the info icon next to "Class Average" Expected Result: The class average info icon displays a definition about scores from completed assignments """ self.ps.test_updates['name'] = 'cc2.08.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.012', '14815'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]') ) ) self.teacher.find( By.XPATH, '//i[@type="info-circle"]').click() self.teacher.find( By.XPATH, '//h3[@class="popover-title" and ' + 'contains(text(), "Class and Overall Averages")]') self.ps.test_updates['passed'] = True ''' # 14816 - 013 - Teacher | View the overall score column @pytest.mark.skipif(str(14816) not in TESTS, reason='Excluded') def test_teacher_view_the_overall_score_column_14816(self): """View the overall score column. Steps: If the user has more than one course, click on a CC course name Click "View Detailed Scores Expected Result: User is presented with the overall score column next to student names """ self.ps.test_updates['name'] = 'cc2.08.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.013', '14816'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"View Detailed Scores")]'))).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"Student Scores")]'))) self.teacher.find(By.XPATH, '//div[contains(@class,"overall-header-cell")]') self.ps.test_updates['passed'] = True
class TestTeacherLoginAndAuthentification(unittest.TestCase): """CC1.11 - Teacher Login and Authentification.""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.teacher = Teacher(use_env_vars=True) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass # Case C7688 - 001 - Teacher | Log into Concept Coach @pytest.mark.skipif(str(7688) not in TESTS, reason='Excluded') def test_teacher_log_into_concept_coach_7688(self): """Log into Concept Coach. Steps: Go to Tutor Click on the 'Login' button Enter the teacher user account in the username and password text boxes Click on the 'Sign in' button If the user has more than one course, click on a CC course name Expected Result: User is taken to the class dashboard. """ self.ps.test_updates['name'] = 'cc1.11.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.11', 'cc1.11.001', '7688'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Log in'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'login_username_or_email').send_keys( self.teacher.username) self.teacher.find(By.CSS_SELECTOR, '.primary').click() self.teacher.find(By.ID, 'login_password').send_keys(self.teacher.password) self.teacher.find(By.CSS_SELECTOR, '.primary').click() self.teacher.page.wait_for_page_load() # check if a password change is required if 'reset your password' in self.teacher.driver.page_source.lower(): try: self.teacher.find(By.ID, 'set_password_password') \ .send_keys(self.teacher.password) self.teacher.find( By.ID, 'set_password_password_confirmation') \ .send_keys(self.teacher.password) self.teacher.find(By.CSS_SELECTOR, '.primary').click() self.teacher.sleep(1) self.teacher.find(By.CSS_SELECTOR, '.primary').click() except Exception as e: raise e self.teacher.page.wait_for_page_load() source = self.teacher.driver.page_source.lower() print('Reached Terms/Privacy') while 'terms of use' in source or 'privacy policy' in source: self.teacher.accept_contract() self.teacher.page.wait_for_page_load() source = self.teacher.driver.page_source.lower() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.teacher.driver.find_element( By.XPATH, '//p[contains(text(),"OpenStax Concept Coach")]').click() self.teacher.driver.find_element(By.XPATH, '//span[text()="Class Dashboard"]') self.ps.test_updates['passed'] = True # Case C7689 - 002 - Teacher | Logging out returns to the Concept Coach # landing page @pytest.mark.skipif(str(7689) not in TESTS, reason='Excluded') def test_teacher_logging_out_returns_to_concept_coach_landing_p_7689(self): """Logging out returns to the Concept Coach landing page. Steps: Click the user menu containing the user's name Click the 'Log Out' button Expected Result: User is taken to cc.openstax.org """ self.ps.test_updates['name'] = 'cc1.11.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.11', 'cc1.11.002', '7689'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.driver.find_element( By.XPATH, '//p[contains(text(),"OpenStax Concept Coach")]').click() self.teacher.open_user_menu() self.teacher.sleep(1) self.teacher.find(By.XPATH, "//a//input[@value='Log out']").click() assert('cc.openstax.org' in self.teacher.current_url()), \ 'Not viewing the calendar dashboard' self.ps.test_updates['passed'] = True '''