class TestStaxingTutorTeacher(unittest.TestCase): """Staxing case tests.""" def setUp(self): """Pretest settings.""" self.teacher = Teacher(use_env_vars=True) self.teacher.username = os.getenv('TEACHER_USER_MULTI', self.teacher.username) self.teacher.set_window_size(height=700, width=1200) self.teacher.login() self.teacher.select_course(title='High School Physics') def tearDown(self): """Test destructor.""" try: self.teacher.driver.quit() except: pass @pytest.mark.skipif(str(301) not in TESTS, reason='Excluded') def test_add_reading_assignment_individual_publish(self): """Build reading assignments.""" # Reading, individual periods, publish assignment_title = 'Reading-%s' % Assignment.rword(5) left = randint(5, 20) right = left + randint(1, 10) start_date_1 = self.teacher.date_string(day_delta=left) end_date_1 = self.teacher.date_string(day_delta=left + right) start_date_2 = self.teacher.date_string(day_delta=left + 1) end_date_2 = self.teacher.date_string(day_delta=left + right + 1) start_time_2 = '6:30 am' end_time_2 = '11:59 pm' start_date_3 = self.teacher.date_string(day_delta=left + 2) end_date_3 = self.teacher.date_string(day_delta=left + right + 2) reading_options = self.teacher.get_book_sections() reading_start = randint(0, (len(reading_options) - 1)) reading_end = reading_start + randint(1, 5) reading_list = reading_options[reading_start:reading_end] self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - individual periods - ' + 'publish', 'periods': { 'First': (start_date_1, end_date_1), 'Second': ((start_date_2, start_time_2), (end_date_2, end_time_2)), 'Third': (start_date_3, end_date_3), }, 'reading_list': reading_list, 'status': 'publish', 'break_point': None, } ) assert('courses' 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(302) not in TESTS, reason='Excluded') def test_add_reading_assignment_all_publish(self): """Build reading assignments.""" # Reading, all periods, publish assignment_title = 'Reading-%s' % Assignment.rword(5) left = randint(5, 20) right = left + randint(1, 10) start_date_1 = self.teacher.date_string(day_delta=left) end_date_1 = self.teacher.date_string(day_delta=left + right) start_date_2 = self.teacher.date_string(day_delta=left + 1) end_date_2 = self.teacher.date_string(day_delta=left + right + 1) reading_options = self.teacher.get_book_sections() reading_start = randint(0, (len(reading_options) - 1)) reading_end = reading_start + randint(1, 5) reading_list = reading_options[reading_start:reading_end] self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - all periods - publish', 'periods': { 'First': (start_date_1, end_date_1), 'all': (start_date_2, end_date_2), }, 'reading_list': reading_list, 'status': 'publish', 'break_point': None, } ) assert('courses' 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_2) @pytest.mark.skipif(str(303) not in TESTS, reason='Excluded') def test_add_reading_assignment_individual_draft(self): """Build reading assignments.""" # Reading, individual periods, draft assignment_title = 'Reading-%s' % Assignment.rword(5) left = randint(5, 20) right = left + randint(1, 10) start_date_1 = self.teacher.date_string(day_delta=left) end_date_1 = self.teacher.date_string(day_delta=left + right) start_date_2 = self.teacher.date_string(day_delta=left + 1) end_date_2 = self.teacher.date_string(day_delta=left + right + 1) start_date_3 = self.teacher.date_string(day_delta=left + 2) end_date_3 = self.teacher.date_string(day_delta=left + right + 2) reading_options = self.teacher.get_book_sections() reading_start = randint(0, (len(reading_options) - 1)) reading_end = reading_start + randint(1, 5) reading_list = reading_options[reading_start:reading_end] self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - individual periods ' + '- draft', 'periods': { 'First': (start_date_1, end_date_1), 'Second': (start_date_2, end_date_2), 'Third': (start_date_3, end_date_3), }, 'reading_list': reading_list, 'status': 'draft', 'break_point': None, } ) assert('courses' 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(self): """Build reading assignments.""" # Reading, all periods, draft assignment_title = 'Reading-%s' % Assignment.rword(5) left = randint(5, 20) right = left + randint(1, 10) start_date_1 = self.teacher.date_string(day_delta=left) end_date_1 = self.teacher.date_string(day_delta=left + right) reading_options = self.teacher.get_book_sections() reading_start = randint(0, (len(reading_options) - 1)) reading_end = reading_start + randint(1, 5) reading_list = reading_options[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('courses' 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(self): """Build reading assignments.""" # Reading, one period, cancel assignment_title = 'Reading-%s' % Assignment.rword(5) left = randint(5, 20) right = left + randint(1, 10) start_date_1 = self.teacher.date_string(day_delta=left) end_date_1 = self.teacher.date_string(day_delta=left + right) reading_options = self.teacher.get_book_sections() reading_start = randint(0, (len(reading_options) - 1)) reading_end = reading_start + randint(1, 5) reading_list = reading_options[reading_start:reading_end] self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'description': 'Staxing test reading - cancel', 'periods': { 'First': (start_date_1, end_date_1), }, 'reading_list': reading_list, 'status': 'cancel', 'break_point': None, } ) assert('courses' 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(self): """No test placeholder.""" pass @pytest.mark.skipif(str(307) not in TESTS, reason='Excluded') def test_delete_assignment(self): """No test placeholder.""" assignment_title = 'Reading-%s' % Assignment.rword(5) start_date = self.teacher.date_string(day_delta=1) end_date = self.teacher.date_string(day_delta=3) self.teacher.add_assignment( assignment='reading', args={ 'title': assignment_title, 'periods': { 'all': (start_date, end_date), }, 'reading_list': ['1', '1.1'], 'status': 'draft', 'break_point': None, } ) assert('courses' 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 ) time.sleep(5.0) assert(reading), \ '%s not publishing on %s' % (assignment_title, end_date) new_date = start_date.split('/') new_date = '%s/%s' % (int(new_date[0]), int(new_date[1])) self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//label[@data-title="%s" and @data-opens-at="%s"]' % (assignment_title, new_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) with pytest.raises(NoSuchElementException): self.teacher.find( By.XPATH, '//label[text()="%s"]' % assignment_title ) @pytest.mark.skipif(str(308) not in TESTS, reason='Excluded') def test_goto_menu_item(self): """No test placeholder.""" pass @pytest.mark.skipif(str(309) not in TESTS, reason='Excluded') def test_goto_calendar(self): """No test placeholder.""" pass @pytest.mark.skipif(str(310) not in TESTS, reason='Excluded') def test_goto_performance_forecast(self): """No test placeholder.""" pass @pytest.mark.skipif(str(311) not in TESTS, reason='Excluded') def test_goto_student_scores(self): """No test placeholder.""" pass @pytest.mark.skipif(str(312) not in TESTS, reason='Excluded') def test_goto_course_roster(self): """No test placeholder.""" pass @pytest.mark.skipif(str(313) not in TESTS, reason='Excluded') def test_goto_course_settings(self): """No test placeholder.""" pass @pytest.mark.skipif(str(314) not in TESTS, reason='Excluded') def test_add_course_section(self): """No test placeholder.""" pass @pytest.mark.skipif(str(315) not in TESTS, reason='Excluded') def test_get_enrollment_code(self): """No test placeholder.""" pass
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 TestWorkAHomework(unittest.TestCase): """""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.student = Student(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.teacher = Teacher(existing_driver=self.student.driver, use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.student = Student(use_env_vars=True) self.teacher = Teacher(use_env_vars=True, existing_driver=self.student.driver) self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.student.driver.session_id), **self.ps.test_updates) self.teacher = None try: self.student.delete() except: pass @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded') def test_working_hw(self): ''' Go to https://tutor-qa.openstax.org/ Login with the account If the user has more than one course, select a Tutor course Click on a homework assignment on the list dashboard ***The user is presented with the first question of the homework assignment (t1.71.01)*** Hover the cursor over the information icon in right corner of the footer ***The user is presented with the assignment description/instructions (t1.71.02)*** [Navigate through the questions sequentially using the breadcrumbs until a free response question is found] Enter a free response into the free response text box ***The Answer button is activated (t1.71.04)*** ***The user is presented with the next question when clicking the breadcrumb(t1.71.03)*** Click on another breadcrumb to get to the next assessment Click back to the original assessment ***The free response on the original assessment is saved (t1.71.08)*** Click 'Answer' (which should be activated) ***A free response answer is submitted and multiple choice is shown (t1.71.05)*** Select a multiple choice answer ***The Submit button is activated (t1.71.06)*** Click on the next breadcrumb to get to the next assessment Click back to the original assessment ***The multiple choice answer on the original assessment is saved (t1.71.09)*** Click "Submit" ***A multiple choice answer is submitted (t1.71.07)*** Click on the course name in the left corner of the header OR Click "Dashboard" in the user menu ***The user returns to dashboard and the assignment progress shows the number of questions answered (t1.71.10)*** Click on the same homework assignment Change a multiple choice answer on an assessment ***The button in the lower left corner says "Saving" with a loading circle A multiple choice answer is changed on an assessment (t1.71.12)*** Continue answering all assessments ***The user is presented with the completion report at the end of the assignment (t1.71.11,14)*** ***A homework may have a Spaced Practice assessment toward the end (t1.71.16)*** ***A homework may have a Personalized assessment toward the end (t1.71.17)*** Click "Back To Dashboard" ***The user is returned to the dashboard (t1.71.13)*** ***The user is returned to the dashboard and the completed homework shows X/X answered in the dashboard progress column (t1.71.15)*** Expected Results: Corresponds to t1.71 01 --> 15 :return: ''' # t1.71.01 --> The user is presented with the first question of the # homework assignment self.teacher.login() target_course = self.teacher.find( By.XPATH, "//div[contains(@data-title,'College Physics with Courseware')" "and not(contains(@data-title,'Debshila'))]") # for reference later as student course_number = target_course.get_attribute('data-course-id') target_course.click() # IMPORTANT -- get the course number of the course that you're in --> # this will let you identify the course later (in case there's any # similarly-named courses) today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=3)).strftime('%m/%d/%Y') # non-immediate feedback assignment_name = 'hw no.{0}: {1}'.format(str(randint(0, 100)), str(today)) self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"calendar-header")]'))) self.teacher.add_assignment( assignment='homework', # CHANGED THIS TOO args={ 'title': assignment_name, 'description': 'description', 'periods': { 'all': (begin, end) }, 'status': 'publish', 'problems': { '1.1': 5 } }) # check add_assignment() method for information on structuring of args # NOTE: exercises hard-coded to chapter 1.1 only --> might cause # problems self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//*[contains(@data-title,"%s")]' % assignment_name))) self.teacher.logout() assert('https://tutor-qa.openstax.org' in self.teacher.current_url()),\ 'NOT BACK AT TUTOR HOMEPAGE' self.student.login() self.wait.until( expect.element_to_be_clickable( (By.XPATH, "//div[contains(@data-course-id,%s)]" % course_number))).click() assert(course_number in self.student.current_url()),\ "Not at the desired course %s page!" % course_number homework = self.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[contains(text(),"%s")]' % assignment_name))) self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', homework) self.student.driver.execute_script('window.scrollBy(0, -80);') homework.click() self.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[contains(@class,"question-stem")]'))) assert('task' in self.student.current_url()),\ "Not currently working %s!" % assignment_name # t1.71.02 --> The user is presented with the assignment # description/instructions self.student.driver.execute_script('window.scrollBy(0, -80);') icon = self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"homework")]' + '//button[contains(@class,"task-details")]' ))) # check that task-details icon is there ActionChains(self.student.driver).move_to_element(icon).perform() self.student.driver.find_element( By.XPATH, '//div[contains(@id,"task-details-popover")]') # when hovering over the icon, a popover should come up # t1.71.03 --> The user is presented with the next question when # clicking the breadcrumb self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]'))) sections = self.student.driver.find_elements( By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]') count = 0 # by default it starts at the first exercises sections[count + 1].click() self.student.driver.find_element( By.XPATH, '//div[@data-question-number="%s"]' % str(count + 2)) self.student.sleep(1) sections[count].click() # t1.71.04 # sections is a list of all the breadcrumbs in the homework answer_text = 'hello' while (True): try: element = self.student.driver.find_element( By.TAG_NAME, 'textarea') for i in answer_text: element.send_keys(i) answer_btn = self.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"btn-primary")]'))) if answer_btn.get_attribute("disabled") is None: # if the answer button is activated, then you can move on break except: count += 1 if count >= len(sections): print('no questions in this homework with free response') raise Exception sections[count].click() # t1.71.08 --> The free response on the original assessment is saved # currently this test might not always work if count == len(sections) - 1: increment = -1 else: increment = 1 # because of a bug that doesn't allow saving when navigating to review # questions ### print('count', count) sections[count + increment].click() self.student.sleep(1) sections[count].click() self.student.driver.find_element( By.XPATH, '//textarea[text()= "%s"]' % answer_text) # t1.71.05 --> A free response answer is submitted and multiple choice # is shown self.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"btn-primary")]'))).click() # this should answer the free response question # print('about to get multiple choice') # WHAT DO WE DO IF WE DON'T GET TO A FREE CHOICE QUESTION UNTIL WE'RE # AT THE LAST QUESTION? mc_choices = self.wait.until( expect.presence_of_all_elements_located( (By.XPATH, '//div[contains(@class,"answers-answer")]'))) # print('got list of all multiple choice') # gives list of all the possible multiple choice options answer_ind = 0 # we are by default picking the first option mc_choices[answer_ind].click() # gives list of all the possible multiple choice options print(mc_choices[answer_ind].get_attribute('class')) children = mc_choices[answer_ind].find_elements(By.XPATH, './/label') print(len(children)) print(children[0].get_attribute('class')) # t1.71.09 --> The multiple choice answer on the original assessment is # saved check that multiple choice answer saved sections[count + increment].click() sections[count].click() mc_choices = self.wait.until( expect.presence_of_all_elements_located( (By.XPATH, '//div[contains(@class,"answers-answer")]'))) # mc_choices reassigned to get rid of stale elements curr_choice_status = mc_choices[answer_ind].get_attribute('class') assert('answer-checked' in curr_choice_status),\ 'Selected answer was not saved upon navigating breadcrumbs' # checking that the answer that we selected is registered as checked # t1.71.06 --> The Submit button is activated print('got here') self.student.driver.execute_script('window.scrollBy(0, -150);') submit_btn = self.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"continue btn")]'))) # t1.71.07 --> A multiple choice answer is submitted submit_btn.click() self.student.driver.find_element( By.XPATH, '//div[@data-question-number="%s"]' % str(count + 2)) # next element will be two more than the offset index of the current # problem # t1.71.10 --> The user returns to dashboard and the assignment # progress shows the number of questions answered # WHERE IS THIS GONNA START? WILL IT START AFTER THE FIRST QUESTION? # VERIFY THAT ALL THE TESTS BEFORE THIS END ON THE FIRST QUESTION # DOES THIS TEST RUN ANY RISK OF OVERSHOOTING? # AS FOR T1.71.16, HOW DO YOU VERIFY THAT THE REVIEW QUESTIONS COMES stop_point = len(sections) // 2 print('stop point', stop_point) sections[0].click() self.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[contains(@class,"question-stem")]'))) for q in range(stop_point): try: # if the question is two part must answer free response to get # to mc element = self.student.driver.find_element( By.TAG_NAME, 'textarea') answer_text = "hello" for i in answer_text: element.send_keys(i) self.wait.until( expect.visibility_of_element_located(( By.XPATH, '//button[contains(@class,"continue btn")]'))).click() except: pass # answer the multiple choice portion self.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[contains(@class,"question-stem")]'))) mc_answer = self.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[contains(@class,"answer-letter")]'))) print('THis is the choice' + mc_answer.text) print('this section' + str(q)) # self.student.driver.execute_script('window.scrollBy(0, 0);') # Assignment.scroll_to(self.student.driver, mc_answer) self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', mc_answer) mc_answer.click() # pass in the case that the answer is already selected self.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"continue btn")]' ))).click() # click to submit # curr_question_num = int(self.student.find( # By.XPATH,"//div[contains(@class,'openstax-question')]" # ).get_attribute("data-question-number") # ) # assert(curr_question_num == stop_point),Not # NOT SURE IF WE NEED THIS ASSERT POINT HERE --> asserts that current # question number is at the stop point curr_question_num = self.wait.until( expect.presence_of_element_located( (By.CSS_SELECTOR, '.openstax-question'))).get_attribute('data-question-number') assert(str(stop_point+1) in curr_question_num),\ 'Not on the question after the designated stop point' self.wait.until( expect.presence_of_element_located( (By.XPATH, '//a[contains(@class,"course-name")]'))).click() # brings you back to the class page # T1.71.11 --> The user is presented with the completion report at the # end of the assignment # Verify the assignment progress changed. # - this is supposed to answer all the questions # test that partial completion report does show on the course home locator = '//div[contains(text(),"%s")]/..//span' % assignment_name print('locator,' + locator) partial_complete = self.wait.until( expect.presence_of_element_located((By.XPATH, locator))) assert("%s/%s" % (str(stop_point), str(len(sections) - 1)) in partial_complete.text), \ "Partial completion report doesn't show" # NOTE: /.. designates the parent of an element homework = partial_complete.find_elements(By.XPATH, '/..') print(homework.get_attribute('class') + "HERE") self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', homework) self.student.driver.execute_script('window.scrollBy(0, -80);') homework.click() # click on the breadcrumb start from the beginning # this is so this test can be independent of the partial completion one sections = self.wait.until( expect.presence_of_all_elements_located( (By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]'))) sections[0].click() for q in range(len(sections)): try: # if the question is two part must answer free response to get # to mc element = self.student.driver.find_element( By.TAG_NAME, 'textarea') answer_text = "hello" for i in answer_text: element.send_keys(i) self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button/span[contains(text(),"Answer")]'))).click() except: pass if 'end' in \ sections[q] \ .find_element(By.XPATH, '//i') \ .get_attribute('class'): pass # answer the multiple choice portion self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"question-stem")]'))) element = self.student.driver.find_element( By.XPATH, '//div[@class="answer-letter"]') self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', element) self.student.driver.execute_script('window.scrollBy(0, -150);') element.click() self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button/span[contains(text(),"Submit")]'))).click() self.student.driver.find_element( By.XPATH, '//div[contains(@class,"completed-message")]') self.student.driver.find_element( By.XPATH, '//h1[contains(text(),"You are done")]') # t1.71.12 --> The button in the lower left corner says "Saving" with a # loading circle and A multiple choice answer is changed on an # assessment (t1.71.12)*** # this is expected to change a multiple choice question # that has already been answered self.student.driver.execute_script('window.scrollTo(0,0)') self.student.driver.find_element( By.XPATH, '//div[contains(@class,"course-name")]').click() homework = self.student.driver.find_element( By.XPATH, '//div[contains(@class,"homework") and ' + 'not(contains(@class,"deleted"))]' + '//i[contains(@class,"icon-homework")]') self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', homework) self.student.driver.execute_script('window.scrollBy(0, -80);') homework.click() # reanswer mc portion self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"question-stem")]'))) element = self.student.driver.find_element( By.XPATH, '//div[contains(@class,"answers-answer") and ' + 'not(contains(@class,"checked"))]') self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', element) self.student.driver.execute_script('window.scrollBy(0, -150);') element.click() self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button/span[contains(text(),"Submit")]'))).click() # t1.71.14 -->The user is presented with the completion report at the # end of the assignment (same as t1.71.11) # Completed homework shows "You are done" in the completion report self.student.find(By.XPATH, "//div[@class='completed-message']") # t1.71.17 -->A homework may have a Personalized assessment toward the # end # FOR PERSONALIZED LOOK UNDER PERFORMANCE FORECAST --> WEAKEST SUBJECTS # T1.71.16 --> A homework may have a Spaced Practice assessment toward # the end # ACCOUNTS NEED MORE HISTORY FOR THESE --> MAYBE WORK THROUGH A COUPLE # ASSIGNMNETS FOR THESE # HOW CAN YOU MAKE SURE THAT THIS STARTS WHERE YOU LEFT OFF FROM AND # ANSWERS FULLY THROUGH? # MAYBE USE A WHILE LOOP? # HOW DO YOU CHECK FOR REVIEW ASSIGNMENT? # t1.71.13 --> The user is returned to the dashboard self.student.driver.find_element( By.XPATH, '//div[contains(@class,"completed-message")]') self.student.driver.find_element( By.XPATH, "//a[contains(text(),'Back to Dashboard')]").click() self.student.find(By.XPATH, "//div[contains(text(),'This Week')]") # t1.71.15 --> The user is returned to the dashboard and the completed # homework # shows X/X answered in the dashboard progress column (t1.71.15) self.student.driver.find_element( By.XPATH, '//div[contains(@class,"homework") and ' + 'not(contains(@class,"deleted"))]' + '//span[contains(text(),"%s/%s answered")]' % (len(sections) - 1, len(sections) - 1))
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 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 TestWorkAHomework(unittest.TestCase): def setUp(self): """Pretest settings.""" if not LOCAL_RUN: self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.student = Student(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) self.teacher = Teacher(existing_driver=self.student.driver, use_env_vars=True, 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.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.student.driver.session_id), **self.ps.test_updates) self.teacher = None try: self.student.delete() except: pass def teacher_make_late_assignment(self, assignment_type="homework", course_title=None, course_no="394", assignment_name=None): """ Expects that you're starting from the teacher dashboard Uses: datetime, time.strftime Makes a late assignment --> usually due within a very short period of time from when it was made :param hw_name: (str) --> name that we're gonna give the assignment :param assignment_type: (str) --> type of assignment we want to make (options: homework, reading, external, event) :param course_title: (str) --> identifier for the course :param :return: """ # Navigate to course if course_title is None: # if no specific course has been specified open_course_xpath = "//div[contains(@data-course-id,%s)]" % \ course_no else: current_term = current_tutor_term() course_title = course_title.lower() open_course_xpath = '//div[contains(@data-appearance,"{0}") and ' \ 'contains(@data-term,"{1}")]//a'.format( course_title, current_term ) # we do the above in order to ensure that the course is open right now target_course = self.teacher.find(By.XPATH, open_course_xpath) # for reference later as student course_number = target_course.get_attribute('data-course-id') print(course_number) target_course.click() # today_date = date.today() begin = (today_date + timedelta(days=0)).strftime('%m/%d/%Y') # begin and end dates will be the same if assignment_type.lower() == 'reading': heading = 'Read' if assignment_type.lower() == 'homework': heading = 'HW' if assignment_type.lower() == 'external': heading = 'Ext' if assignment_type.lower() == 'event': heading = 'Event' if assignment_name is None: assignment_name = '{0} no.{1}: {2}'.format(heading, str(randint(0, 100)), str(today_date)) # create assignment new_due_time = get_new_set_time(60) begin_tuple = (begin, "1201am") end_tuple = (begin, new_due_time) # PROBLEM --> for some reason, the begin tuples are correct and give # today's date # but during the add assignment page, the begin date is set as tomorrow self.teacher.add_assignment(assignment=assignment_type, args={ 'title': assignment_name, 'description': 'description', 'periods': { 'all': (begin_tuple, end_tuple) }, 'status': 'publish', 'problems': { 'ch1': 5 }, 'feedback': 'non-immediate' }) @pytest.mark.skipif(str(2) not in TESTS, reason='Excluded') def test_late_homework(self): """ Go to https://tutor-qa.openstax.org/ Login with student account If the user has more than one course, select a Tutor course Click on the "All Past Work" tab on the dashboard Click on a homework assignment Expected Result ***The user starts a late homework assignment (t1.71.18)*** Enter a free response into the free response text box Click "Answer" Select a multiple choice answer Click "Submit" *** A multiple choice answer is submitted (t1.71.19)*** *** answer feedback is presented (t1.71.20) *** *** Correctness for a completed assessment is displayed in the breadcrumbs (t1.71.21)*** Corresponds to... t1.71.18 --> 21 """ self.teacher.login() course_number = str(160) self.teacher_make_late_assignment(assignment_type='homework', course_no=course_number) self.teacher.logout() # THE STUDENT PART --> self.student.login() # t1.71.18 --> The user starts a late homework assignment try: late_icon = self.student.find(By.XPATH, "//i[contains(@class,'info late')]") late_icon.click() # should direct you to homework except: self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//a[contains(text(),"All Past Work")]'))).click() homework = self.student.driver.find_element( By.XPATH, '//div[contains(@aria-hidden,"false")]' + '//div[contains(@class,"homework") and ' + 'not(contains(@class,"deleted"))]' + '//span[contains(text(),"0/")]') self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', homework) homework.click() # t1.71.20 --> A multiple choice answer is submitted and answer # feedback is presented try: # if the question is two part must answer free response to get mc text_box = self.student.find(By.TAG_NAME, 'textarea') self.teacher.driver.execute_script( "arguments[0].scrollIntoView(true);", text_box) answer_text = "hello" for i in answer_text: text_box.send_keys(i) self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"continue")]'))).click() except: pass mc_choice = self.student.find(By.XPATH, '//div[@class="answer-letter"]') self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', mc_choice) self.student.driver.execute_script('window.scrollBy(0, -150);') mc_choice.click() self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"continue")]'))).click() try: # this is looking for question feedback -- though not all questions # might have self.student.find( By.XPATH, '//div[contains(@class,"question-feedback-content")]') except: correct_answer = self.student.find( By.XPATH, "//div[contains(@class,'disabled answer-correct')]") print(correct_answer) # t1.71.21 --> Correctness for a completed assessment is displayed in # the breadcrumbs self.student.driver.find_element( By.XPATH, '//span[contains(@class,"breadcrumb")]' + '//i[contains(@class,"correct") or contains(@class,"incorrect")]') # t1.71.19 --> A multiple choice answer is submitted self.student.driver.find_element( By.XPATH, '//button/span[contains(text(),"Next Question")]')
class TestCreateAReading(unittest.TestCase): """T1.14 - Create a Reading.""" 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 C162172 001 Teacher | Add a new open event for all periods @pytest.mark.skipif(str(162172) not in TESTS, reason="Excluded") def test_teacher_add_a_new_open_event_all_periods_162172(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162172'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_001_%d' % (randint(100, 999)) assignment = Assignment() # Open Add Reading page self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add event screen' # Find and fill in title self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'reading-title') ) ).send_keys(assignment_name) # Fill in description self.teacher.find( By.XPATH, '//textarea[contains(@class, "form-control")]' ).send_keys('description') # Set date today = datetime.date.today() end = randint(1, 5) opens_on = today.strftime( '%m/%d/%Y') # make the start date today so it will be open closes_on = (today + datetime.timedelta(days=end)) \ .strftime('%m/%d/%Y') assignment.assign_periods( self.teacher.driver, {'all': (opens_on, closes_on)}) # publish self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"-publish")]') ) ).click() try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) self.ps.test_updates['passed'] = True # Case C162173 002 Teacher | Save a draft for individual periods @pytest.mark.skipif(str(162173) not in TESTS, reason="Excluded") def test_teacher_save_a_draft_event_for_individual_periods_162173(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162173'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_002_%d' % (randint(100, 999)) assignment = Assignment() # Open Add Reading page self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add readings screen' # Find and fill in title self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'reading-title') ) ).send_keys(assignment_name) # Set date today = datetime.date.today() start = randint(0, 6) end = start + randint(1, 5) opens_on = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') closes_on = (today + datetime.timedelta(days=end)) \ .strftime('%m/%d/%Y') # Find all individual periods self.teacher.find(By.ID, 'show-periods-radio').click() period_boxes = self.teacher.driver.find_elements( By.XPATH, '//input[contains(@id, "period-toggle-period")]' ) period_assignment = {} for period in period_boxes: period_assignment[ self.teacher.driver.find_element( By.XPATH, '//label[contains(@for, "%s")]' % period.get_attribute( 'id')).text ] = (opens_on, closes_on) assignment.assign_periods(self.teacher.driver, period_assignment) # Save as draft self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'builder-draft-button') ) ).click() # Check if the draft is on the dashboard try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) self.ps.test_updates['passed'] = True # Case C162174 003 Teacher | Create and publish a new unopened assignment from calendar @pytest.mark.skipif(str(162174) not in TESTS, reason="Excluded") def test_teacher_create_and_publish_new_unopened_event_from_calendar_162174(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162174'] self.ps.test_updates['passed'] = False # Test steps and verification assertions calendar_date = self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//div[contains(@class,"Day--upcoming")]') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', calendar_date ) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(calendar_date) actions.move_by_offset(0, -35) actions.click() actions.move_by_offset(30, 105) actions.click() actions.perform() assert ('event/new' in self.teacher.current_url()), \ 'not at Add Event page' assignment_name = 'event_003_%d' % (randint(100, 999)) assignment = Assignment() # Find and fill in title self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'reading-title') ) ).send_keys(assignment_name) # Fill in description self.teacher.find( By.XPATH, '//div[contains(@class,"assignment-description")]' + '//textarea[contains(@class,"form-control")]' ).send_keys('description') # or change it to span .assignment-description > .form-control # Set date today = datetime.date.today() start = randint(1, 5) end = start + randint(1, 5) # the open date should be in the future for the assignment to be unopened opens_on = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') closes_on = (today + datetime.timedelta(days=end)) \ .strftime('%m/%d/%Y') assignment.assign_periods( self.teacher.driver, {'all': (opens_on, closes_on)}) # Publish self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class, "-publish")]') ) ).click() try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name)) self.ps.test_updates['passed'] = True # Case C162175 004 Teacher | Publish a draft event @pytest.mark.skipif(str(162175) not in TESTS, reason="Excluded") def test_teacher_publish_a_draft_event_162175(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162175'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_004_%s' % randint(100, 999) today = datetime.date.today() start = randint(0, 6) finish = start + randint(1, 5) begin = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() # Publish the draft assignment self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"-publish")]') ) ).click() try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ) self.ps.test_updates['passed'] = True # Case C162176 005 Teacher | Cancel a new event before making changes @pytest.mark.skipif(str(162176) not in TESTS, reason="Excluded") def test_teacher_cancel_a_new_event_before_changes_162176(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162176'] self.ps.test_updates['passed'] = False # Open "Add Event" page self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add event screen' # Cancel a reading with "Cancel" button self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'builder-cancel-button') ) ).click() assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling event' # Open "Add Event" page self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add event screen' # Cancel an event with "X" button self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"openstax-close-x")]') ) ).click() assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling event' self.ps.test_updates['passed'] = True # Case C162177 006 Teacher | Cancel a new event after making changes @pytest.mark.skipif(str(162177) not in TESTS, reason="Excluded") def test_teacher_cancel_a_new_event_after_changes_162177(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162177'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_006_%d' % (randint(100, 999)) # Open "Add Event" page self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add Event screen' # Add title self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'reading-title') ) ).send_keys(assignment_name) sleep(1) # Cancel with "Cancel" button self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'builder-cancel-button') ) ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"ok")]') ) ).click() # Check if back at user dashboard assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling Event' # Open "Add Event" page self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add Event screen' # Add title self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'reading-title') ) ).send_keys(assignment_name) # Cancel with "X" button self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"openstax-close-x")]') ) ).click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"ok")]') ) ).click() assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling Event' self.ps.test_updates['passed'] = True # Case C162178 007 Teacher | Cancel a draft event before making changes @pytest.mark.skipif(str(162178) not in TESTS, reason="Excluded") def test_teacher_cancel_a_draft_event_before_changes_162178(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162178'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name_1 = 'event_007_%s' % randint(100, 500) assignment_name_2 = 'event_007_%s' % randint(500, 999) today = datetime.date.today() finish = randint(1, 5) begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create a draft assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name_1, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name_1) ).click() sleep(1) # Cancel with "Cancel" button cancel_button = self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'builder-cancel-button') ) ) self.teacher.scroll_to(cancel_button) cancel_button.click() # Check if teacher is taken to user dashboard self.teacher.page.wait_for_page_load() assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling Event' # Add a draft Event self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name_2, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name_2) ).click() sleep(1) # Cancel with "X" button self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"openstax-close-x")]') ) ).click() # Check if the teacher is back to user dashboard assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling Event' self.ps.test_updates['passed'] = True # Case C162179 008 Teacher | Cancel a draft event after making changes @pytest.mark.skipif(str(162179) not in TESTS, reason="Excluded") def test_teacher_cancel_a_draft_event_after_changes_162179(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162179'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name_1 = 'event_008_%s' % randint(100, 500) assignment_name_2 = 'event_008_%s' % randint(500, 999) today = datetime.date.today() finish = randint(1, 5) begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create a draft assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name_1, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name_1) ).click() sleep(1) # Edit the assignment self.teacher.find( By.ID, "reading-title" ).send_keys('changed') # Cancel with "Cancel" button cancel_button = self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'builder-cancel-button') ) ) self.teacher.scroll_to(cancel_button) cancel_button.click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"ok")]') ) ).click() # Check if teacher is taken to user dashboard self.teacher.page.wait_for_page_load() assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling Event' # Create a draft assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name_2, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name_2) ).click() sleep(1) # Edit the assignment self.teacher.find( By.ID, "reading-title" ).send_keys('changed') # Cancel with "X" button self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"openstax-close-x")]') ) ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"ok")]') ) ).click() # Check if the teacher is back to user dashboard assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling Event' self.ps.test_updates['passed'] = True # Case C162180 009 Teacher | Attempt to save or publish an event with blank required fields @pytest.mark.skipif(str(162180) not in TESTS, reason="Excluded") def test_teacher_attempt_to_save_or_publish_events_with_blank_required_fields_162180(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162180'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.assign.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add Event screen' # Publish without filling in any fields self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class,"-publish")]') ) ).click() # Required field reminder self.teacher.find( By.XPATH, '//div[contains(text(),"Required field")]') assert ('event' in self.teacher.current_url()), \ 'went back to calendar even though required fields were left blank' # Refresh the page self.teacher.driver.refresh() sleep(3) # Save without filling in any fields self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//button[contains(@class, "save")]') ) ).click() # Required field reminder self.teacher.find( By.XPATH, '//div[contains(text(),"Required field")]') assert ('event' in self.teacher.current_url()), \ 'went back to calendar even though required fields were left blank' self.ps.test_updates['passed'] = True # Case C162181 010 Teacher | Delete a draft event @pytest.mark.skipif(str(162181) not in TESTS, reason="Excluded") def test_teacher_delete_a_draft_event_162181(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162181'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_010_%s' % randint(100, 500) today = datetime.date.today() finish = randint(1, 5) begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create a draft assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() sleep(1) # Delete the draft assignment self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"delete-link")]') ) ).click() self.teacher.find( By.XPATH, '//button[contains(text(),"Yes")]' ).click() sleep(3) assert ('month' in self.teacher.current_url()), \ 'not returned to calendar after deleting an assignment' # have to refresh to remove the assignment tab from calendar self.teacher.driver.refresh() self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) deleted_event = self.teacher.find_all( By.XPATH, '//label[@data-title="{0}"]'.format(assignment_name) ) assert (len(deleted_event) == 0), 'Event not deleted' self.ps.test_updates['passed'] = True # Case C162182 011 Teacher | Delete an unopened event @pytest.mark.skipif(str(162182) not in TESTS, reason="Excluded") def test_teacher_delete_an_unopened_event_162182(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162182'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_011_%s' % randint(100, 500) today = datetime.date.today() start = randint(2, 3) finish = start + randint(1, 5) begin = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create an unopened assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish', } ) # Find the unopened Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'edit-assignment-button') ) ).click() # Delete the assignment delete_button = self.teacher.find( By.XPATH, '//button[contains(@class,"delete-link")]' ) self.teacher.scroll_to(delete_button) delete_button.click() sleep(3) confirm_button = self.teacher.find( By.XPATH, '//button[contains(text(),"Yes")]' ) self.teacher.scroll_to(confirm_button) confirm_button.click() sleep(3) assert ('month' in self.teacher.current_url()), \ 'not returned to calendar after deleting an assignment' # Have to refresh the browser to remove assignment tab from calendar self.teacher.driver.refresh() deleted_unopened = self.teacher.find_all( By.XPATH, '//label[@data-title="{0}"]'.format(assignment_name) ) assert len(deleted_unopened) == 0, 'unopened reading not deleted' self.ps.test_updates['passed'] = True # Case C162183 012 Teacher | Delete an open event @pytest.mark.skipif(str(162183) not in TESTS, reason="Excluded") def test_teacher_delete_an_open_event_162183(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162183'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_012_%s' % randint(100, 500) today = datetime.date.today() finish = randint(1, 5) begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create an unopened assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish', } ) # Find the open Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'edit-assignment-button') ) ).click() # Delete the assignment delete_button = self.teacher.find( By.XPATH, '//button[contains(@class,"delete-link")]' ) self.teacher.scroll_to(delete_button) delete_button.click() sleep(3) confirm_button = self.teacher.find( By.XPATH, '//button[contains(text(),"Yes")]' ) self.teacher.scroll_to(confirm_button) confirm_button.click() sleep(3) assert ('month' in self.teacher.current_url()), \ 'not returned to calendar after deleting an assignment' # Have to refresh the browser to remove assignment tab from calendar self.teacher.driver.refresh() deleted_unopened = self.teacher.find_all( By.XPATH, '//label[@data-title="{0}"]'.format(assignment_name) ) assert len( deleted_unopened) == 0, 'open Event not deleted' self.ps.test_updates['passed'] = True # Case C162184 013 Teacher | Change a draft event @pytest.mark.skipif(str(162184) not in TESTS, reason="Excluded") def test_teacher_change_a_draft_event_162184(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162184'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_013_%s' % randint(100, 500) assignment = Assignment() today = datetime.date.today() finish = randint(1, 5) begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create a draft assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'draft', } ) # Find the draft Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() sleep(1) # Change the title self.teacher.find( By.ID, "reading-title" ).send_keys("changed") # Change the description self.teacher.find( By.CSS_SELECTOR, ".assignment-description>.form-control" ).send_keys("changed") # Set new due dates today = datetime.date.today() start = randint(1, 6) end = start + randint(1, 5) opens_on = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') closes_on = (today + datetime.timedelta(days=end)) \ .strftime('%m/%d/%Y') assignment.assign_periods( self.teacher.driver, {'all': (opens_on, closes_on)} ) # Save as draft self.teacher.find( By.XPATH, '//button[contains(@class,"-save")]' ).click() sleep(1) # Find the new title on the calendar try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format( assignment_name + 'changed') ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format( assignment_name + 'changed') ) self.ps.test_updates['passed'] = True # Case C162185 014 Teacher | Change an unopened event @pytest.mark.skipif(str(162185) not in TESTS, reason="Excluded") def test_teacher_change_an_unopened_event_162185(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162185'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_014_%s' % randint(100, 500) assignment = Assignment() today = datetime.date.today() start = randint(2, 3) finish = start + randint(1, 5) begin = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create an unopened assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish', } ) # Find the unopened Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'edit-assignment-button') ) ).click() # Change the title self.teacher.find( By.ID, "reading-title" ).send_keys("changed") # Change the description self.teacher.find( By.CSS_SELECTOR, ".assignment-description>.form-control" ).send_keys("changed") # Set new due dates today = datetime.date.today() start = randint(1, 6) end = start + randint(1, 5) opens_on = (today + datetime.timedelta(days=start)) \ .strftime('%m/%d/%Y') closes_on = (today + datetime.timedelta(days=end)) \ .strftime('%m/%d/%Y') assignment.assign_periods( self.teacher.driver, {'all': (opens_on, closes_on)} ) # Publish self.teacher.find( By.XPATH, '//button[contains(@class,"-publish")]' ).click() sleep(1) # Find the new title on the calendar try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format( assignment_name + 'changed') ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format( assignment_name + 'changed') ) self.ps.test_updates['passed'] = True # Case C162186 015 Teacher | Change an open event @pytest.mark.skipif(str(162186) not in TESTS, reason="Excluded") def test_teacher_change_an_open_event_162186(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162186'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_015_%s' % randint(100, 500) assignment = Assignment() today = datetime.date.today() finish = randint(1, 5) begin = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)) \ .strftime('%m/%d/%Y') # Create an open assignment self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish', } ) # Find the open Event on the calendar self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'edit-assignment-button') ) ).click() # Change the title self.teacher.find( By.ID, "reading-title" ).send_keys("changed") # Change the description self.teacher.find( By.CSS_SELECTOR, ".assignment-description>.form-control" ).send_keys("changed") # Set new due dates end = randint(1, 5) closes_on = (today + datetime.timedelta(days=end)) \ .strftime('%m/%d/%Y') assignment.assign_date( driver=self.teacher.driver, date=closes_on, is_all=True, target='due' ) # Publish self.teacher.find( By.XPATH, '//button[contains(@class,"-publish")]' ).click() sleep(1) # Find the new title on the calendar try: self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format( assignment_name + 'changed') ) except NoSuchElementException: self.teacher.find( By.XPATH, '//a[contains(@class,"header-control next")]' ).click() self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format( assignment_name + 'changed') ) self.ps.test_updates['passed'] = True # Case C162187 016 Teacher | Add an event by dragging and dropping @pytest.mark.skipif(str(162187) not in TESTS, reason="Excluded") def test_teacher_add_an_event_by_drag_and_drop_162187(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162187'] self.ps.test_updates['passed'] = False # Test verification self.teacher.assign.open_assignment_menu(self.teacher.driver) event_tab = self.teacher.find( By.LINK_TEXT, 'Add Event' ) due_date = self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//div[contains(@class,"Day--upcoming")]') ) ) actions = ActionChains(self.teacher.driver) actions.move_to_element(event_tab) actions.drag_and_drop(event_tab, due_date).perform() sleep(3) assert ('event/new' in self.teacher.current_url()), \ 'not at Add Event page' self.ps.test_updates['passed'] = True # Case C162188 017 Teacher| Get assignment link test info icons @pytest.mark.skipif(str(162188) not in TESTS, reason="Excluded") def test_teacher_get_assignment_link_and_view_info_icons_162188(self): self.ps.test_updates['name'] = 'tutor_event_teacher' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher', '162188'] self.ps.test_updates['passed'] = False # Test steps and verification assertions assignment_name = 'event_017_%d' % (randint(100, 999)) assignment = Assignment() today = datetime.date.today() start = randint(2, 6) finish = start + randint(1, 5) begin_today = today.strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=finish)).strftime('%m/%d/%Y') # Open Add Event page assignment.open_assignment_menu(self.teacher.driver) self.teacher.find(By.LINK_TEXT, 'Add Event').click() assert ('event/new' in self.teacher.current_url()), \ 'not at add event screen' # Test info icon self.teacher.find( By.XPATH, '//button[contains(@class, "footer-instructions")]' ).click() self.teacher.find(By.ID, 'plan-footer-popover') self.ps.test_updates['passed'] = True # Back to dashboard self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'builder-cancel-button') ) ).click() assert ('month' in self.teacher.current_url()), \ 'not back at calendar after cancelling event' self.teacher.add_assignment( assignment='event', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin_today, end)}, 'url': 'www.openstax.org', 'status': 'publish' } ) # View assignment summary self.teacher.wait.until( expect.presence_of_element_located( (By.CLASS_NAME, 'month-wrapper') ) ) self.teacher.find( By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name) ).click() # Get assignment link self.teacher.wait.until( expect.element_to_be_clickable( (By.ID, 'lms-info-link') ) ).click() sleep(3) self.teacher.find( By.XPATH, '//div[contains(@id, "sharable-link-popover")]' ) self.ps.test_updates['passed'] = True
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")
class TestAnalyzeCollegeWorkflow(unittest.TestCase): """T2.05 - Analyze College Workflow.""" 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, pasta_user=self.ps, capabilities=self.desired_capabilities, existing_driver=self.teacher.driver) 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 @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded') def test_create_assignment_links_teacher(self): """ Go to https://tutor-qa.openstax.org/ Click on the 'Login' button Login to student account Click 'Next' Enter the teacher password [ password ] in the password text box Click on the 'Login' button If the user has more than one course, click on a Tutor course name Click on a published reading assignment on the calendar dashboard Click "Get Assignment Link" ***User is presented with links to assigned readings (t2.05.04)*** Click on 'X' to get out of pop-up menu Click on a published homework assignment on the calendar dashboard ***Click "Get Assignment Link" User is presented with links to assigned homework (t2.05.05)*** Expected Results: Corresponds to... t2.05.04 --> 05 :return: """ # t2.05.04 --> ser is presented with links to assigned readings (t2.05.04) self.teacher.login() self.teacher.select_course(appearance='biology') assignment_name = 'reading004_%d' % (randint(100, 999)) today = datetime.date.today() begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=4)).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' }) try: self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() except NoSuchElementException: self.teacher.find( By.XPATH, "//a[contains(@class, 'header-control next')]").click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[@class="get-link"]'))).click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="popover-content"]' + '//input[contains(@value,"https://tutor")]'))) # t2.05.05 --> Clicking "Get Assignment Link presents # user with links to assigned homework (t2.05.05)*** ### FIND A WAY TO GET BACK TO MY CURRENT COURSES PAGE (maybe use teacher goto... method) self.teacher.select_course(appearance='biology') assignment_name = 'hw005_%d' % (randint(100, 999)) today = datetime.date.today() begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=4)).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' }) try: self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.sleep(1) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() except NoSuchElementException: self.teacher.find( By.XPATH, "//a[contains(@class, 'header-control next')]").click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[@class="get-link"]'))).click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="popover-content"]' + '//input[contains(@value,"https://tutor")]')))
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 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.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", "1.2"], "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.wait.until(expect.visibility_of_element_located((By.LINK_TEXT, "This Week"))) reading = self.student.driver.find_element(By.XPATH, '//span[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() 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 # 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.milestones-toggle").click() self.student.sleep(1) cards = self.student.find_all(By.CSS_SELECTOR, 'div[class="milestone"]') preview = "" if not isinstance(cards, list): preview = cards.find_element(By.XPATH, '/div[@class="milestone-preview"]').text cards.click() else: card = randint(0, len(cards) - 1) preview = cards[card].find_element(By.XPATH, '/div[@class="milestone-preview"]').text cards[card].click() # Issue: section titles are not in the content preview self.ps.test_updates["passed"] = True
class TestWorkAHomework(unittest.TestCase): def setUp(self): """Pretest settings.""" if not LOCAL_RUN: self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() self.student = Student( use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities ) self.teacher = Teacher( existing_driver=self.student.driver, use_env_vars=True, 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.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME) def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job( job_id=str(self.student.driver.session_id), **self.ps.test_updates ) self.teacher = None try: self.student.delete() except: pass @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded') def test_teacher_make_homework_immediate(self): """ Go to https://tutor-qa.openstax.org/ Login with student account If the user has more than one course, select a Tutor course Click on a homework assignment (with immediate feedback) on the list dashboard ***The user starts an open homework assignment (t1.71.22)*** Enter a free response into the free response text box Click "Answer" Select a multiple choice answer Click "Submit" ***A multiple choice answer is submitted (t1.71.23)*** ***Answer feedback is presented (t1.71.24)*** Expected results: Corresponds to... t1.71 22 --> 24 :return: """ # go to course self.teacher.login() # t1.71 22 --> The user starts an open homework assignment today = datetime.date.today() begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=3)).strftime('%m/%d/%Y') assignment_name = 'hw no.{0}: {1}'.format( str(randint(0, 100)), str(today) ) # get course name and term course_title = "Physics" # name of course or part of the name current_term = current_tutor_term(begin) open_course_xpath = '//div[contains(@data-title,"{0}") and ' \ 'contains(@data-term,"{1}")]//a'.format( course_title, current_term ) # we do the above in order to ensure that the course is open right now target_course = self.teacher.find(By.XPATH, open_course_xpath) # for reference later as student course_number = target_course.get_attribute('data-course-id') target_course.click() # immediate feedback self.teacher.add_assignment(assignment='homework', args={ 'title': assignment_name, 'description': 'description', 'periods': {'all': (begin, end)}, 'status': 'publish', 'problems': {'ch1': 5}, 'feedback': 'immediate' }) self.teacher.logout() self.student.login() self.wait.until( expect.element_to_be_clickable(( By.XPATH, "//div[contains(@data-course-id,%s)]" % course_number )) ).click() assert (course_number in self.student.current_url()), \ "Not at the desired course %s page!" % course_number homework = self.student.find( By.XPATH, '//a[contains(@aria-labelledby, "%s")]' % assignment_name ) self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', homework ) ActionChains(self.student.driver).move_to_element(homework).perform() homework.click() # make sure that we're at the HW # t1.71 24 --> Answer feedback is presented wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME) wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@class,"question-stem")]') ) ) try: # if the question is two part must answer free response to get mc text_box = self.student.find( By.TAG_NAME, 'textarea') self.teacher.driver.execute_script( "arguments[0].scrollIntoView(true);", text_box ) answer_text = "hello" for i in answer_text: text_box.send_keys(i) self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"continue")]') ) ).click() except: pass mc_choice = self.student.find( By.XPATH, '//div[@class="answer-letter"]') self.student.driver.execute_script( 'return arguments[0].scrollIntoView();', mc_choice ) self.student.driver.execute_script('window.scrollBy(0, -150);') mc_choice.click() self.wait.until( expect.visibility_of_element_located( (By.XPATH, '//button[contains(@class,"continue")]') ) ).click() try: # this is looking for question feedback -- though not all questions # might have self.student.find( By.XPATH, '//div[contains(@class,"question-feedback-content")]' ) except: correct_answer = self.student.find( By.XPATH, "//div[contains(@class,'disabled answer-correct')]" ) print(correct_answer) # you should expect to see the answer feedback # t1.71 23 --> A multiple choice answer is submitted and # you can navigate to the next assessment self.student.find( By.XPATH, '//button[contains(text(),"Next")]')
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 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.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', '1.2'], '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.wait.until( expect.visibility_of_element_located((By.LINK_TEXT, 'This Week'))) reading = self.student.driver.find_element( By.XPATH, '//span[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() 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 # 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.milestones-toggle').click() self.student.sleep(1) cards = self.student.find_all(By.CSS_SELECTOR, 'div[class="milestone"]') preview = '' if not isinstance(cards, list): preview = cards.find_element( By.XPATH, '/div[@class="milestone-preview"]').text cards.click() else: card = randint(0, len(cards) - 1) preview = cards[card].find_element( By.XPATH, '/div[@class="milestone-preview"]').text cards[card].click() # Issue: section titles are not in the content preview self.ps.test_updates['passed'] = True
class TestAnalyzeCollegeWorkflow(unittest.TestCase): """T2.05 - Analyze College Workflow.""" 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, pasta_user=self.ps, capabilities=self.desired_capabilities, existing_driver=self.teacher.driver) 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 # 14645 - 001 - Student | All work is visible for college students # not just "This Week" @pytest.mark.skipif(str(14645) not in TESTS, reason='Excluded') def test_student_all_work_is_visible_for_college_students_14645(self): """All work is visible for college students, not just 'This Week'. Steps: Log into tutor-qa as student Click on a college course Expected Result: Can view assignments due later than this week """ self.ps.test_updates['name'] = 't2.05.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.001', '14645'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.student.login() self.student.select_course(title='College Physics with Courseware') # find either upcoming events, or a message stating there are none. try: self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[contains(text(),"%s")]' % "Coming Up"))) except TimeoutException: self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(text(),"%s")]' % "No upcoming events"))) self.ps.test_updates['passed'] = True ''' # 14646 - 002 - Teacher | Create a link to the OpenStax Dashboard @pytest.mark.skipif(str(14646) not in TESTS, reason='Excluded') def test_teacher_create_a_link_to_the_openstax_dashboard_14646(self): """Create a link to the OpenStax Dashboard. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.05.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.002', '14646'] 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 ''' ''' # 14647 - 003 - Teacher | Create a link to the OpenStax Dashboard @pytest.mark.skipif(str(14647) not in TESTS, reason='Excluded') def test_teacher_create_a_link_to_the_openstax_dashboard_14647(self): """Create a link to the OpenStax Dashboard. Steps: Expected Result: """ self.ps.test_updates['name'] = 't2.05.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.003', '14647'] 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 ''' # 14648 - 004 - Teacher | Create links to assigned readings in their LMS @pytest.mark.skipif(str(14648) not in TESTS, reason='Excluded') def test_teacher_create_links_to_assigned_readings_in_lms_14648(self): """Create links to assigned readings in their LMS. Steps: Login as a teacher If the user has more than one course, click on a tutor course name Click on a published reading assignment on the calendar dashboard Click "Get Assignment Link" Expected Result: The user is presented with links to assigned readings """ self.ps.test_updates['name'] = 't2.05.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.004', '14648'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='biology') assignment_name = 'reading004_%d' % (randint(100, 999)) today = datetime.date.today() begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=4)).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' }) try: self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() except NoSuchElementException: self.teacher.find( By.XPATH, "//a[contains(@class, 'header-control next')]").click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[@class="get-link"]'))).click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="popover-content"]' + '//input[contains(@value,"https://tutor")]'))) self.ps.test_updates['passed'] = True # 14649 - 005 - Teacher | Create links to assigned homework in their LMS @pytest.mark.skipif(str(14649) not in TESTS, reason='Excluded') def test_teacher_create_links_to_assigned_homework_in_lms_14649(self): """Create links to assigned homework in their LMS. 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 on a published homework assignment on the calendar dashboard Click "Get Assignment Link" Expected Result: The user is presented with links to assigned homework """ self.ps.test_updates['name'] = 't2.05.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.005', '14649'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.login() self.teacher.select_course(appearance='biology') assignment_name = 'hw005_%d' % (randint(100, 999)) today = datetime.date.today() begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y') end = (today + datetime.timedelta(days=4)).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' }) try: self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.sleep(1) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() except NoSuchElementException: self.teacher.find( By.XPATH, "//a[contains(@class, 'header-control next')]").click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="month-wrapper"]'))) self.teacher.find( By.XPATH, "//div/label[contains(text(), '" + assignment_name + "')]").click() self.teacher.wait.until( expect.element_to_be_clickable( (By.XPATH, '//a[@class="get-link"]'))).click() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//div[@class="popover-content"]' + '//input[contains(@value,"https://tutor")]'))) self.ps.test_updates['passed'] = True '''