class TestViewClassScores(unittest.TestCase): """T1.23 - View Class Scores.""" 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.wait = WebDriverWait(self.teacher.driver, Assignment.WAIT_TIME) 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 @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded') def test_homework_assignment_from_scores(self): ''' Go to https://tutor-qa.openstax.org/ Click on the 'Login' button Enter the teacher user account [ teacher01 | password ] 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 the "Student Scores" button Click on the tab for the chosen period Click on the "Review" button under the selected homework assignment. ***Displays students progress on chosen assignment for selected period, actual questions, and question results. (T1.23.13)*** ***Period tabs are displayed. (t1.23.18)*** ***Each question has a correct response displayed (t1.23.21)*** ***Assessment pane shows interleaved class stats (t1.23.23)*** ***Screen is moved down to selected section of homework. (t1.23.17)*** Click "Back to Scores" button Click on score cell for chosen student and homework assignment (student must have started the hw) Click on a breadcrumb of selected section of homework. ***Teacher view of student work shown. Teacher can go through different questions with either the "Next Question" button, or breadcrumbs. Students answers are shown for questions they have worked. (t1.23.25)*** Expected Results: Corresponds to... t1.23. 13,17,18,21,23,25 ''' # go to Student Scores self.teacher.select_course( appearance='college_physics' ) # might have to change the course appearance self.teacher.goto_student_scores() # self.teacher.find( # By.LINK_TEXT, 'Student Scores').click() # self.teacher.wait.until( # expect.visibility_of_element_located( # (By.XPATH, '//span[contains(text(), "Student Scores")]') # ) # ).click() ### UNNECESSARY CODE COMMENTED? ^ #(t1.23.13 --> Displays students progress on chosen assignment for # selected period, actual questions, and question results. # go to the Review Metrics of a HW by clicking 'Review' self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class, "tab-item-period-name")]'))).click() bar = 0 scroll_width = 1 scroll_total_size = 1 # scroll bar might not be there try: scroll_bar = self.teacher.find( By.XPATH, '//div[contains(@class,"ScrollbarLayout_faceHorizontal")]') scroll_width = scroll_bar.size['width'] scroll_total_size = self.teacher.find( By.XPATH, '//div[contains(@class,"ScrollbarLayout_mainHorizontal")]' ).size['width'] bar = scroll_width except: pass while (bar < scroll_total_size): try: self.teacher.find( By.XPATH, '//span[@class="review-link"]' + '//a[contains(text(),"Review")]').click() assert ('metrics' in self.teacher.current_url()), \ 'Not viewing homework assignment summary' break except: bar += scroll_width if scroll_total_size <= bar: print("No HWs for this class :(") raise Exception # drag scroll bar instead of scrolling actions = ActionChains(self.teacher.driver) actions.move_to_element(scroll_bar) actions.click_and_hold() actions.move_by_offset(scroll_width, 0) actions.release() actions.perform() # (t1.23.18) --> Period tabs are displayed. self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//ul[contains(@role,"tablist")]' + '//span[contains(@class,"tab-item-period-name")]'))) # (t1.23.21) --> Each question has a correct response displayed correct_answers = self.teacher.driver.find_elements( By.XPATH, '//div[contains(@class,"answer-correct")]') questions = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]') assert (len(correct_answers) == len(questions)), \ "number of correct answers not equal to the number of questions" # (t1.23.23) --> Assessment pane shows interleaved class stats (t1.23.23) ### PRETTY SURE T1.23.23 IS ALREADY COVERED # (t1.23.17) --> Screen is moved down to selected section of homework. (t1.23.17) sections = self.teacher.driver.find_elements( By.XPATH, '//span[contains(@class,"breadcrumbs")]') sections[-1].click() self.teacher.sleep(2) assert (expect.visibility_of_element_located( (By.XPATH, "//div[contains(@data-section,'%s')]" % str(len(sections) - 1)))) # (t1.23.25) --> Teacher view of student work shown. Teacher can go through different # questions with either the "Next Question" button, or breadcrumbs. # Students answers are shown for questions they have worked. (t1.23.25)*** ### GOT UP TO HERE ON TESTING! SUBSEQUENT CODE MIGHT NOT WORK # go back to student scores self.teacher.find(By.XPATH, '//span[contains(@title,"Menu")]').click() self.teacher.find(By.LINK_TEXT, 'Student Scores').click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(), "Student Scores")]'))).click() # look for a student that's worked a homework # click on their score to review the homework while (bar < scroll_total_size): try: self.teacher.find( By.XPATH, "//div[contains(@class,'score')]//a[@data-assignment-type='homework']" ).click() break # except (NoSuchElementException, # ElementNotVisibleException, # WebDriverException) except: bar += scroll_width if scroll_total_size <= bar: print("No worked HWs for this class :(") raise Exception # drag scroll bar instead of scrolling actions = ActionChains(self.teacher.driver) actions.move_to_element(scroll_bar) actions.click_and_hold() actions.move_by_offset(scroll_width, 0) actions.release() actions.perform() # make sure that we're reviewing the hw assert ('step' in self.teacher.current_url()), \ 'Not viewing student work for homework' self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class,"breadcrumbs")]'))) sections = self.teacher.find_all( By.XPATH, '//span[contains(@class,"breadcrumbs")]') section = sections[-1] section.click() chapter = section.get_attribute("data-chapter") assert (self.teacher.driver.find_element( By.XPATH, '//span[contains(text(),"' + chapter + '")]').is_displayed()), \ 'chapter not displayed'
class TestStaxingTutorTeacher(unittest.TestCase): """Staxing case tests for Teacher.""" book_sections = None class_start_end_dates = None def setUp(self): """Pretest settings.""" self.teacher = Teacher(use_env_vars=True, driver_type=DRIVER) self.teacher.username = os.getenv('TEACHER_USER_MULTI', self.teacher.username) self.teacher.set_window_size(height=700, width=1200) self.teacher.login() courses = self.teacher.get_course_list() if len(courses) < 1: raise ValueError('No course available for selection') course = courses[randint(0, len(courses) - 1)] self.teacher.select_course(title=course.get_attribute('data-title')) if not self.__class__.book_sections: self.__class__.book_sections = self.teacher.get_book_sections() if not self.__class__.class_start_end_dates: self.__class__.class_start_end_dates = \ self.teacher.get_course_begin_end() self.book_sections = self.__class__.book_sections self.start_end = self.__class__.class_start_end_dates def tearDown(self): """Test destructor.""" try: self.teacher.delete() except Exception: pass @pytest.mark.skipif(str(301) not in TESTS, reason='Excluded') def test_add_reading_assignment_individual_publish_301(self): """Build reading assignments. Type: reading Sections: individualized Action: publish """ assignment_title = 'Reading-%s' % Assignment.rword(5) left_delta = randint(0, 20) left = datetime.date.today() + datetime.timedelta(left_delta) start_date_1 = self.teacher.date_string(day_delta=left_delta) start_date_2 = self.teacher.date_string(day_delta=left_delta + 1) start_date_3 = self.teacher.date_string(day_delta=left_delta + 2) start_date_4 = self.teacher.date_string(day_delta=left_delta + 3) if not self.teacher.date_is_valid(left): start_date_1 = (self.class_start_end_dates[0]) \ .strftime('%m/%d/%Y') start_date_2 = \ (self.class_start_end_dates[0] + datetime.timedelta(1)) \ .strftime('%m/%d/%Y') start_date_3 = \ (self.class_start_end_dates[0] + datetime.timedelta(2)) \ .strftime('%m/%d/%Y') start_date_4 = \ (self.class_start_end_dates[0] + datetime.timedelta(3)) \ .strftime('%m/%d/%Y') right_delta = left_delta + randint(1, 10) right = datetime.date.today() + datetime.timedelta(right_delta) end_date_1 = self.teacher.date_string(day_delta=right_delta) end_date_2 = self.teacher.date_string(day_delta=right_delta + 1) end_date_3 = self.teacher.date_string(day_delta=right_delta + 2) end_date_4 = self.teacher.date_string(day_delta=right_delta + 3) if not self.teacher.date_is_valid(right): end_date_1 = \ (self.class_start_end_dates[1] - datetime.timedelta(3)) \ .strftime('%m/%d/%Y') end_date_2 = \ (self.class_start_end_dates[1] - datetime.timedelta(2)) \ .strftime('%m/%d/%Y') end_date_3 = \ (self.class_start_end_dates[1] - datetime.timedelta(1)) \ .strftime('%m/%d/%Y') end_date_4 = \ (self.class_start_end_dates[1]) \ .strftime('%m/%d/%Y') print('Left: %s Right: %s' % (left, right)) start_time_2 = '6:30 am' end_time_2 = '11:59 pm' reading_start = randint(0, (len(self.book_sections) - 1)) reading_end = reading_start + randint(1, 5) reading_list = self.book_sections[reading_start:reading_end] sections = self.teacher.get_course_sections() assign_sections = {} if len(sections) >= 1 and sections[0]: assign_sections[sections[0]] = (start_date_1, end_date_1) if len(sections) >= 2 and sections[1]: assign_sections[sections[1]] = ((start_date_2, start_time_2), (end_date_2, end_time_2)) if len(sections) >= 3 and sections[2]: assign_sections[sections[2]] = (start_date_3, end_date_3) if len(sections) >= 4 and sections[3]: assign_sections[sections[3]] = (start_date_4, end_date_4) for number, section in enumerate(sections): assign_sections[section] = ((start_date_1, start_time_2), (end_date_1, end_time_2)) self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - individual periods - ' + 'publish', 'periods': assign_sections, 'reading_list': reading_list, 'status': 'publish', 'break_point': None, }) assert('course' in self.teacher.current_url()), \ 'Not at dashboard' print(self.teacher.current_url()) self.teacher.rotate_calendar(end_date_1) reading = self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) time.sleep(5.0) assert (reading), '%s not publishing on %s' % (assignment_title, end_date_1) @pytest.mark.skipif(str(302) not in TESTS, reason='Excluded') def test_add_reading_assignment_all_publish_302(self): """Build reading assignments.""" # Reading, all periods, publish assignment_title = 'Reading-%s' % Assignment.rword(5) left_delta = randint(0, 20) left = datetime.date.today() + datetime.timedelta(left_delta) # start_date_1 = self.teacher.date_string(day_delta=left_delta) start_date_2 = self.teacher.date_string(day_delta=left_delta + 1) if not self.teacher.date_is_valid(left): # start_date_1 = \ # (self.class_start_end_dates[0]) \ # .strftime('%m/%d/%Y') start_date_2 = \ (self.class_start_end_dates[0] + datetime.timedelta(1)) \ .strftime('%m/%d/%Y') right_delta = left_delta + randint(1, 10) right = datetime.date.today() + datetime.timedelta(right_delta) end_date_1 = self.teacher.date_string(day_delta=right_delta) end_date_2 = self.teacher.date_string(day_delta=right_delta + 1) if not self.teacher.date_is_valid(right): end_date_1 = \ (self.class_start_end_dates[1] - datetime.timedelta(2)) \ .strftime('%m/%d/%Y') end_date_2 = \ (self.class_start_end_dates[1] - datetime.timedelta(1)) \ .strftime('%m/%d/%Y') print('Left: %s Right: %s' % (left, right)) # self.book_sections = self.teacher.get_book_sections() reading_start = randint(0, (len(self.book_sections) - 1)) reading_end = reading_start + randint(1, 5) reading_list = self.book_sections[reading_start:reading_end] self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - all periods - publish', 'periods': { # '1st': (start_date_1, end_date_1), 'all': (start_date_2, end_date_2), }, 'reading_list': reading_list, 'status': 'publish', 'break_point': None, }) assert('course' in self.teacher.current_url()), \ 'Not at dashboard' time.sleep(2.0) self.teacher.rotate_calendar(end_date_1) reading = self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) time.sleep(5.0) assert (reading), '%s not publishing on %s' % (assignment_title, end_date_2) @pytest.mark.skipif(str(303) not in TESTS, reason='Excluded') def test_add_reading_assignment_individual_draft_303(self): """Build reading assignments.""" # Reading, individual periods, draft assignment_title = 'Reading-%s' % Assignment.rword(5) left_delta = randint(0, 20) left = datetime.date.today() + datetime.timedelta(left_delta) '''start_date_1 = self.teacher.date_string(day_delta=left_delta) start_date_2 = self.teacher.date_string(day_delta=left_delta + 1) start_date_3 = self.teacher.date_string(day_delta=left_delta + 2) if not self.teacher.date_is_valid(left): start_date_1 = \ (self.class_start_end_dates[0]).strftime('%m/%d/%Y') start_date_2 = \ (self.class_start_end_dates[0] + datetime.timedelta(1)) \ .strftime('%m/%d/%Y') start_date_3 = \ (self.class_start_end_dates[0] + datetime.timedelta(2)) \ .strftime('%m/%d/%Y')''' right_delta = left_delta + randint(1, 10) right = datetime.date.today() + datetime.timedelta(right_delta) end_date_1 = self.teacher.date_string(day_delta=right_delta) # end_date_2 = self.teacher.date_string(day_delta=right_delta + 1) end_date_3 = self.teacher.date_string(day_delta=right_delta + 2) if not self.teacher.date_is_valid(right): end_date_1 = \ (self.class_start_end_dates[1] - datetime.timedelta(2)) \ .strftime('%m/%d/%Y') # end_date_2 = \ # (self.class_start_end_dates[1] - datetime.timedelta(1)) \ # .strftime('%m/%d/%Y') end_date_3 = \ (self.class_start_end_dates[1]) \ .strftime('%m/%d/%Y') print('Left: %s Right: %s' % (left, right)) # self.book_sections = self.teacher.get_book_sections() reading_start = randint(0, (len(self.book_sections) - 1)) reading_end = reading_start + randint(1, 5) reading_list = self.book_sections[reading_start:reading_end] sections = self.teacher.get_course_sections() periods = {} for index, section in enumerate(sections): periods[section] = \ (self.teacher.date_string(day_delta=left_delta + index), self.teacher.date_string(day_delta=right_delta + index)) self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - individual periods ' + '- draft', 'periods': periods, 'reading_list': reading_list, 'status': 'draft', 'break_point': None, }) assert('course' in self.teacher.current_url()), \ 'Not at dashboard' self.teacher.rotate_calendar(end_date_1) reading = self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) time.sleep(5.0) assert (reading), '%s not publishing on %s' % (assignment_title, end_date_3) @pytest.mark.skipif(str(304) not in TESTS, reason='Excluded') def test_add_reading_assignment_all_draft_304(self): """Build reading assignments.""" # Reading, all periods, draft assignment_title = 'Reading-%s' % Assignment.rword(5) left_delta = randint(0, 20) left = datetime.date.today() + datetime.timedelta(left_delta) start_date_1 = self.teacher.date_string(day_delta=left_delta) if not self.teacher.date_is_valid(left): start_date_1 = \ (self.class_start_end_dates[0]) \ .strftime('%m/%d/%Y') right_delta = left_delta + randint(1, 10) right = datetime.date.today() + datetime.timedelta(right_delta) end_date_1 = self.teacher.date_string(day_delta=right_delta) if not self.teacher.date_is_valid(right): end_date_1 = \ (self.class_start_end_dates[1] - datetime.timedelta(2)) \ .strftime('%m/%d/%Y') print('Left: %s Right: %s' % (left, right)) # self.book_sections = self.teacher.get_book_sections() reading_start = randint(0, (len(self.book_sections) - 1)) reading_end = reading_start + randint(1, 5) reading_list = self.book_sections[reading_start:reading_end] self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - all periods - draft', 'periods': { 'all': (start_date_1, end_date_1), }, 'reading_list': reading_list, 'status': 'draft', 'break_point': None, }) assert('course' in self.teacher.current_url()), \ 'Not at dashboard' self.teacher.rotate_calendar(end_date_1) reading = self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) time.sleep(5.0) assert (reading), '%s not publishing on %s' % (assignment_title, end_date_1) @pytest.mark.skipif(str(305) not in TESTS, reason='Excluded') def test_add_reading_assignment_one_cancel_305(self): """Build reading assignments.""" # Reading, one period, cancel assignment_title = 'Reading-%s' % Assignment.rword(5) left_delta = randint(0, 20) left = datetime.date.today() + datetime.timedelta(left_delta) start_date_1 = self.teacher.date_string(day_delta=left_delta) if not self.teacher.date_is_valid(left): start_date_1 = \ (self.class_start_end_dates[0]) \ .strftime('%m/%d/%Y') right_delta = left_delta + randint(1, 10) right = datetime.date.today() + datetime.timedelta(right_delta) end_date_1 = self.teacher.date_string(day_delta=right_delta) if not self.teacher.date_is_valid(right): end_date_1 = \ (self.class_start_end_dates[1] - datetime.timedelta(2)) \ .strftime('%m/%d/%Y') print('Left: %s Right: %s' % (left, right)) # self.book_sections = self.teacher.get_book_sections() reading_start = randint(0, (len(self.book_sections) - 1)) reading_end = reading_start + randint(1, 5) reading_list = self.book_sections[reading_start:reading_end] sections = self.teacher.get_course_sections() if not isinstance(sections, list): sections = [sections] self.teacher.add_assignment(assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - cancel', 'periods': { sections[0]: (start_date_1, end_date_1), }, 'reading_list': reading_list, 'status': 'cancel', 'break_point': None, }) assert('course' in self.teacher.current_url()), \ 'Not at dashboard' self.teacher.rotate_calendar(end_date_1) time.sleep(5.0) with pytest.raises(NoSuchElementException): self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) @pytest.mark.skipif(str(306) not in TESTS, reason='Excluded') def test_change_assignment_306(self): """No test placeholder.""" pass @pytest.mark.skipif(str(307) not in TESTS, reason='Excluded') def test_delete_assignment_307(self): """No test placeholder.""" assignment_title = 'Reading-%s' % Assignment.rword(5) left_delta = randint(0, 20) left = datetime.date.today() + datetime.timedelta(left_delta) start_date = self.teacher.date_string(day_delta=left_delta) if not self.teacher.date_is_valid(left): start_date = \ (self.class_start_end_dates[0]) \ .strftime('%m/%d/%Y') right_delta = left_delta + randint(1, 10) right = datetime.date.today() + datetime.timedelta(right_delta) end_date = self.teacher.date_string(day_delta=right_delta) if not self.teacher.date_is_valid(right): end_date = \ (self.class_start_end_dates[1] - datetime.timedelta(2)) \ .strftime('%m/%d/%Y') self.teacher.add_assignment(assignment='reading', args={ 'title': assignment_title, 'periods': { 'all': (start_date, end_date), }, 'reading_list': ['1', '1.1'], 'status': 'publish', 'break_point': None, }) assert('course' in self.teacher.current_url()), \ 'Not at dashboard' self.teacher.rotate_calendar(end_date) reading = self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) print('Waiting for publish') time.sleep(5.0) assert(reading), \ '%s not publishing on %s' % (assignment_title, end_date) self.teacher.delete_assignment(assignment='reading', args={ 'title': assignment_title, 'periods': { 'all': (start_date, end_date), }, }) self.teacher.rotate_calendar(end_date) time.sleep(5.0) try: self.teacher.find(By.XPATH, '//label[text()="%s"]' % assignment_title) assert (False), '%s still exists' % assignment_title except Exception: pass @pytest.mark.skipif(str(308) not in TESTS, reason='Excluded') def test_goto_menu_item_308(self): """No test placeholder.""" pass @pytest.mark.skipif(str(309) not in TESTS, reason='Excluded') def test_goto_calendar_309(self): """No test placeholder.""" pass @pytest.mark.skipif(str(310) not in TESTS, reason='Excluded') def test_goto_performance_forecast_310(self): """No test placeholder.""" self.teacher.goto_performance_forecast() @pytest.mark.skipif(str(311) not in TESTS, reason='Excluded') def test_goto_student_scores_311(self): """No test placeholder.""" self.teacher.goto_student_scores() @pytest.mark.skipif(str(312) not in TESTS, reason='Excluded') def test_goto_course_roster_312(self): """No test placeholder.""" self.teacher.goto_course_roster() @pytest.mark.skipif(str(313) not in TESTS, reason='Excluded') def test_goto_course_settings_313(self): """No test placeholder.""" self.teacher.goto_course_settings() @pytest.mark.skipif(str(314) not in TESTS, reason='Excluded') def test_add_course_section_314(self): """Add a course section to a class.""" section_name = 'New Section' self.teacher.add_course_section(section_name) classes = self.teacher.find_all(By.CSS_SELECTOR, 'a[role*="tab"]') section_names = [] for section in classes: section_names.append(section.get_attribute('innerHTML')) assert(section_name in section_names), \ '%s not in %s' % (section_name, section_names) self.teacher.goto_course_settings() self.teacher.find @pytest.mark.skipif(str(315) not in TESTS, reason='Excluded') def test_get_enrollment_code_315(self): """No test placeholder.""" code = self.teacher.get_enrollment_code() assert('enroll' in code and re.search('\d{6}', code) is not None), \ '%s is not the correct enrollment URL' % code @pytest.mark.skipif(str(316) not in TESTS, reason='Excluded') def test_teacher_handle_modals_316(self): self.teacher.enable_debug_mode() self.teacher.close_beta_windows() time.sleep(3) assert ("modal closed")