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 TestExercisesTeacher(unittest.TestCase): """Tutor | Teacher""" def setUp(self): """Pretest settings.""" self.ps = PastaSauce() self.desired_capabilities['name'] = self.id() if not LOCAL_RUN: self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: self.teacher = Teacher(use_env_vars=True) # self.teacher.login(url='http://exercises-qa.openstax.org') def tearDown(self): """Test destructor.""" if not LOCAL_RUN: self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates) try: self.teacher.delete() except: pass @pytest.mark.skipif(str(162257) not in TESTS, reason='Excluded') def test_creating_true_and_false_question_162257(self): """ Go to exercises qa Log in as a teacher Click "Write a new exercise" Click "True/False" button Expected result: ***User is presented with a page where a True/False question can be created*** Corresponding test cases: T2.12 001, 002 https://trello.com/c/w4T1eqT4/66-creating-vocabulary-question-and-true-false """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162257' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162257'] self.ps.test_updates['passed'] = False # log into exercises self.teacher.login(url=os.getenv('EXERCISES_STAGING'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # Click "Write a new exercise" self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() # Click true false button self.teacher.find(By.CSS_SELECTOR, "#input-true-false").click() # Verify that user is presented with a page where they can make a true # false q self.teacher.find(By.CSS_SELECTOR, "textarea") self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162258) not in TESTS, reason='Excluded') def test_question_library_functionality_162258(self): """ Go to tutor qa Log in as a teacher Click on a course Upper right corner under user menu, click "Question Library" Select a section or chapter click "Show Questions" **User is presented with all the questions for the section or chapter** Scroll down to a question, click "Exclude Question" ***Observe that Question is excluded*** Click on the "Reading" tab ***Exercises that are only for Reading appear*** Click on the "Practice" tab @@@@@@@@@@@ Should this be Homework? ***Exercises that are only for Practice appear*** Scroll down **Observe that tabs are pinned to the top of the screen when scrolled** Click on the section links at the top of the screen ***Observe that the screen scrolls to the selected screen*** Hover over a question and click "Question details" Click "Report an error" Expected result: ***Observe that a new tab with the assessment errata form appears with the assessment ID already filled in*** Corresponding test cases: T2.11 001-007 https://trello.com/c/SchGDgfL/70-question-library-functionality """ self.ps.test_updates['name'] = \ 'exercises_question_library_teacher_162258' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'question_library', 'teacher', '162258'] self.ps.test_updates['passed'] = False self.teacher.login() # select random tutor course self.teacher.random_course() # if Tutor feedback pops up try: self.teacher.find( By.XPATH, ".//*[contains(text(),'I won’t be using it')]").click() except: pass # go to question library self.teacher.open_user_menu() self.teacher.wait.until( expect.visibility_of_element_located( (By.CSS_SELECTOR, "#menu-option-viewQuestionsLibrary"))) self.teacher.find(By.CSS_SELECTOR, "#menu-option-viewQuestionsLibrary").click() # 50/50 coin toss. 0 = chapter, 1 = section(s) coin = randint(0, 1) # reveal sections chaptertitles = self.teacher.find_all( By.CSS_SELECTOR, ".chapter-heading.panel-title>a") for num in range(1, len(chaptertitles) - 1): self.teacher.scroll_to(chaptertitles[num]) self.teacher.sleep(.2) chaptertitles[num].click() self.teacher.sleep(.2) # choose a random chapter and all its sections if coin == 0: chapters = self.teacher.find_all(By.CSS_SELECTOR, ".chapter-checkbox") chapternum = randint(0, len(chapters) - 1) self.teacher.scroll_to(chapters[chapternum]) self.teacher.sleep(0.5) chapters[chapternum].click() self.teacher.sleep(0.5) # choose randomly 1-5 sections from anywhere in the book elif coin == 1: sections = self.teacher.find_all(By.CSS_SELECTOR, ".section-checkbox") randomlist = random.sample(range(len(sections) - 1), k=randint(1, 5)) for num in randomlist: self.teacher.scroll_to(sections[num]) self.teacher.sleep(.5) sections[num].click() # click show questions self.teacher.find(By.CSS_SELECTOR, ".btn.btn-primary").click() self.teacher.sleep(5) # verify questions show up readingq = self.teacher.find_all(By.CSS_SELECTOR, ".controls-overlay") excludebutton = self.teacher.find_all(By.CSS_SELECTOR, ".action.exclude")[0] # exclude a random question self.teacher.scroll_to(excludebutton) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(excludebutton) self.teacher.sleep(1) actions.perform() self.teacher.sleep(2) excludebutton.click() self.teacher.sleep(.5) self.teacher.find(By.CSS_SELECTOR, ".action.include").click() # click reading button self.teacher.find(By.CSS_SELECTOR, ".reading.btn.btn-default").click() self.teacher.page.wait_for_page_load() totalq = self.teacher.find_all(By.CSS_SELECTOR, ".controls-overlay") # click homework button self.teacher.find(By.CSS_SELECTOR, ".homework.btn.btn-default").click() homeworkq = self.teacher.find_all(By.CSS_SELECTOR, ".controls-overlay") assert (len(totalq) > len(readingq)) assert (len(totalq) > len(homeworkq)) # Observe that tabs are pinned to the top of the screen when scrolled self.teacher.driver.execute_script("window.scrollTo(0, 0);") self.teacher.sleep(3) self.teacher.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);") self.teacher.sleep(3) self.teacher.find(By.XPATH, "//div[@class='section active']") self.teacher.find(By.CSS_SELECTOR, ".homework.btn.btn-default") self.teacher.find(By.CSS_SELECTOR, ".reading.btn.btn-default") # jumps jumps = self.teacher.find_all( By.XPATH, "//div[@class='sectionizer']/div[@class='section']") # Click the section links and verify the page is scrolled position = self.teacher.driver.execute_script("return window.scrollY;") for button in jumps: button.click() self.teacher.sleep(1) assert(position != self.teacher.driver.execute_script( "return window.scrollY;")), \ 'Section link did not jump to next section' position = \ self.teacher.driver.execute_script("return window.scrollY;") # details will lead to Question details details = self.teacher.find_all(By.CSS_SELECTOR, ".action.details")[0] self.teacher.scroll_to(details) self.teacher.sleep(1) actions = ActionChains(self.teacher.driver) actions.move_to_element(details) self.teacher.sleep(1) actions.perform() self.teacher.sleep(2) details.click() self.teacher.find(By.CSS_SELECTOR, ".action.report-error").click() details_window = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(details_window) self.teacher.page.wait_for_page_load() self.teacher.sleep(2) self.teacher.find(By.CSS_SELECTOR, ".errata-page.page") self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162259) not in TESTS, reason='Excluded') def test_creating_multiple_choice_questions_162259(self): """ Go to exercises qa Log in as a teacher Click "Write a new exercise" Enter the video embed link into the Question Stem text box ***The video should appear in the box to the right*** Fill out the required fields Click on the box "Order Matters" ***User is able to preserve the order of choices*** Click "Tags" Click "Question Type", "DOK", "Blooms", and/or "Time" ***The user is able to pull out the dropdown tags*** Select a choice from the dropdown tags ***User is able to select a specific tag and the tag(s) appear in the box to the right*** Check the box that says "Requires Context" ***The user is able to specify whether context is required for a question and the tag "requires-context:true" appears in the box to the right*** Click "+" next to "CNX Module" Enter the CNX Module number Click "Save Draft" Click "Assets" Click "Add new image" Select an image ***The image and the options "Choose different image" and "Upload" should come up*** Click "Upload" ***There shoould be a URL and a "Delete" button)*** ***The user is presented with uploaded URL in the HTML snippet*** Click "Delete" ***The image is deleted*** Click "Save Draft", then click "Publish" ***Observe message: "Exercise [exercise ID] has published successfully")*** Click "Search" Enter the desired exercise ID Scroll down to "Detailed Solutions" Edit text in the "Detailed Solutions" text box Click "Publish" Expected Result: ***The user is able to edit detailed solutions and the changes are in the box to the right*** Corresponding test cases: T2.11 022-031 https://trello.com/c/n5VmmdyB/83-creating-multiple-choice-questions """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162259' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162259'] self.ps.test_updates['passed'] = False self.teacher.login(url=os.getenv('EXERCISES_QA'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # click create a new question self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() textboxes = self.teacher.find_all(By.CSS_SELECTOR, ".question>div>textarea") # put embed link into Question Stem text box embedlink = '<iframe width="560" height="315" ' + \ 'src="https://www.youtube.com/embed/' embedlink += 'QnQe0xW_JY4" frameborder="0" allowfullscreen></iframe>"' textboxes[0].send_keys(embedlink) # verify that the video appears in the box to the right self.teacher.find(By.CSS_SELECTOR, "iframe") # fill out the required fields answers = self.teacher.find_all(By.CSS_SELECTOR, ".correct-answer>textarea") answers[0].send_keys('answer numero uno') answers[1].send_keys('answer numero dos') # textboxes[1].send_keys('answer numero tres') # click on Order Matters checkbox self.teacher.find(By.CSS_SELECTOR, "#input-om").click() # Click on Tabs tag self.teacher.find(By.CSS_SELECTOR, "#exercise-parts-tab-tags").click() # verify that all the dropdowns are clickable tagoptions = self.teacher.find_all(By.CSS_SELECTOR, ".form-control") for num in range(len(tagoptions)): expect.element_to_be_clickable(tagoptions[num]) # choose an option from a dropdown tagoptions[1].click() self.teacher.find_all(By.CSS_SELECTOR, "option")[1].click() # verify that the tag appears in the box to the right self.teacher.find( By.XPATH, "//*[@class='exercise-tag' and contains(text(),'type')]") self.teacher.find(By.CSS_SELECTOR, ".tag>input").click() self.teacher.find( By.XPATH, "//*[@class='exercise-tag' and contains(text(),'context:true')]") # click "+" next to CNX Module self.teacher.find_all(By.CSS_SELECTOR, ".fa.fa-plus-circle")[2].click() # put in a CNX module self.teacher.find( By.XPATH, ".//*[@class='form-control' and @placeholder]").send_keys( '12345678-1234-5788-9123-456798123456') # click save draft self.teacher.find(By.CSS_SELECTOR, ".async-button.draft.btn.btn-info").click() # click assets tab self.teacher.find(By.CSS_SELECTOR, "#exercise-parts-tab-assets") \ .click() # Choose image. This is all local -- prob have to edit for diff # computer IMAGEPATH = "/Users/openstax10/desktop/bee_clip_art_18782.jpg" self.teacher.find(By.ID, "file").send_keys(IMAGEPATH) # check that Choose different image and Upload buttons are present self.teacher.find(By.XPATH, './/*[contains(text(),"Choose different image")]') self.teacher.find(By.XPATH, './/*[contains(text(),"Upload")]').click() self.teacher.page.wait_for_page_load() # check if uploaded url is present self.teacher.find(By.CSS_SELECTOR, ".copypaste") # check that delete button is present and click it self.teacher.find(By.XPATH, './/*[contains(text(),"Delete")]').click() self.teacher.sleep(1) # click publish self.teacher.find(By.CSS_SELECTOR, '.async-button.publish.btn.btn-primary').click() self.teacher.sleep(1) # confirm that you want to publish self.teacher.find( By.XPATH, './/*[@class="btn btn-primary" and contains(text(),"Publish")]' ).click() self.teacher.sleep(1) # close popup window tellign you ID # self.teacher.find( By.XPATH, './/*[@class="btn btn-primary" and contains(text(),"Close")]' ).click() # get id ID = self.teacher.current_url().split('/')[-1] # click search button self.teacher.find(By.CSS_SELECTOR, '.btn.btn-danger.back.btn.btn-default').click() # enter ID into field self.teacher.find(By.CSS_SELECTOR, '.form-control').send_keys(ID) self.teacher.find(By.CSS_SELECTOR, '.btn.btn-default.load').click() # edit detailed solution self.teacher.find(By.XPATH, "//div[4]/textarea") \ .send_keys('hello edited') detailedsol = self.teacher.find( By.CSS_SELECTOR, '.openstax-has-html.solution').get_attribute('innerHTML') # check that the text you inputted into detailed solution is in the # box to the right assert ('hello edited' == detailedsol) self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162260) not in TESTS, reason='Excluded') def test_creating_vocabulary_questions_162260(self): """ Go to exercises qa Log in with as a teacher Click "Write a new exercise" Click "New Vocabulary Term" from the header Fill out required fields Click "Save Draft" Click "Publish" ***The "Publish" button is whited out and the exercise ID appears in the box to the right*** Click "Search" Enter the desired exercise ID ***The vocabulary question loads and user is able to review it*** Enter next text into "Key Term", "Key Term Definition", and "Distractors" Click "Save Draft" Click "Publish" Expected result: ***The user is able to edit and save a vocabulary question*** Corresponding test cases: T2.11 035-037 https://trello.com/c/3j0K6fp0/89-creating-vocabulary-questions """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162260' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162260'] self.ps.test_updates['passed'] = False # logging in with these credentials self.teacher.login(url=os.getenv('EXERCISES_QA'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # click create a new question self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() # click New vocabulary question self.teacher.find(By.CSS_SELECTOR, ".btn.btn-success.vocabulary.blank").click() # enter testing as the key term self.teacher.find(By.CSS_SELECTOR, "#key-term").send_keys('testing') # enter 'ignore' as the definition self.teacher.find(By.CSS_SELECTOR, "#key-term-def").send_keys('ignore') # click save draft self.teacher.find(By.CSS_SELECTOR, ".async-button.draft.btn.btn-info").click() # click publish self.teacher.find(By.CSS_SELECTOR, ".async-button.publish.btn.btn-primary").click() self.teacher.sleep(1) # confirm publish self.teacher.find( By.XPATH, ".//*[@class='btn btn-primary' and contains(text(),'Publish')]" ).click() self.teacher.sleep(3) # get the exercise id exerciseid = self.teacher.find_all( By.CSS_SELECTOR, ".exercise-tag")[3].get_attribute('innerHTML')[4:] # go to search self.teacher.find(By.XPATH, ".//*[contains(text(),'Search')]").click() # search the exercise id self.teacher.find(By.CSS_SELECTOR, ".form-control") \ .send_keys(exerciseid) # click search self.teacher.find(By.CSS_SELECTOR, ".btn.btn-default.load").click() # confirm key term value is what was inputted originally keyterm = self.teacher.find(By.CSS_SELECTOR, "#key-term") \ .get_attribute('value') assert (keyterm == 'testing') # write something else for key term keyterm = self.teacher.find(By.CSS_SELECTOR, "#key-term") keyterm.send_keys(Keys.BACKSPACE * len('testing ')) self.teacher.sleep(0.2) keyterm.send_keys('test edit') # confirm key term def value is what was inputted oirignally keytermdef = self.teacher.find(By.CSS_SELECTOR, '#key-term-def') \ .get_attribute('value') assert (keytermdef == 'ignore') # write something else for key term def keytermdef = self.teacher.find(By.CSS_SELECTOR, "#key-term-def") keytermdef.send_keys(Keys.BACKSPACE * len('ignore ')) self.teacher.sleep(0.2) keytermdef.send_keys('ignore edit') # fill in value for distractor self.teacher.find_all(By.CSS_SELECTOR, ".form-control")[2].send_keys('im a distractor') self.teacher.sleep(3) # save as draft self.teacher.find(By.CSS_SELECTOR, ".async-button.draft.btn.btn-info").click() self.teacher.sleep(1) # publish self.teacher.find(By.CSS_SELECTOR, ".async-button.publish.btn.btn-primary").click() # confirm publish self.teacher.find( By.XPATH, './/*[@class="btn btn-primary" and contains(text(),"Publish")]' ).click() self.teacher.sleep(2) # get new exercise id exerciseid = self.teacher.find_all( By.CSS_SELECTOR, ".exercise-tag")[3].get_attribute('innerHTML')[4:] # click search self.teacher.find(By.XPATH, ".//*[contains(text(),'Search')]").click() # search the exercise id self.teacher.find(By.CSS_SELECTOR, ".form-control") \ .send_keys(exerciseid) self.teacher.find(By.CSS_SELECTOR, ".btn.btn-default.load").click() # verify that the value in key term is what was inputted previously keyterm = self.teacher.find(By.CSS_SELECTOR, "#key-term") \ .get_attribute('value') assert (keyterm == 'test edit') self.ps.test_updates['passed'] = True @pytest.mark.skipif(str(162261) not in TESTS, reason='Excluded') def test_creating_multipart_question_162261(self): """ Go to exercises qa Log in as a teacher Click "Write a new exercise" Check the box that says "Exercise contains multiple parts" Fill out the required fields Click "Publish" Expected result: ***The user gets a confirmation that says "Exercise [exercise ID] has published successfully"*** Corresponding test case: T2.11 045 https://trello.com/c/8LnE8Qml/162-creating-multi-part-question """ self.ps.test_updates['name'] = \ 'exercises_new_exercise_teacher_162261' + \ inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = \ ['exercises', 'new_exercise', 'teacher', '162261'] self.ps.test_updates['passed'] = False # logging in with these credentials self.teacher.login(url=os.getenv('EXERCISES_QA'), username=os.getenv('CONTENT_USER'), password=os.getenv('CONTENT_PASSWORD')) # click create a new question self.teacher.find(By.CSS_SELECTOR, "a[href*='new']").click() # click "Exercise contains multiple parts" self.teacher.find(By.CSS_SELECTOR, '#mpq-toggle').click() # write in something for question stem self.teacher.find(By.CSS_SELECTOR, '.question>div>textarea') \ .send_keys('test') # write in something for Distractor self.teacher.find(By.CSS_SELECTOR, '.correct-answer>textarea') \ .send_keys('ignore') # click tab "question 2" self.teacher.find(By.CSS_SELECTOR, '#exercise-parts-tab-question-1') \ .click() self.teacher.sleep(1) # write in something for question stem self.teacher.find_all(By.CSS_SELECTOR, '.question>div>textarea')[2].send_keys('test2') # write in something for Distractor self.teacher.find_all( By.CSS_SELECTOR, '.correct-answer>textarea')[2].send_keys('ignore2') # click save draft self.teacher.find(By.CSS_SELECTOR, '.async-button.draft.btn.btn-info').click() # click publish self.teacher.find(By.CSS_SELECTOR, '.async-button.publish.btn.btn-primary').click() self.teacher.sleep(1) # confirm publish self.teacher.find( By.XPATH, ".//*[@class='btn btn-primary' and contains(text(),'Publish')]" ).click() # confirm message appears self.teacher.find(By.CSS_SELECTOR, '.modal-body>b') self.ps.test_updates['passed'] = True
class TestRecruitingTeachers(unittest.TestCase): """CC1.01 - Recruiting Teachers.""" 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.CONDENSED_WIDTH = 1105 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 C7751 - 001 - Admin | Recruitment and promo website is available @pytest.mark.skipif(str(7751) not in TESTS, reason='Excluded') def test_admin_recruitment_and_promo_website_is_available_7751(self): """Recruitment and promo website is available. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Expected Result: Recruitment website loads and renders """ self.ps.test_updates['name'] = 'cc1.01.001' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.001', '7751'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() assert('OpenStax Concept Coach' in self.teacher.driver.page_source), \ 'Not on the Concept Coach entry site' self.ps.test_updates['passed'] = True # Case C7752 - 002 - Teacher | Information about Concept Coach and the # pilot are available on the demo site @pytest.mark.skipif(str(7752) not in TESTS, reason='Excluded') def test_teacher_information_about_cc_is_available_on_demo_site_7752(self): """Information about CC and pilot are available on the demo site. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Expected Result: Page loads several sections describing Concept Coach """ self.ps.test_updates['name'] = 'cc1.01.002' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.002', '7752'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'who-we-are') self.ps.test_updates['passed'] = True # Case C7753 - 003 - Teacher | Can interact with a Concept Coach wire frame # for each subject @pytest.mark.skipif(str(7753) not in TESTS, reason='Excluded') def test_teacher_can_interact_with_a_cc_wire_frame_for_subjects_7753(self): """Can interact with a Concept Coach wire frame for each subject. Steps: Go to the recruitment website ( http://cc.openstax.org/) Hover over "demos" in the header Click "Interactice Demo" CLick on a Concept Coach book title Expected Result: A new tab or window opens rendering the demo content for the selected book """ self.ps.test_updates['name'] = 'cc1.01.003' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.003', '7753'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() assert('http://cc.openstax.org/assets/demos/cc-mockup' in self.teacher.current_url()), \ 'not at demo book' self.ps.test_updates['passed'] = True # # NOT DONE # Case C7754 - 004 - Teacher | View a Concept Coach demo video @pytest.mark.skipif(str(7754) not in TESTS, reason='Excluded') def test_teacher_view_a_concept_coach_demo_video_7754(self): """View a Concept Coach demo video. Steps: Open recruitment website ( http://cc.openstax.org/ ) Hover over "demos" in the header Click "Interactive Demo" Click on a Concept Coach book title Scroll down until an embedded video pane is displayed Click on the right-pointing arrow to play the video Expected Result: The video loads and plays """ self.ps.test_updates['name'] = 'cc1.01.004' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.004', '7754'] self.ps.test_updates['passed'] = False # Test steps and verification assertions # Load demo site self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() # Use the physics demo demo_link = self.teacher.find(By.CSS_SELECTOR, 'a[href*="physics"]') self.teacher.scroll_to(demo_link) self.teacher.sleep(1) demo_link.click() # Switch tab/window to show the physics demo course target_window = len(self.teacher.driver.window_handles) - 1 window_with_book = self.teacher.driver.window_handles[target_window] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() self.teacher.sleep(1) # Grab the iframe tag for manipulation video = self.teacher.wait.until( expect.visibility_of_element_located((By.TAG_NAME, 'iframe'))) self.teacher.scroll_to(video) # Retrieve IDs and enable the YouTube javascript API self.teacher.driver.switch_to_default_content() video_id = video.get_attribute('id') content_id = video.get_attribute('src').split('/')[-1] print('Video: {0}, Content: {1}'.format(video_id, content_id)) set_src = video.get_attribute('src') + '?enablejsapi=1' self.teacher.driver.execute_script("arguments[0].src = arguments[1];", video, set_src) self.teacher.driver.execute_script( "arguments[0].setAttribute('enablejsapi', '1');", video) states = { '-1': 'Unstarted', '0': 'Ended', '1': 'Playing', '2': 'Paused', '3': 'Buffering', '5': 'Video cued', } # Run the API control to play the demo video app_script = ''' var tag = document.createElement("script"); tag.src = "https://www.youtube.com/iframe_api"; tag.type = "text/javascript"; var firstScriptTag = document.getElementsByTagName("script")[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); window.onYouTubeIframeAPIReady = function() { window.player = new YT.Player("''' + video_id + '''", { videoId: "''' + content_id + '''", events: { "onReady": onPlayerReady } }); } function onPlayerReady(event) { event.target.playVideo(); } ''' self.teacher.driver.execute_script(app_script) # Wait a bit then check the video status to see if it is playing self.teacher.sleep(2.5) state = self.teacher.driver.execute_script( 'return player.getPlayerState();') assert((int(state) if state is not None else state) == 1), \ 'Video player is %s, not Playing' % states[state] self.ps.test_updates['passed'] = True # Case C7755 - 005 - Teacher | Sample exercise questions are seen in # the wire frames @pytest.mark.skipif(str(7755) not in TESTS, reason='Excluded') def test_teacher_sample_exercise_questions_are_in_wire_frames_7755(self): """Sample exercise questions are seen in the wire frames. Steps: Open recruitment website ( http://cc.openstax.org/ ) Hover over "demos" in the header Click "Interactive Demo" Click on a Concept Coach book title Scroll down until the 'CONCEPT COACH' pane is displayed Expected Result: Demo exercises are rendered and can be answered along with showing feedback """ self.ps.test_updates['name'] = 'cc1.01.005' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.005', '7755'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() demo_link = self.teacher.find( By.XPATH, '//section[@id="interactive-demo"]' + '//a[@class="btn" and contains(@href,"cc-mockup-physics")]') self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', demo_link) self.teacher.driver.execute_script('window.scrollBy(0, -80);') self.teacher.sleep(1) demo_link.click() window_with_book = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_book) self.teacher.page.wait_for_page_load() self.teacher.sleep(1) self.teacher.find( By.XPATH, '//span[contains(text(),"JUMP TO CONCEPT COACH")]').click() self.teacher.find(By.XPATH, '//div[contains(@data-label,"q1-multiple-choice")]') self.teacher.sleep(2) answer = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//div[contains(@data-label,"choice-1b-text")]'))) actions = ActionChains(self.teacher.driver) actions.move_to_element(answer) actions.click() actions.perform() self.teacher.find(By.XPATH, "//div[@data-label='State2']").click() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, "//div[@data-label='q1-answer-b']//div[@data-label='next']"))) self.ps.test_updates['passed'] = True # Case C7756 - 006 - Teacher | Access Concept Coach help and support before # the teacher's course is created @pytest.mark.skipif(str(7756) not in TESTS, reason='Excluded') def test_teacher_access_cc_support_before_course_is_created_7756(self): """Access CC help and support before the teacher's course is created. Steps: Open the recruitment website ( http://cc.openstax.org/ ) Click "Support" in the header Expected Result: A new tab opens with the CC Help Center """ self.ps.test_updates['name'] = 'cc1.01.006' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.006', '7756'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.driver.find_element( By.XPATH, '//div[@id="headerNav"]//a[contains(text(),"support")]').click() window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) self.teacher.page.wait_for_page_load() self.teacher.driver.find_element( By.XPATH, '//center[text()="OpenStax Concept Coach Support"]') self.ps.test_updates['passed'] = True ''' # Case C7757 - 007 - Teacher | Teacher registers to use a CC course @pytest.mark.skipif(str(7757) not in TESTS, reason='Excluded') def test_teacher_teacher_registers_to_use_a_cc_course_7757(self): """Teacher registers to use a Concept Coach course. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Expected Result: Web form renders """ self.ps.test_updates['name'] = 'cc1.01.007' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.007', '7757' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.ps.test_updates['passed'] = True ''' ''' # Case C7758 - 008 - Teacher | Teacher uses a web form to sign up for CC @pytest.mark.skipif(str(7758) not in TESTS, reason='Excluded') def test_teacher_teacher_uses_a_web_form_to_sign_up_for_cc_7758(self): """Teacher uses a web form to sign up for Concept Coach. Steps: Teacher fills out the form Expected Result: Preconditions pass. User is presented with a confirmation message """ self.ps.test_updates['name'] = 'cc1.01.008' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.008', '7758' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True ''' ''' # Case C7759 - 009 - Teacher | Receive error messages if required fields on # the sign up form are blank @pytest.mark.skipif(str(7759) not in TESTS, reason='Excluded') def test_teacher_receive_error_messages_if_required_fields_are_7759(self): """Receive error messages if required fields on sign up form are blank. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Click on the 'sign up now' button Submit the form without changing any of the text fields Expected Result: Receive 'Please fill out this field' error messages in red for each blank required field """ self.ps.test_updates['name'] = 'cc1.01.009' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.009', '7759' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) submit = self.teacher.find( By.XPATH, '//input[@type="submit"]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', submit) self.teacher.sleep(0.5) submit.click() assert('/sign-up' in self.teacher.current_url()), \ 'moved from sign up when submitting with blank required fields' self.teacher.find( By.XPATH, '//div[contains(text(),"Please fill out this field.")]' ) self.ps.test_updates['passed'] = True ''' ''' # Case C7760 - 010 - Teacher | Submit a form to supply required course info @pytest.mark.skipif(str(7760) not in TESTS, reason='Excluded') def test_teacher_submit_a_form_to_supply_required_course_info_7760(self): """Submit a form to supply required course information. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Web form submits Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.010' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.010', '7760' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') # choose a book! menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True ''' ''' # Case C7761 - 011 - Teacher | Submit co-instructors, classes, names, etc. @pytest.mark.skipif(str(7761) not in TESTS, reason='Excluded') def test_teacher_submit_coinstructors_classes_names_etc_7761(self): """Submit co-instructors, classes, names and other data. Steps: Go to the recruitment and promo website ( http://cc.openstax.org/ ) Click on the 'sign up now' button Click on the 'Co-Teaching class with a colleague?' circle button Enter the co-instructor's (or co-instructors') information Enter text into other fields concerning classe, names, etc. Expected Result: Input box exists for instructor information, class details and other data. The user is able to input information. """ self.ps.test_updates['name'] = 'cc1.01.011' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.011', '7761' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) option = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@class="slide-checkbox"]/label') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', option) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) option.click() textarea = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@id="coteachcontact"]/textarea') ) ) textarea.send_keys('co teacher info') self.ps.test_updates['passed'] = True ''' ''' # Case C7762 - 012 - Teacher | Select the textbook to use in the course @pytest.mark.skipif(str(7762) not in TESTS, reason='Excluded') def test_teacher_select_the_textbook_to_use_in_the_course_7762(self): """Select the textbook to use in the course. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Select the course textbook from the 'Book' dropdown options Expected Result: Able to select any Concept Coach textbook """ self.ps.test_updates['name'] = 'cc1.01.012' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.012', '7762' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) menu = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) book = self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ) title = book.text book.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//span[contains(@title,"' + title + '") and ' + 'contains(@class,"select2-selection__rendered")]' ) self.ps.test_updates['passed'] = True ''' ''' # Case C7763 - 013 - Teacher | Indicate whether the teacher was recruited # by OpenStax @pytest.mark.skipif(str(7763) not in TESTS, reason='Excluded') def test_teacher_indicate_whether_the_teacher_was_recruited_by_7763(self): """Indicate if the teacher was or was not recruited by OpenStax. Steps: Go to the recruitment and promo website ( http://cc.openstax.org/ ) Click on the 'sign up now' button ( http://cc.openstax.org/sign-up ) Enter recruitment information into the 'Anything else we need to know?' text box Expected Result: Able to input recruitment information """ self.ps.test_updates['name'] = 'cc1.01.013' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.013', '7763' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) textarea = self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//textarea[@placeholder="Feedback"]') ) ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', textarea) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) textarea.send_keys('recuitment info') self.ps.test_updates['passed'] = True ''' ''' # Case C7764 - 014 - Teacher | Presented a thank you page after registering # to use Concept Coach @pytest.mark.skipif(str(7764) not in TESTS, reason='Excluded') def test_teacher_presented_a_thank_you_page_after_registering_7764(self): """Presented a thank you page after registering to use Concept Coach. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.014' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.014', '7764' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True ''' ''' # Case C7765 - 015 - Teacher | Sign up for an OpenStax Accounts username @pytest.mark.skipif(str(7765) not in TESTS, reason='Excluded') def test_teacher_sign_up_for_an_openstax_accounts_username_7765(self): """Sign up for an OpenStax Accounts username. Steps: Go to the recruitment website ( http://cc.openstax.org ) Click on the 'sign up now' button Fill out the intent to participate form Submit the form Expected Result: Displays a Thank you message panel """ self.ps.test_updates['name'] = 'cc1.01.015' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.015', '7765' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('http://cc.openstax.org/') self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//section[@id="video2"]//a[@href="/sign-up"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.find( By.ID, 'signup-form' ) self.teacher.find( By.ID, 'first_name' ).send_keys('first') self.teacher.find( By.ID, 'last_name' ).send_keys('last') self.teacher.find( By.ID, 'email' ).send_keys('*****@*****.**') self.teacher.find( By.ID, 'company' ).send_keys('school') menu = self.teacher.find( By.XPATH, '//span[@id="book-select"]' + '//span[contains(@class,"select2-container--")]' ) self.teacher.driver.execute_script( 'return arguments[0].scrollIntoView();', menu) self.teacher.driver.execute_script('window.scrollBy(0, -120);') self.teacher.sleep(0.5) menu.click() self.teacher.sleep(0.5) self.teacher.find( By.XPATH, '//li[contains(@class,"select2-results__option")]' ).click() self.teacher.find( By.XPATH, '//input[@maxlength="255" and @required]' ).send_keys('25') self.teacher.find( By.XPATH, '//input[@type="submit"]' ).click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.visibility_of_element_located( (By.XPATH, '//h1[contains(text(),"Thank you")]') ) ) assert('/thank-you' in self.teacher.current_url()), \ 'not at thank you page after submitting form' self.ps.test_updates['passed'] = True ''' # Case C7770 - 020 - Admin | Add co-instructors to a course @pytest.mark.skipif(str(7770) not in TESTS, reason='Excluded') def test_admin_add_coinstructors_to_a_course_7770(self): """Add co-instructors to a course. Steps: Log into Tutor as an admin From the user menu, select 'Admin' From the 'Course Organization' menu, select 'Courses' In the Courses table, find the correct course and click the 'Edit' button on the right side of that row Click on the 'Teachers' tab In the search box, enter the teacher's name or username Select the teacher in the list below the search bar or hit the down arrow followed by the enter/return key Expected Result: Co-instructor is linked to the affected course """ self.ps.test_updates['name'] = 'cc1.01.020' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.020', '7770'] self.ps.test_updates['passed'] = False # Test steps and verification assertions if not LOCAL_RUN: admin = Admin(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities) else: admin = Admin(use_env_vars=True) admin.login() admin.open_user_menu() admin.find(By.CSS_SELECTOR, '[href*=admin]').click() admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Course Organization'))).click() admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Courses'))).click() admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Edit'))).click() admin.wait.until( expect.visibility_of_element_located( (By.PARTIAL_LINK_TEXT, 'Teachers'))).click() admin.wait.until( expect.visibility_of_element_located( (By.ID, 'course_teacher'))).send_keys('teacher0') element = admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//ul[contains(@class,"ui-autocomplete")]' + '//li[contains(text(),"(teacher0")]'))) teacher_name = element.text.split(' (')[0] element.click() # check that the teacher has been added to the table print(teacher_name) admin.wait.until( expect.visibility_of_element_located( (By.XPATH, '//td[contains(text(),"' + teacher_name + '")]'))) self.ps.test_updates['passed'] = True # Case C7771 - 021 - Teacher | Login with an Existing OpenStax Account @pytest.mark.skipif(str(7771) not in TESTS, reason='Excluded') def test_teacher_login_with_an_existing_openstax_account_7771(self): """Log in with an Existing OpenStax Accounts username. Steps: Go to the recruitment website ( http://cc.openstax.org/ ) Click on faculty login You are redirected to the accounts page. Enter a username and password click on Login. Expected Result: Login should be successful. It should take you to the teacher course picker/dashboard page. """ self.ps.test_updates['name'] = 'cc1.01.021' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.021', '7771'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get(self.teacher.url) self.teacher.page.wait_for_page_load() # check to see if the screen width is normal or condensed if self.teacher.driver.get_window_size()['width'] <= \ self.teacher.CONDENSED_WIDTH: # get small-window menu toggle is_collapsed = self.teacher.find( By.XPATH, '//button[contains(@class,"navbar-toggle")]') # check if the menu is collapsed and, if yes, open it if ('collapsed' in is_collapsed.get_attribute('class')): is_collapsed.click() self.teacher.wait.until( expect.visibility_of_element_located( (By.LINK_TEXT, 'Log in'))).click() self.teacher.page.wait_for_page_load() self.teacher.find(By.ID, 'login_username_or_email').send_keys( self.teacher.username) self.teacher.find(By.CSS_SELECTOR, '.primary').click() self.teacher.find(By.ID, 'login_password').send_keys(self.teacher.password) self.teacher.find(By.CSS_SELECTOR, '.primary').click() self.teacher.page.wait_for_page_load() # check if a password change is required if 'reset your password' in self.teacher.driver.page_source.lower(): try: self.teacher.find(By.ID, 'set_password_password') \ .send_keys(self.teacher.password) self.teacher.find( By.ID, 'set_password_password_confirmation') \ .send_keys(self.teacher.password) self.teacher.find(By.CSS_SELECTOR, '.primary').click() self.teacher.sleep(1) self.teacher.find(By.CSS_SELECTOR, '.primary').click() except Exception as e: raise e self.teacher.page.wait_for_page_load() source = self.teacher.driver.page_source.lower() print('Reached Terms/Privacy') while 'terms of use' in source or 'privacy policy' in source: self.teacher.accept_contract() self.teacher.page.wait_for_page_load() source = self.teacher.driver.page_source.lower() assert('dashboard' in self.teacher.current_url()),\ 'Not taken to dashboard: %s' % self.teacher.current_url() self.ps.test_updates['passed'] = True # Case C7772 - 022 - Teacher | Access the Concept Coach course @pytest.mark.skipif(str(7772) not in TESTS, reason='Excluded') def test_teacher_access_the_cc_course_7772(self): """Access the Concept Coach course. Steps: Once you login you will be taken to a course picker page. Click on the course you want to check the dashboard Expected Result: At Concept Coach teacher dashboard """ self.ps.test_updates['name'] = 'cc1.01.022' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = ['cc1', 'cc1.01', 'cc1.01.022', '7772'] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.get('https://cc.openstax.org/') self.teacher.sleep(2) try: self.teacher.find(By.CSS_SELECTOR, '#headerNav [href*="tutor"]').click() except: self.teacher.find_all(By.CSS_SELECTOR, '.mobile-nav-toggle-label')[1].click() self.teacher.sleep(0.5) self.teacher.find(By.CSS_SELECTOR, '#sidecarNav [href*="tutor"]').click() self.teacher.login() courses = self.teacher.find_all( By.XPATH, '//*[@class="course-listing-current"]' + '//a[p[contains(text(),"Concept Coach")]]') if not isinstance(courses, list): courses.click() elif len(courses) == 1: courses[0].click() else: course_id = randint(0, len(courses)) print(len(courses), course_id, courses) courses[course_id].click() self.teacher.page.wait_for_page_load() self.teacher.wait.until( expect.presence_of_element_located( (By.XPATH, '//span[contains(text(),"Class Dashboard")]'))) self.ps.test_updates['passed'] = True ''' # Case C7773 - 023 - Admin | Distribute access codes for the course @pytest.mark.skipif(str(7773) not in TESTS, reason='Excluded') def test_admin_distribute_access_codes_for_the_course_7773(self): """Distribute access codes for the teacher's course. Steps: CC approves a faculty. Login as admin Click on user menu Click on Admin Click on Salesforce tab Click on import [Do not check the box] This will automatically create a course for the teacher created. Email is sent to the email id used when signing up with the unique course URL. Expected Result: Instructors are emailed the unique course url to the address provided when they signed up. """ self.ps.test_updates['name'] = 'cc1.01.023' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.023', '7773' ] self.ps.test_updates['passed'] = False raise NotImplementedError(inspect.currentframe().f_code.co_name) # Test steps and verification assertions admin = None if not LOCAL_RUN: admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, pasta_user=self.ps, capabilities=self.desired_capabilities ) else: admin = Admin( use_env_vars=True, existing_driver=self.teacher.driver, ) admin.login() admin.open_user_menu() admin.find(By.LINK_TEXT, 'Admin').click() admin.page.wait_for_page_load() admin.find(By.LINK_TEXT, 'Salesforce').click() admin.page.wait_for_page_load() admin.find( By.XPATH, '//input[@vale="Import Courses"]' ).click() self.ps.test_updates['passed'] = True ''' ''' # Case C7774 - 024 - Teacher | Access CC help and support during the course @pytest.mark.skipif(str(7774) not in TESTS, reason='Excluded') def test_teacher_acccess_cc_help_and_support_during_the_course_7774(self): """Access Concept Coach help and support during the course. Steps: Login as teacher Click on the course name On dashboard click on the name of the teacher It drops down and displays several options. Click on Get Help Expected Result: It should open a new tab which shows the openstax.force.com """ self.ps.test_updates['name'] = 'cc1.01.024' \ + inspect.currentframe().f_code.co_name[4:] self.ps.test_updates['tags'] = [ 'cc1', 'cc1.01', 'cc1.01.024', '7774' ] self.ps.test_updates['passed'] = False # Test steps and verification assertions self.teacher.username = os.getenv('TEACHER_USER_CC') self.teacher.login() self.teacher.find( By.XPATH, '//div[text()="Concept Coach"]/preceding-sibling::a' ).click() self.teacher.wait.until( expect.presence_of_element_located( (By.CSS_SELECTOR, 'div.hide-section-legend') ) ) self.teacher.open_user_menu() support = self.teacher.find( By.XPATH, '//a[contains(text(),"Get Help")]' ) support_link = support.get_attribute('href') Assignment.scroll_to(self.teacher.driver, support) support.click() handles = len(self.teacher.driver.window_handles) if handles <= 1: self.teacher.driver.execute_script("window.open('');") window_with_help = self.teacher.driver.window_handles[1] self.teacher.driver.switch_to_window(window_with_help) if handles <= 1: self.teacher.get(support_link) self.teacher.page.wait_for_page_load() self.teacher.find( By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]' ).click() self.ps.test_updates['passed'] = True ''' '''