def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     if not LOCAL_RUN:
         self.teacher = Teacher(
             use_env_vars=True,
             pasta_user=self.ps,
             capabilities=self.desired_capabilities
         )
         self.student = Student(
             use_env_vars=True,
             existing_driver=self.teacher.driver,
             pasta_user=self.ps,
             capabilities=self.desired_capabilities
         )
         self.admin = Admin(
             use_env_vars=True,
             existing_driver=self.teacher.driver,
             pasta_user=self.ps,
             capabilities=self.desired_capabilities
         )
     else:
         self.teacher = Teacher(
             use_env_vars=True
         )
         self.student = Student(
             use_env_vars=True,
             existing_driver=self.teacher.driver,
         )
         self.admin = Admin(
             use_env_vars=True,
             existing_driver=self.teacher.driver,
         )
 def 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 setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(
                use_env_vars=True,
                pasta_user=self.ps,
                capabilities=self.desired_capabilities
            )
        else:
            self.teacher = Teacher(
                use_env_vars=True
            )
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)


        self.teacher.login()

        # go to student scores
        self.teacher.select_course(appearance='biology')
        self.teacher.driver.find_element(
            By.LINK_TEXT, 'Student Scores').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(), "Student Scores")]')
            )
        ).click()
Example #4
0
 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)
Example #5
0
    def test_teacher_bypass_the_course_picker_8257(self):
        """Bypass the course picker.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account [ qateacher | password ] in the
            username and password text boxes
        Click on the 'Sign in' button

        Expected Result:
        The user bypasses the course picker and is presented with the
        calendar dashboard (because qateacher only has one course)
        """
        self.ps.test_updates['name'] = 't1.38.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.004',
            '8257'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login(username="******")
        assert('calendar' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True
Example #6
0
    def test_teacher_select_a_course_8256(self):
        """Select a course.

        Steps:
        Click on a Tutor course name

        Expected Result:
        The user selects a course and is presented with the calendar dashboard
        """
        self.ps.test_updates['name'] = 't1.38.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.003',
            '8256'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login()
        self.user.select_course(appearance='physics')
        assert('calendar' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True
Example #7
0
 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')
Example #8
0
class TestEpicName(unittest.TestCase):
    """Product.Epic - Epic Text."""

    def setUp(self):
        """Pretest settings."""

        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(
                use_env_vars=True,
                pasta_user=self.ps,
                capabilities=self.desired_capabilities
            )
        else:
            self.teacher = Teacher(
                use_env_vars=True
            )

    def tearDown(self):
        """Test destructor."""
        if not LOCAL_RUN:
            self.ps.update_job(
                job_id=str(self.teacher.driver.session_id),
                **self.ps.test_updates
            )
        try:
            self.teacher.delete()
        except:
            pass

    # Case CaseID - Story# - UserType
    @pytest.mark.skipif(str(CaseID) not in TESTS, reason='Excluded')
    def test_usertype_storytext_CaseID(self):
        """Story Text.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 'product.epic.story' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'product',
            'product.epic',
            'product.epic.story',
            'CaseID'
        ]
        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
Example #9
0
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.teacher = Teacher(use_env_vars=True,
                            pasta_user=self.ps,
                            capabilities=self.desired_capabilities)
     self.teacher.login()
     self.teacher.driver.find_element(
         By.XPATH, '//a[contains(@href,"/cc-dashboard")]').click()
Example #10
0
 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
Example #11
0
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.teacher = Teacher(
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.teacher.login()
     self.teacher.select_course(appearance='biology')
     self.teacher.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
 def 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')
class TestImproveCourseManagement(unittest.TestCase):
    """T2.07 - Improve Course Management."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(use_env_vars=True,
                               pasta_user=self.ps,
                               capabilities=self.desired_capabilities)
        self.admin = Admin(use_env_vars=True,
                           pasta_user=self.ps,
                           capabilities=self.desired_capabilities,
                           existing_driver=self.teacher.driver)

    def tearDown(self):
        """Test destructor."""
        if not LOCAL_RUN:
            self.ps.update_job(job_id=str(self.teacher.driver.session_id),
                               **self.ps.test_updates)
        self.admin = None
        try:
            self.teacher.delete()
        except:
            pass

    def test_view_stats_admin(self):
        """
        Log in as Admin
        Click on User Menu for drop-down
        Click on 'Admin' on user menu
        Click "Stats"
        Click "Concept Coach"
        ***The user is presented with Concept Coach Statistics (t2.07.01)***

        Corresponds to...
        t2.07.01
        :return:
        """
        # t2.07.01 --> The user is presented with Concept Coach Statistics
        self.admin.login()
        self.admin.goto_admin_control()
        self.admin.sleep(5)
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Stats'))).click()
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Concept Coach'))).click()

        assert ('/stats/concept_coach' in self.admin.current_url()), \
            'Not viewing Concept Coach stats'
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     if not LOCAL_RUN:
         self.teacher = Teacher(username=os.getenv('TEACHER_USER_CC'),
                                password=os.getenv('TEACHER_PASSWORD'),
                                pasta_user=self.ps,
                                capabilities=self.desired_capabilities)
     else:
         self.teacher = Teacher(
             username=os.getenv('TEACHER_USER_CC'),
             password=os.getenv('TEACHER_PASSWORD'),
         )
     self.teacher.login()
     if 'cc-dashboard' not in self.teacher.current_url():
         courses = self.teacher.find_all(By.CLASS_NAME,
                                         'tutor-booksplash-course-item')
         assert (courses), 'No courses found.'
         if not isinstance(courses, list):
             courses = [courses]
         course_id = randint(0, len(courses) - 1)
         self.course = courses[course_id].get_attribute('data-title')
         self.teacher.select_course(title=self.course)
     self.teacher.goto_course_roster()
     try:
         section = self.teacher.find_all(
             By.XPATH, '//*[contains(@class,"nav-tabs")]//a')
         if isinstance(section, list):
             section = '%s' % section[randint(0, len(section) - 1)].text
         else:
             section = '%s' % section.text
     except Exception:
         section = '%s' % randint(100, 999)
         self.teacher.add_course_section(section)
     self.code = self.teacher.get_enrollment_code(section)
     print('Course Phrase: ' + self.code)
     self.book_url = self.teacher.find(
         By.XPATH,
         '//a[span[contains(text(),"Online Book")]]').get_attribute('href')
     self.teacher.find(By.CSS_SELECTOR, 'button.close').click()
     self.teacher.sleep(0.5)
     self.teacher.logout()
     self.teacher.sleep(1)
     self.student = Student(use_env_vars=True,
                            existing_driver=self.teacher.driver)
     self.first_name = Assignment.rword(6)
     self.last_name = Assignment.rword(8)
     self.email = self.first_name + '.' \
         + self.last_name \
         + '@tutor.openstax.org'
class TestEpicName(unittest.TestCase):
    """Product.Epic - Epic Text."""

    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
        )

    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 CaseID - Story# - UserType
    @pytest.mark.skipif(str(CaseID) not in TESTS, reason='Excluded')
    def test_usertype_storytext_CaseID(self):
        """Story Text.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 'product.epic.story' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'product',
            'product.epic',
            'product.epic.story',
            'CaseID'
        ]
        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
Example #16
0
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.teacher = Teacher(use_env_vars=True,
                            pasta_user=self.ps,
                            capabilities=self.desired_capabilities)
     self.teacher.login()
     self.teacher.select_course(appearance='physics')
     self.teacher.open_user_menu()
     self.teacher.wait.until(
         expect.element_to_be_clickable(
             (By.LINK_TEXT, 'Course Settings and Roster'))).click()
     self.teacher.page.wait_for_page_load()
Example #17
0
class TestStaxingConceptCoachTeacher(unittest.TestCase):
    """Staxing case tests."""

    def setUp(self):
        """Pretest settings."""
        self.teacher = Teacher(username='', password='', site='')
        self.teacher.set_window_size(height=700, width=1200)

    def tearDown(self):
        """Test destructor."""
        try:
            self.teacher.driver.quit()
        except:
            pass
    def test_student_select_a_course_8254(self):
        """Select a course.

        Steps:
        Click on a Tutor course name

        Expected Result:
        The user selects a course and is presented with the dashboard.
        """
        self.ps.test_updates['name'] = 't1.38.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.001',
            '8254'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Student(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login()
        self.user.select_course(appearance='physics')

        assert('list' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.admin = Admin(
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.content = ContentQA(
         existing_driver=self.admin.driver,
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.student = Student(
         existing_driver=self.admin.driver,
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.teacher = Teacher(
         existing_driver=self.admin.driver,
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
Example #20
0
    def test_student_bypass_the_course_picker_8255(self):
        """Bypass the course picker.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account qas_01
        Click on the 'Sign in' button

        Expected Result:
        The user bypasses the course picker and is presented with the
        dashboard (because qas_01 is only enrolled in one course)
        """
        self.ps.test_updates['name'] = 't1.38.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.002',
            '8255'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Student(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login(username="******")
        assert('list' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True
Example #21
0
 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 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 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
     )
Example #24
0
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.admin = Admin(use_env_vars=True,
                        pasta_user=self.ps,
                        capabilities=self.desired_capabilities)
     self.content = ContentQA(existing_driver=self.admin.driver,
                              use_env_vars=True,
                              pasta_user=self.ps,
                              capabilities=self.desired_capabilities)
     self.student = Student(existing_driver=self.admin.driver,
                            use_env_vars=True,
                            pasta_user=self.ps,
                            capabilities=self.desired_capabilities)
     self.teacher = Teacher(existing_driver=self.admin.driver,
                            use_env_vars=True,
                            pasta_user=self.ps,
                            capabilities=self.desired_capabilities)
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     if not LOCAL_RUN:
         self.teacher = Teacher(
             use_env_vars=True,
             pasta_user=self.ps,
             capabilities=self.desired_capabilities
         )
     else:
         self.teacher = Teacher(
             use_env_vars=True
         )
     self.teacher.login()
     self.teacher.driver.find_element(
         By.XPATH,
         '//p[contains(text(),"OpenStax Concept Coach")]'
     ).click()
 def 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 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
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.teacher = Teacher(
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.teacher.login()
     self.teacher.driver.find_element(
         By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
     ).click()
Example #29
0
    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 setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.teacher = Teacher(
         username=os.getenv('TEACHER_USER_CC'),
         password=os.getenv('TEACHER_PASSWORD'),
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.teacher.login()
     if 'cc-dashboard' not in self.teacher.current_url():
         courses = self.teacher.find_all(
             By.CLASS_NAME,
             'tutor-booksplash-course-item'
         )
         assert(courses), 'No courses found.'
         if not isinstance(courses, list):
             courses = [courses]
         course_id = randint(0, len(courses) - 1)
         self.course = courses[course_id].get_attribute('data-title')
         self.teacher.select_course(title=self.course)
     self.teacher.goto_course_roster()
     try:
         section = self.teacher.find_all(
             By.XPATH,
             '//*[contains(@class,"nav-tabs")]//a'
         )
         if isinstance(section, list):
             section = '%s' % section[randint(0, len(section) - 1)].text
         else:
             section = '%s' % section.text
     except Exception:
         section = '%s' % randint(100, 999)
         self.teacher.add_course_section(section)
     self.code = self.teacher.get_enrollment_code(section)
     print('Course Phrase: ' + self.code)
     self.book_url = self.teacher.find(
         By.XPATH, '//a[span[contains(text(),"Online Book")]]'
     ).get_attribute('href')
     self.teacher.find(By.CSS_SELECTOR, 'button.close').click()
     self.teacher.sleep(0.5)
     self.teacher.logout()
     self.teacher.sleep(1)
     self.student = Student(use_env_vars=True,
                            existing_driver=self.teacher.driver)
     self.first_name = Assignment.rword(6)
     self.last_name = Assignment.rword(8)
     self.email = self.first_name + '.' \
         + self.last_name \
         + '@tutor.openstax.org'
    def test_teacher_able_to_search_within_the_book_7629(self):
        """Able to search within the book.

        Steps:
        Go to tutor-qa
        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 "Online Book" in the header
        Enter search words into the search engine next to the "Contents" button

        Expected Result:
        The search word is highlighted in yellow within the text and is bolded
        within the table of contents
        """
        self.ps.test_updates['name'] = 'cc1.05.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.05', 'cc1.05.005', '7629']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        teacher = Teacher(
            existing_driver=self.student.driver,
            username=os.getenv('TEACHER_USER'),
            password=os.getenv('TEACHER_PASSWORD'),
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
        )
        teacher.login()
        teacher.driver.find_element(
            By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click()
        teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a//span[contains(text(),"Online Book")]'))).click()
        window_with_book = teacher.driver.window_handles[1]
        teacher.driver.switch_to_window(window_with_book)
        assert('cnx' in teacher.current_url()), \
            'Not viewing the textbook PDF'
        teacher.page.wait_for_page_load()
        teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//input[@placeholder="Search this book"]'
                 ))).send_keys('balance' + Keys.ENTER)
        # make sure the search worked
        # still passes if no results found and it says: No matching results...
        teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="result-count"]')))
        teacher.delete()
        self.ps.test_updates['passed'] = True
Example #32
0
    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
 def setUp(self):
     """Pretest settings."""
     self.ps = PastaSauce()
     self.desired_capabilities['name'] = self.id()
     self.teacher = Teacher(
         use_env_vars=True,
         pasta_user=self.ps,
         capabilities=self.desired_capabilities
     )
     self.teacher.login()
     self.teacher.select_course(appearance='physics')
     self.teacher.open_user_menu()
     self.teacher.wait.until(
         expect.element_to_be_clickable(
             (By.LINK_TEXT, 'Course Settings and Roster')
         )
     ).click()
     self.teacher.page.wait_for_page_load()
 def 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 test_teacher_able_to_search_within_the_book_7629(self):
        """Able to search within the book.

        Steps:
        Go to tutor-qa
        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 "Online Book" in the header
        Enter search words into the search engine next to the "Contents" button

        Expected Result:
        The search word is highlighted in yellow within the text and is bolded
        within the table of contents
        """
        self.ps.test_updates["name"] = "cc1.05.005" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["cc1", "cc1.05", "cc1.05.005", "7629"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        teacher = Teacher(
            existing_driver=self.student.driver,
            username=os.getenv("TEACHER_USER"),
            password=os.getenv("TEACHER_PASSWORD"),
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
        )
        teacher.login()
        teacher.driver.find_element(By.XPATH, '//a[contains(@href,"/cc-dashboard/")]').click()
        teacher.wait.until(
            expect.visibility_of_element_located((By.XPATH, '//a//span[contains(text(),"Online Book")]'))
        ).click()
        window_with_book = teacher.driver.window_handles[1]
        teacher.driver.switch_to_window(window_with_book)
        assert "cnx" in teacher.current_url(), "Not viewing the textbook PDF"
        teacher.page.wait_for_page_load()
        teacher.wait.until(
            expect.visibility_of_element_located((By.XPATH, '//input[@placeholder="Search this book"]'))
        ).send_keys("balance" + Keys.ENTER)
        # make sure the search worked
        # still passes if no results found and it says: No matching results...
        teacher.wait.until(expect.visibility_of_element_located((By.XPATH, '//div[@class="result-count"]')))
        teacher.delete()
        self.ps.test_updates["passed"] = True
Example #36
0
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 TestAnalyzeCollegeWorkflow(unittest.TestCase):
    """T2.05 - Analyze College Workflow."""

    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,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
            existing_driver=self.teacher.driver
        )

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.teacher.driver.session_id),
            **self.ps.test_updates
        )
        try:
            self.student = None
            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(appearance='physics')
        assert('list/' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        self.student.sleep(5)

        page = self.student.driver.page_source
        assert('Coming Up' in page or 'No upcoming events' in page), \
            'No Coming Up/No upcoming events text is visible/present'

        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:
        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 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='physics')
        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.ID, 'add-assignment')
            )
        ).click()
        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Add Reading').click()
        assert('readings' in self.teacher.current_url()), \
            'Not on the add a homework page'

        self.teacher.find(
            By.XPATH, "//input[@id = 'reading-title']").send_keys('Epic 5-4')
        self.teacher.find(
            By.XPATH, "//input[@id = 'hide-periods-radio']").click()

        # Choose the second date calendar[1], first is calendar[0]
        self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__input-container']")[1].click()
        while(self.teacher.find(
            By.XPATH,
            "//span[@class = 'datepicker__current-month']"
        ).text != 'December 2016'):
            self.teacher.find(
                By.XPATH, "//a[@class = 'datepicker__navigation datepicker__" +
                "navigation--next']").click()

        # Choose the due date of December 31, 2016
        weekends = self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__day datepicker__day--weekend']")
        for day in weekends:
            if day.text == '31':
                due = day
                due.click()
                break

        self.teacher.sleep(3)

        # Choose reading sections
        self.teacher.find(
            By.XPATH, "//button[@id='reading-select']").click()
        self.teacher.find(
            By.XPATH, "//span[@class = 'chapter-checkbox']").click()
        self.teacher.find(
            By.XPATH,
            "//button[@class='-show-problems btn btn-primary']").click()
        self.teacher.sleep(10)

        # Publish the assignment
        self.teacher.driver.execute_script('window.scrollBy(0, -200);')
        self.teacher.find(
            By.XPATH,
            "//button[@class='async-button -publish btn btn-primary']").click()

        # Give the assignment time to publish
        self.teacher.sleep(60)

        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        spans = self.teacher.driver.find_elements_by_tag_name('span')
        for element in spans:
            if element.text.endswith('2016'):
                month = element

        # Change the calendar date if necessary
        while (month.text != 'December 2016'):
            self.teacher.find(
                By.XPATH,
                "//a[@class = 'calendar-header-control next']").click()

        # Select the newly created assignment, get the LMS link, and delete it
        assignments = self.teacher.driver.find_elements_by_tag_name('label')
        for assignment in assignments:
            if assignment.text == 'Epic 5-4':
                assignment.click()
                self.teacher.find(
                    By.PARTIAL_LINK_TEXT, "Get assignment link").click()
                self.teacher.find(
                    By.XPATH,
                    "//div[@class = 'fade in lms-sharable-link popover top']")
                self.teacher.sleep(5)
                self.teacher.find(
                    By.XPATH,
                    "//a[@class='btn btn-default -edit-assignment']").click()
                self.teacher.sleep(5)
                self.teacher.find(
                    By.XPATH,
                    "//button[@class='async-button delete-link pull-" +
                    "right btn btn-default']").click()
                self.teacher.find(
                    By.XPATH, "//button[@class='btn btn-primary']").click()
                self.teacher.sleep(5)
                break

        self.teacher.driver.refresh()
        deleted = True

        # Verfiy the assignment was deleted
        spans = self.teacher.driver.find_elements_by_tag_name('span')
        for element in spans:
            if element.text.endswith('2016'):
                month = element

        while (month.text != 'December 2016'):
            self.teacher.find(
                By.XPATH,
                "//a[@class = 'calendar-header-control next']").click()

        assignments = self.teacher.driver.find_elements_by_tag_name('label')
        for assignment in assignments:
            if assignment.text == 'Epic 5-4':
                deleted = False
                break

        if deleted:
            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='physics')
        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.ID, 'add-assignment')
            )
        ).click()
        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Add Homework').click()
        assert('homeworks' in self.teacher.current_url()), \
            'Not on the add a homework page'

        self.teacher.find(
            By.XPATH, "//input[@id = 'reading-title']").send_keys('Epic 5-5')
        self.teacher.find(
            By.XPATH, "//input[@id = 'hide-periods-radio']").click()

        # Choose the second date calendar[1], first is calendar[0]
        self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__input-container']")[1].click()
        while(self.teacher.find(
            By.XPATH,
            "//span[@class = 'datepicker__current-month']"
        ).text != 'December 2016'):
            self.teacher.find(
                By.XPATH, "//a[@class = 'datepicker__navigation datepicker__" +
                "navigation--next']").click()

        # Choose the due date of December 31, 2016
        weekends = self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__day datepicker__day--weekend']")
        for day in weekends:
            if day.text == '31':
                due = day
                due.click()
                break

        self.teacher.sleep(3)

        # Open the select problem cards
        self.teacher.find(
            By.XPATH, "//button[@id = 'problems-select']").click()
        self.teacher.find(
            By.XPATH, "//span[@class = 'chapter-checkbox']").click()
        self.teacher.find(
            By.XPATH,
            "//button[@class='-show-problems btn btn-primary']").click()
        self.teacher.sleep(10)

        # Choose a problem for the assignment
        element = self.teacher.find(
            By.XPATH, "//div[@class = 'controls-overlay'][1]")
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(element)
        actions.perform()
        self.teacher.find(By.XPATH, "//div[@class = 'action include']").click()
        self.teacher.find(
            By.XPATH,
            "//button[@class='-review-exercises btn btn-primary']").click()
        self.teacher.sleep(2)

        # Publish the assignment
        self.teacher.driver.execute_script('window.scrollBy(0, -200);')
        self.teacher.find(
            By.XPATH,
            "//button[@class='async-button -publish btn btn-primary']").click()

        # Give the assignment time to publish
        self.teacher.sleep(60)

        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        spans = self.teacher.driver.find_elements_by_tag_name('span')
        for element in spans:
            if element.text.endswith('2016'):
                month = element

        # Change the calendar date if necessary
        while (month.text != 'December 2016'):
            self.teacher.find(
                By.XPATH,
                "//a[@class = 'calendar-header-control next']").click()

        # Select the newly created assignment, get the LMS link, and delete it
        assignments = self.teacher.driver.find_elements_by_tag_name('label')
        for assignment in assignments:
            if assignment.text == 'Epic 5-5':
                assignment.click()
                self.teacher.find(
                    By.PARTIAL_LINK_TEXT, "Get assignment link").click()
                self.teacher.find(
                    By.XPATH,
                    "//div[@class = 'fade in lms-sharable-link popover top']")
                self.teacher.sleep(5)
                self.teacher.find(
                    By.XPATH,
                    "//a[@class='btn btn-default -edit-assignment']").click()
                self.teacher.sleep(5)
                self.teacher.find(
                    By.XPATH,
                    "//button[@class='async-button delete-link pull-" +
                    "right btn btn-default']").click()
                self.teacher.find(
                    By.XPATH, "//button[@class='btn btn-primary']").click()
                self.teacher.sleep(5)
                break

        self.teacher.driver.refresh()
        deleted = True

        # Verfiy the assignment was deleted
        spans = self.teacher.driver.find_elements_by_tag_name('span')
        for element in spans:
            if element.text.endswith('2016'):
                month = element

        while (month.text != 'December 2016'):
            self.teacher.find(
                By.XPATH,
                "//a[@class = 'calendar-header-control next']").click()

        assignments = self.teacher.driver.find_elements_by_tag_name('label')
        for assignment in assignments:
            if assignment.text == 'Epic 5-5':
                deleted = False
                break

        if deleted:
            self.ps.test_updates['passed'] = True

    # 14650 - 006 - Teacher | View instructions on how to export summary grade
    # for my student's OpenStax practice to my LMS
    @pytest.mark.skipif(str(14650) not in TESTS, reason='Excluded')
    def test_teacher_view_instructions_on_how_to_export_summary_14650(self):
        """View instructions on how to export summary grade into LMS.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.05.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.05',
            't2.05.006',
            '14650'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
class TestTrainingAndSupportingTeachersAndStudents(unittest.TestCase):
    """CC1.14 - Training and Supporting Teachers and Students."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.student = Student(
            use_env_vars=True,
            existing_driver=self.teacher.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.teacher.driver.session_id),
            **self.ps.test_updates
        )
        self.student = None
        try:
            self.teacher.delete()
        except:
            pass

    # Case C7704 - 001 - System | Concept Coach Zendesk is web-accessible
    @pytest.mark.skipif(str(7704) not in TESTS, reason='Excluded')
    def test_system_concept_coach_zendesk_is_web_accessible_7704(self):
        """Concept Coach Zendesk is web-accesible.

        Steps:
        Log in to Tutor as teacher
        If more then one course, click on a concept coach course
        In user menu in top right of header, click 'Get Help'

        Expected Result:
        In a new window or tab, zendesk help is opened
        """
        self.ps.test_updates['name'] = 'cc1.14.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.001',
            '7704'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard/")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_help)
        self.teacher.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.teacher.current_url()), 'not at help center'

        self.ps.test_updates['passed'] = True

    # Case C7705 - 002 - Teacher | Can access user support
    @pytest.mark.skipif(str(7705) not in TESTS, reason='Excluded')
    def test_teacher_can_access_user_support_7705(self):
        """Can access user support.

        Steps:
        Click on the user menu
        Click on the Get Help option

        Expected Result:
        In a new tab or window Zendesk is opened
        """
        self.ps.test_updates['name'] = 'cc1.14.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.002',
            '7705'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard/")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_help)
        self.teacher.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.teacher.current_url()), 'not at help center'

        self.ps.test_updates['passed'] = True

    # Case C7706 - 003 - Student | Can access user support
    @pytest.mark.skipif(str(7706) not in TESTS, reason='Excluded')
    def test_student_can_access_user_support_7706(self):
        """Can access user support.

        Steps:
        Click on the user menu
        Click on the Get Help option

        Expected Result:
        In a new tab or window zendesk is opened
        """
        self.ps.test_updates['name'] = 'cc1.14.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.003',
            '7706'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.open_user_menu()
        self.student.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_help)
        self.student.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.student.current_url()), 'not at help center'
        self.ps.test_updates['passed'] = True

    # Case C7707 - 004 - Non-user | Submit support questions
    @pytest.mark.skipif(str(7707) not in TESTS, reason='Excluded')
    def test_nonuser_submit_support_questions_7707(self):
        """Submit support questions.

        Steps:
        Go to the Concept Coach landing page
        click support in the header
        enter text into the search box
        click contact us
        fillout form
        click Submit

        Expected Result:
        'Message sent' displayed in help box
        """
        self.ps.test_updates['name'] = 'cc1.14.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.004',
            '7707'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.get('http://cc.openstax.org/')
        self.teacher.sleep(1)
        # number hardcoded because condenses at different size than tutor
        if self.teacher.driver.get_window_size()['width'] < 1105:
            element = self.teacher.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//label[@for="mobileNavToggle"]')
                )
            )
            actions = ActionChains(self.teacher.driver)
            # use action chain because it is clicking to the wrong elemnt
            actions.move_to_element(element)
            actions.click()
            actions.perform()
        support = self.teacher.find(
            By.LINK_TEXT, 'support'
        )
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(support)
        actions.click()
        actions.perform()
        window_with_help = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_help)
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.ID, 'searchAskInput'
        ).send_keys('fake_question')
        self.teacher.find(
            By.ID, 'searchAskButton'
        ).click()
        self.teacher.find(
            By.LINK_TEXT, 'Contact Us'
        ).click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]'
        ).send_keys('qa')
        self.teacher.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]'
        ).send_keys('test')
        self.teacher.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:email")]'
        ).send_keys('*****@*****.**')
        self.teacher.find(
            By.XPATH, '//div[@class="submit-container"]//input'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//p[contains(text(),"Thank you")]')
            )
        )
        self.ps.test_updates['passed'] = True

    # Case C7708 - 005 - Teacher | Submit support questions
    @pytest.mark.skipif(str(7708) not in TESTS, reason='Excluded')
    def test_teacher_submit_support_questions_7708(self):
        """Submit support questions.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If user has more than one course, click on a Concept Coach course
        Click the user menu in the right corner of the header
        Click "Get Help"
        Click "Submit a request"
        Fill out all the necessary text fields
        Click "Submit"

        Expected Result:
        The user submits support questions
        """
        self.ps.test_updates['name'] = 'cc1.14.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.005',
            '7708'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard/")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_help)
        self.teacher.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.teacher.current_url()), 'not at help center'
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.ID, 'searchAskInput'
        ).send_keys('fake_question')
        self.teacher.find(
            By.ID, 'searchAskButton'
        ).click()
        self.teacher.find(
            By.LINK_TEXT, 'Contact Us'
        ).click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]'
        ).send_keys('qa')
        self.teacher.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]'
        ).send_keys('test')
        self.teacher.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:email")]'
        ).send_keys('*****@*****.**')
        self.teacher.find(
            By.XPATH, '//div[@class="submit-container"]//input'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//p[contains(text(),"Thank you")]')
            )
        )
        self.ps.test_updates['passed'] = True

    # Case C7709 - 006 - Student | Submit support questions
    @pytest.mark.skipif(str(7709) not in TESTS, reason='Excluded')
    def test_student_submit_support_questions_7709(self):
        """Submit support questions.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        Click the user menu in the right corner of the header
        Click "Get Help"
        Click "Submit a request"
        Fill out all the necessary text fields
        Click "Submit"

        Expected Result:
        The user submits support questions
        """
        self.ps.test_updates['name'] = 'cc1.14.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.006',
            '7709'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.open_user_menu()
        self.student.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_help)
        self.student.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.student.current_url()), 'not at help center'
        self.student.page.wait_for_page_load()
        self.student.find(
            By.ID, 'searchAskInput'
        ).send_keys('fake_question')
        self.student.find(
            By.ID, 'searchAskButton'
        ).click()
        self.student.find(
            By.LINK_TEXT, 'Contact Us'
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:firstName")]'
        ).send_keys('qa')
        self.student.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:lastName")]'
        ).send_keys('test')
        self.student.find(
            By.XPATH, '//input[contains(@id,"contactUsForm:email")]'
        ).send_keys('*****@*****.**')
        self.student.find(
            By.XPATH, '//div[@class="submit-container"]//input'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//p[contains(text(),"Thank you")]')
            )
        )

        self.ps.test_updates['passed'] = True

    # Case C7710 - 007 - Teacher | View instructions on how to use CC
    @pytest.mark.skipif(str(7710) not in TESTS, reason='Excluded')
    def test_teacher_view_instructions_on_how_to_use_cc_7710(self):
        """View instructions on how to use Concept Coach.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If user has more than one course, click on a Concept Coach course
        Click the user menu in the right corner of the header
        Click "Get Help"
        Click "Getting Started Guide"
        * Click on the pdf link
            OR
        * Click "Getting Started" from the user menu

        Expected Result:
        The user is presented with a guide to use CC
        """
        self.ps.test_updates['name'] = 'cc1.14.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.007',
            '7710'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard/")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Getting Started'
        ).click()
        self.teacher.find(
            By.XPATH, '//h3[contains(text(),"Getting Started")]'
        ).click()
        assert('help' in self.teacher.current_url()), 'not at help center'

        self.ps.test_updates['passed'] = True

    # Case C7711 - 008 - Student | View instructions on how to use CC
    @pytest.mark.skipif(str(7711) not in TESTS, reason='Excluded')
    def test_student_view_instructions_on_how_to_use_cc_7711(self):
        """View instructions on how to use Concept Coach.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        Click the user menu in the right corner of the header
        Click "Get Help"
        Scroll down to the questions under "Students"

        Expected Result:
        The user is presented with instructions on how to use CC
        """
        self.ps.test_updates['name'] = 'cc1.14.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.008',
            '7711'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.open_user_menu()
        self.student.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_help)
        self.student.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.student.current_url()), 'not at help center'
        self.ps.test_updates['passed'] = True

    # Case C7712 - 009 - Teacher | View instructions on how to assign CC
    @pytest.mark.skipif(str(7712) not in TESTS, reason='Excluded')
    def test_teacher_view_instructions_on_how_to_assign_cc_7712(self):
        """View instructions on how to use Concept Coach.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If user has more than one course, click on a Concept Coach course
        Click the user menu in the right corner of the header
        Click "Get Help"

        Expected Result:
        Taken to Zendesk in a new window or tab
        Assorted help is displayed
        """
        self.ps.test_updates['name'] = 'cc1.14.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.009',
            '7712'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard/")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Get Help'
        ).click()
        # change to window with help center
        window_with_help = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_help)
        self.teacher.find(
            By.XPATH, '//center[contains(text(),"Concept Coach Help Center")]'
        )
        assert('support' in self.teacher.current_url()), 'not at help center'

        self.ps.test_updates['passed'] = True

    # Case C7713 - 010 - Student | Get help during account registration
    @pytest.mark.skipif(str(7713) not in TESTS, reason='Excluded')
    def test_student_get_help_during_account_registration_7713(self):
        """View instructions on how to use Concept Coach.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 'cc1.14.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.010',
            '7713'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # Case C7714 - 011 - Teacher | View instructions for Legacy users
    # transitioning to Concept Coach
    @pytest.mark.skipif(str(7714) not in TESTS, reason='Excluded')
    def test_teacher_view_instructions_for_legacy_users_transition_7714(self):
        """View instructions for Legacy users transitioning to Concept Coach.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 'cc1.14.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.14',
            'cc1.14.011',
            '7714'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
class TestImprovesScoresReporting(unittest.TestCase):
    """CC2.08 - Improves Scores Reporting."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
        else:
            self.teacher = Teacher(use_env_vars=True)
        self.teacher.login()
        self.teacher.find(By.XPATH,
                          '//a[contains(@href,"/cc-dashboard")]').click()

    def tearDown(self):
        """Test destructor."""
        if not LOCAL_RUN:
            self.ps.update_job(job_id=str(self.teacher.driver.session_id),
                               **self.ps.test_updates)
        try:
            self.teacher.delete()
        except:
            pass

    # 14806 - 001 - Teacher | View student scores as percent complete
    @pytest.mark.skipif(str(14806) not in TESTS, reason='Excluded')
    def test_teacher_view_student_scores_as_percent_complete_14806(self):
        """View student scores as percent complete.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores"
        Click on the icon in the progress column

        Expected Result:
        Student Scores are presented as percent complete
        """
        self.ps.test_updates['name'] = 'cc2.08.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.001', '14806']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(By.XPATH,
                          '//button[contains(text(),"percentage")]').click()
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"score")]//a[contains(text(),"%")]')
        self.ps.test_updates['passed'] = True

    # 14807 - 002 - Teacher | View student scores as number of total
    @pytest.mark.skipif(str(14807) not in TESTS, reason='Excluded')
    def test_teacher_view_student_scores_as_number_of_total_14807(self):
        """View student scores as number of total.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores"
        Click "Number"

        Expected Result:
        Student Scores are presented as "Number of Total"
        """
        self.ps.test_updates['name'] = 'cc2.08.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.002', '14807']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(By.XPATH,
                          '//button[contains(text(),"number")]').click()
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"score")]//a[contains(text()," of ")]')

        self.ps.test_updates['passed'] = True

    # 14808 - 003 - Teacher | View tooltips on hover
    @pytest.mark.skipif(str(14808) not in TESTS, reason='Excluded')
    def test_teacher_view_tooltips_on_hover_14808(self):
        """View tooltips on hover.

        Steps:
        If the user has more than one course, click on a CC course name
        Hover over the info icons

        Expected Result:
        The user is presented with tooltips
        """
        self.ps.test_updates['name'] = 'cc2.08.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.003', '14808']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(By.XPATH, '//i[@type="info-circle"]').click()
        self.teacher.find(
            By.XPATH, '//h3[@class="popover-title" and ' +
            'contains(text(), "Class and Overall Averages")]')
        self.ps.test_updates['passed'] = True

    # 14810 - 004 - Teacher | Sort student scores based on score
    @pytest.mark.skipif(str(14810) not in TESTS, reason='Excluded')
    def test_teacher_sort_student_scores_based_on_score_14810(self):
        """Sort student scores based on score.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores"
        Click "Score" for the desired assignment

        Expected Result:
        Students are sorted based on score
        """
        self.ps.test_updates['name'] = 'cc2.08.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.004', '14810']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"sortable")]//div[text()="Score"]').click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"is-descending")]//div[text()="Score"]'
        ).click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"is-ascending")]//div[text()="Score"]')
        self.ps.test_updates['passed'] = True

    # 14811 - 005 - Teacher | Sort student scores based on number complete
    @pytest.mark.skipif(str(14811) not in TESTS, reason='Excluded')
    def test_teacher_sort_student_scores_based_on_number_completed_14811(self):
        """Sort student scores based on number complete.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores"
        Click "Progress" for the desired assignment

        Expected Result:
        Students are sorted based on number completed
        """
        self.ps.test_updates['name'] = 'cc2.08.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.005', '14811']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"sortable")]//div[text()="Progress"]'
        ).click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"is-descending")]//div[text()="Progress"]'
        ).click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"is-ascending")]//div[text()="Progress"]')
        self.ps.test_updates['passed'] = True

    # 14668 - 006 - Teacher | All popups in the roster have an X button
    @pytest.mark.skipif(str(14668) not in TESTS, reason='Excluded')
    def test_teacher_all_popups_in_the_roster_have_an_x_button_14668(self):
        """All popups in the roster have an X button.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Course Settings and Roster" from the user menu
        Click "Rename Course," "Change Course Timezone,"
        "View Archived Period," "Add Period," "Rename," and "Get Student
            Enrollment Code"

        Expected Result:
        All pop ups have an X button
        """
        self.ps.test_updates['name'] = 'cc2.08.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.006', '14668']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.find(By.XPATH,
                          '//a[text()="Course Settings and Roster"]').click()
        self.teacher.sleep(1)
        # rename couse
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"Rename Course")]').click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[@class="modal-content"]//button[@class="close"]').click()
        self.teacher.sleep(0.75)
        # course timezone
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"Change Course Timezone")]').click(
            )
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH,
            '//div[@class="modal-content"]//button[@class="close"]').click()
        self.teacher.sleep(0.75)
        # add period/section
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"add-period")]//button').click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[@class="modal-content"]//button[@class="close"]').click()
        self.teacher.sleep(0.75)
        # rename period
        self.teacher.find(
            By.XPATH,
            '//span[contains(@class,"rename-period")]//button').click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[@class="modal-content"]//button[@class="close"]').click()
        self.teacher.sleep(0.75)
        # student enrollemnt code
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"Your student enrollment code")]'
        ).click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[@class="modal-content"]//button[@class="close"]').click()
        self.teacher.sleep(0.75)
        # View Archived periods
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"View Archived ")]').click()
        self.teacher.sleep(0.75)
        self.teacher.find(
            By.XPATH,
            '//div[@class="modal-content"]//button[@class="close"]').click()
        self.ps.test_updates['passed'] = True

    # 14670 - 007 - Teacher | Close popup with X button
    @pytest.mark.skipif(str(14670) not in TESTS, reason='Excluded')
    def test_teacher_close_popup_with_x_button_14670(self):
        """Close popup with X button.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Course Settings and Roster" from the user menu
        Click ONE of the following:
        * Rename Course
        * Change Course Timezone
        * View Archived Period
        * Add Period
        * Rename
        * Get Student Enrollment Code
        Click the X on the pop up

        Expected Result:
        Popup is closed
        """
        self.ps.test_updates['name'] = 'cc2.08.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.007', '14670']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.find(By.XPATH,
                          '//a[text()="Course Settings and Roster"]').click()
        self.teacher.sleep(1)
        # rename couse
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button//span[contains(text(),"Rename Course")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//button[@class="close"]'
                 ))).click()
        self.teacher.sleep(1)
        with self.assertRaises(NoSuchElementException):
            self.teacher.find(By.XPATH, '//div[@class="modal-content"]')
        # course timezone
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"Change Course Timezone")]').click(
            )
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//button[@class="close"]'
                 ))).click()
        self.teacher.sleep(1)
        with self.assertRaises(NoSuchElementException):
            self.teacher.find(By.XPATH, '//div[@class="modal-content"]')
        # add period/section
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"add-period")]//button').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//button[@class="close"]'
                 ))).click()
        self.teacher.sleep(1)
        with self.assertRaises(NoSuchElementException):
            self.teacher.find(By.XPATH, '//div[@class="modal-content"]')
        # rename period
        self.teacher.find(
            By.XPATH,
            '//span[contains(@class,"rename-period")]//button').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//button[@class="close"]'
                 ))).click()
        self.teacher.sleep(1)
        with self.assertRaises(NoSuchElementException):
            self.teacher.find(By.XPATH, '//div[@class="modal-content"]')
        # student enrollemnt code
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"Your student enrollment code")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//button[@class="close"]'
                 ))).click()
        self.teacher.sleep(1)
        with self.assertRaises(NoSuchElementException):
            self.teacher.find(By.XPATH, '//div[@class="modal-content"]')
        # View Archived Periods
        self.teacher.find(
            By.XPATH,
            '//button//span[contains(text(),"View Archived")]').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//button[@class="close"]'
                 ))).click()
        self.teacher.sleep(1)
        with self.assertRaises(NoSuchElementException):
            self.teacher.find(By.XPATH, '//div[@class="modal-content"]')

        self.ps.test_updates['passed'] = True

    # 14669 - 008 - Teacher | The icon in the progress column shows info on
    # percentage complete, attempted out of total possible questions, and
    # the date last worked
    @pytest.mark.skipif(str(14669) not in TESTS, reason='Excluded')
    def test_teacher_the_icon_in_the_progress_column_shows_info_14669(self):
        """The icon in the progress column shows info.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores"
        Click on the icon in the progress column for a completed assignment

        Expected Result:
        Shows information on percentage complete, attempted out of total
        possible questions as well as the date last worked
        """
        self.ps.test_updates['name'] = 'cc2.08.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.008', '14669']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        icon = self.teacher.find(
            By.XPATH,
            '//span[contains(@aria-describedby,"scores-cell-info-popover")]')
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(icon)
        actions.perform()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[contains(@id,"scores-cell-info-popover")]'))).click()
        # more on each individial thing
        self.ps.test_updates['passed'] = True

    '''
    # 14812 - 009 - Teacher | Import CC Student Scores export into an LMS
    @pytest.mark.skipif(str(14812) not in TESTS, reason='Excluded')
    def test_teacher_import_cc_student_scores_export_into_an_lms_14812(self):
        """Import CC student scores export into an LMS.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 'cc2.08.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.009', '14812']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
    '''

    # 14813 - 010 - Teacher | View zeros in exported scores instead of blank
    # cells for incomplete assignments
    @pytest.mark.skipif(str(14813) not in TESTS, reason='Excluded')
    def test_teacher_view_zeros_in_exported_scores_instead_of_blan_14813(self):
        """View zeros in exported scores for incomplete assignments.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores"
        Click "Export"
        Open the excel file

        Expected Result:
        For incomplete assignments or assignments that are not started,
        there are zeros instead of blank cells
        """
        self.ps.test_updates['name'] = 'cc2.08.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.010', '14813']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(By.XPATH,
                          '//div[@class="export-button"]//button').click()
        # wait until button return and no longer is loading
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="export-button"]//button' +
                 '/span[text()="Export"]')))
        self.teacher.sleep(2)
        coursename = self.teacher.find(By.XPATH,
                                       '//div[@class="course-name"]').text
        coursename = coursename.replace(' ', '_') + "_Scores"
        home = os.getenv("HOME")
        files = os.listdir(home + '/Downloads')
        file_name = ''
        for i in range(len(files)):
            if (coursename in files[i]) and (files[i][-5:] == '.xlsx'):
                file_name = files[i]
                break
            else:
                if i == len(files) - 1:
                    raise Exception
        period = self.teacher.find(
            By.XPATH, '//span[contains(@class,"tab-item-period-name")]').text
        wb = load_workbook(str(home + '/Downloads/' + file_name))
        sheet = wb[period + ' - %']
        rows = sheet.rows
        start_row = float("inf")
        for i in range(len(sheet.rows)):
            if rows[i][0].value == 'First Name':
                start_row = i
            if i >= start_row:
                if rows[i][4].value == 0:
                    # found that 0% is being used istead of blanks
                    break
                elif rows[i + 1][4].value is None:
                    print('empty cell instead of 0%')
                    raise Exception
        self.ps.test_updates['passed'] = True

    # 14814 - 011 - Teacher | Green check icon is displayed for completed
    # assignments
    @pytest.mark.skipif(str(14814) not in TESTS, reason='Excluded')
    def test_teacher_green_check_icon_is_displayed_for_completed_14814(self):
        """Green check icon is displayed for completed assignments.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores

        Expected Result:
        Green check icon is displayed for completed assignments
        """
        self.ps.test_updates['name'] = 'cc2.08.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.011', '14814']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        # scroll to find a green checkmark
        assignments = self.teacher.find_all(
            By.XPATH,
            "//span[contains(@aria-describedby,'header-cell-title')]")

        for i in range(len(assignments) // 4):
            try:
                self.teacher.find(
                    By.XPATH, '//span[contains(@class,"trig")]' +
                    '//*[contains(@class,"finished")]')
                break
            except (NoSuchElementException, ElementNotVisibleException):
                if i >= (len(assignments) // 4) - 1:
                    print("completed assignments for this period")
                    raise Exception
                # try to drag scroll bar instead of scrolling
                scroll_bar = self.teacher.find(
                    By.XPATH,
                    '//div[contains(@class,"ScrollbarLayout_faceHorizontal")]')
                actions = ActionChains(self.teacher.driver)
                actions.move_to_element(scroll_bar)
                actions.click_and_hold()
                actions.move_by_offset(50, 0)
                actions.release()
                actions.perform()

        self.ps.test_updates['passed'] = True

    '''
    # 14815 - 012 - Teacher | The class average info icon displays a definition
    # about scores from completed assignments
    @pytest.mark.skipif(str(14815) not in TESTS, reason='Excluded')
    def test_teacher_class_average_info_icon_displays_definition_14815(self):
        """The class average info icon displays a definition.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores
        Click on the info icon next to "Class Average"

        Expected Result:
        The class average info icon displays a definition about scores from
        completed assignments
        """
        self.ps.test_updates['name'] = 'cc2.08.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.012', '14815']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(text(),"View Detailed Scores")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')
            )
        )
        self.teacher.find(
            By.XPATH, '//i[@type="info-circle"]').click()
        self.teacher.find(
            By.XPATH,
            '//h3[@class="popover-title" and ' +
            'contains(text(), "Class and Overall Averages")]')

        self.ps.test_updates['passed'] = True
    '''

    # 14816 - 013 - Teacher | View the overall score column
    @pytest.mark.skipif(str(14816) not in TESTS, reason='Excluded')
    def test_teacher_view_the_overall_score_column_14816(self):
        """View the overall score column.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "View Detailed Scores

        Expected Result:
        User is presented with the overall score column next to student names
        """
        self.ps.test_updates['name'] = 'cc2.08.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.08', 'cc2.08.013', '14816']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"View Detailed Scores")]'))).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"Student Scores")]')))
        self.teacher.find(By.XPATH,
                          '//div[contains(@class,"overall-header-cell")]')

        self.ps.test_updates['passed'] = True
class TestGuideMonitorSupportAndTrainUsers(unittest.TestCase):
    """T2.18 - Guide, Monitor, Support, and Train Users."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities["name"] = self.id()
        self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities)

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(job_id=str(self.teacher.driver.session_id), **self.ps.test_updates)
        try:
            self.teacher.delete()
        except:
            pass

    # 14752 - 001 - User | In-app Notification of downtime
    @pytest.mark.skipif(str(14752) not in TESTS, reason="Excluded")
    def test_user_inapp_notification_of_downtime_14752(self):
        """In-app Notification of downtime.

        Steps:

        Go to Tutor
        Log in as admin
        Click "Admin" from the user menu
        Click "System Setting"
        Click "Notifications"
        Enter a new notification into the text box
        Click "Add"
        Log out of admin
        Log in as teacher01

        Expected Result:
        An orange header with the notification pops up when you sign in
        """
        self.ps.test_updates["name"] = "t2.18.001" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.001", "14752"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 14751 - 002 - Teacher | Directed to a "No Courses" page when not in any
    # courses yet
    @pytest.mark.skipif(str(14751) not in TESTS, reason="Excluded")
    def test_teacher_directed_to_a_no_courses_page_when_not_in_any_14751(self):
        """Directed to a "No Courses" page when not in any courses yet.

        Steps:
        Go to tutor-qa.openstax.org
        Sign in as demo_teacher; password

        Expected Result:
        The message "We cannot find an OpenStax course associated with your
        account" displays with help links below
        """
        self.ps.test_updates["name"] = "t2.18.002" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.002", "14751"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58279 - 003 - Teacher | View "Getting Started with Tutor" Guide
    @pytest.mark.skipif(str(58279) not in TESTS, reason="Excluded")
    def test_teacher_view_getting_started_with_tutor_guide_58279(self):
        """View "Getting Started with Tutor" Guide.

        Steps:
        Click "Tutor Instructors. Get help"

        Expected Result:
        Tutor Help Center opens in another tab with the Getting Started guide
        """
        self.ps.test_updates["name"] = "t2.18.003" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.003", "58279"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58280 - 004 - Teacher | Access Tutor Help Center after registering for
    # a course
    @pytest.mark.skipif(str(58280) not in TESTS, reason="Excluded")
    def test_teacher_access_tutor_help_center_after_registering_58280(self):
        """Access Tutor Help Center after registering for a course.

        Steps:
        Go to Tutor
        Sign in as teacher01
        Click on a Tutor course if the user is in more than one
        Click "Get Help" from the user menu in the upper right corner of the
            screen

        Expected Result:
        The user is presented with the Tutor Help Center
        """
        self.ps.test_updates["name"] = "t2.18.004" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.004", "58280"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58284 - 005 - Teacher | Submit a question
    @pytest.mark.skipif(str(58284) not in TESTS, reason="Excluded")
    def test_teacher_submit_a_question_58284(self):
        """Submit a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter

        Expected Result:
        The user is presented with search results
        """
        self.ps.test_updates["name"] = "t2.18.005" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.005", "58284"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58352 - 006 - Teacher | View "Contact Us" button after submitting a
    # question
    @pytest.mark.skipif(str(58352) not in TESTS, reason="Excluded")
    def test_teacher_view_contact_us_button_after_submitting_quest_58352(self):
        """View "Contact Us" button after submitting a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Scroll to the bottom of the screen

        Expected Result:
        "Contact Us" button exists
        """
        self.ps.test_updates["name"] = "t2.18.006" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.006", "58352"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58288 - 007 - Teacher | View an article after submitting a question
    @pytest.mark.skipif(str(58288) not in TESTS, reason="Excluded")
    def test_teacher_view_an_article_after_submitting_a_question_58288(self):
        """View an article after submitting a question.

        Steps:

        Click "Get Help" from the user menu in the upper right corner of the
        screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result

        Expected Result:
        The user is presented with an article containing answer to the question
        """
        self.ps.test_updates["name"] = "t2.18.007" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.007", "58288"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58313 - 008 - Teacher | Indicate that the article was helpful
    @pytest.mark.skipif(str(58313) not in TESTS, reason="Excluded")
    def test_teacher_indicate_that_the_article_was_helpful_58313(self):
        """Indicate that the article was helpful.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "Yes"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed
        """
        self.ps.test_updates["name"] = "t2.18.008" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.008", "58313"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58314 - 009 - Teacher | Negative feedback renders a feedback popup box
    @pytest.mark.skipif(str(58314) not in TESTS, reason="Excluded")
    def test_teacher_negative_feedback_renders_feedback_popup_box_58314(self):
        """Negative feedback renders a feedback popup box.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"

        Expected Result:
        The user is presented with a popup box that allows them to input
        feedback
        """
        self.ps.test_updates["name"] = "t2.18.009" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.009", "58314"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58315 - 010 - Teacher | Submit feedback for an article
    @pytest.mark.skipif(str(58315) not in TESTS, reason="Excluded")
    def test_teacher_submit_feedback_for_an_article_58315(self):
        """Submit feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed in the box
        """
        self.ps.test_updates["name"] = "t2.18.010" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.010", "58315"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58322 - 011 - Teacher | Close window after submitting feedback for an
    # article
    @pytest.mark.skipif(str(58322) not in TESTS, reason="Excluded")
    def test_teacher_close_window_after_submitting_feedback_for_58322(self):
        """Close window after submitting feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"
        Click "Close window"

        Expected Result:
        The popup box closes and the message "Thanks for your feedback"
        displays beneath "Feedback"
        """
        self.ps.test_updates["name"] = "t2.18.011" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.011", "58322"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58316 - 012 - Teacher | Cancel feedback
    @pytest.mark.skipif(str(58316) not in TESTS, reason="Excluded")
    def test_teacher_cancel_feedback_before_making_changes_58316(self):
        """Cancel feedback.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        [optional] Enter feedback into the text box
        Click "Cancel"

        Expected Result:
        The popup box closes
        """
        self.ps.test_updates["name"] = "t2.18.012" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.012", "58316"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58318 - 013 - Teacher | View related articles
    @pytest.mark.skipif(str(58318) not in TESTS, reason="Excluded")
    def test_teacher_view_related_articles_58318(self):
        """View related articles.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Related Articles"
        Click on one of the articles (if any)

        Expected Result:
        The user is presented with the related article
        """
        self.ps.test_updates["name"] = "t2.18.013" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.013", "58318"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58319 - 014 - Teacher | Submit a question to Customer Support
    @pytest.mark.skipif(str(58319) not in TESTS, reason="Excluded")
    def test_teacher_submit_a_question_to_customer_support_58319(self):
        """Submit a question to Customer Support.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        CLick "Search" or press enter
        Click on a search result
        Scroll to the bottom of the page
        CLick "Contact Us"
        Fill out the required fields
        Enter "Submit"

        Expected Result:
        The message "Thank you for your message! We'll be back to you within
        one business day" is displayed
        """
        self.ps.test_updates["name"] = "t2.18.014" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.014", "58319"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 14755 - 015 - Teacher | View guided tutorials of Tutor
    @pytest.mark.skipif(str(14755) not in TESTS, reason="Excluded")
    def test_teacher_view_guided_tutorials_of_concept_coach_14755(self):
        """View guided tutorials of Tutor.

        Steps:


        Expected Result:

        """
        self.ps.test_updates["name"] = "t2.18.015" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.015", "14755"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 14750 - 016 - Student | Directed to a "No Courses" page when not in any
    # courses yet
    @pytest.mark.skipif(str(14750) not in TESTS, reason="Excluded")
    def test_student_directed_to_a_no_courses_page_when_not_in_any_14750(self):
        """Directed to a "No Courses" page when not in any courses yet.

        Steps:
        Go to Tutor
        Log in as qa_student_37003

        Expected Result:
        The message "We cannot find an OpenStax course associated with your
        account" displays with help links
        """
        self.ps.test_updates["name"] = "t2.18.016" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.016", "14750"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58336 - 017 - Student | View "Getting Started with Tutor" Guide
    @pytest.mark.skipif(str(58336) not in TESTS, reason="Excluded")
    def test_student_view_getting_started_with_tutor_guide_58336(self):
        """View "Getting Started with Tutor" Guide.

        Steps:
        Click "Tutor Students. Get help"

        Expected Result:
        Tutor Help Center opens in another tab with the Getting Started guide
        """
        self.ps.test_updates["name"] = "t2.18.017" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.017", "58336"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58337 - 018 - Student | Access Tutor Help Center after registering for a
    # course
    @pytest.mark.skipif(str(58337) not in TESTS, reason="Excluded")
    def test_student_access_tutor_help_center_after_registering_58337(self):
        """Access Tutor Help Center after registering for a course.

        Steps:
        Go to Tutor
        Sign in as student01
        Click on a Tutor course if the user is in more than one
        Click "Get Help" from the user menu in the upper right corner of the
            screen

        Expected Result:
        The user is presented with the Tutor Help Center
        """
        self.ps.test_updates["name"] = "t2.18.018" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.018", "58337"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58338 - 019 - Student | Submit a question
    @pytest.mark.skipif(str(58338) not in TESTS, reason="Excluded")
    def test_student_submit_a_question_58338(self):
        """Submit a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter

        Expected Result:
        The user is presented with search results
        """
        self.ps.test_updates["name"] = "t2.18.019" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.019", "58338"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58353 - 020 - Student | View "Contact Us" button after submitting a
    # question
    @pytest.mark.skipif(str(58353) not in TESTS, reason="Excluded")
    def test_student_view_contact_us_button_after_submitting_quest_58353(self):
        """View "Contact Us" button after submitting a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Scroll to the bottom of the page

        Expected Result:
        "Contact Us" button exists
        """
        self.ps.test_updates["name"] = "t2.18.020" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.020", "58353"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58339 - 021 - Student | View an article after submitting a question
    @pytest.mark.skipif(str(58339) not in TESTS, reason="Excluded")
    def test_student_view_an_article_after_submitting_a_question_58339(self):
        """View an article after submitting a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result

        Expected Result:
        The user is presented with an article containing answer to the question
        """
        self.ps.test_updates["name"] = "t2.18.021" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.021", "58339"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58340 - 022 - Student | Indicate that the article was helpful
    @pytest.mark.skipif(str(58340) not in TESTS, reason="Excluded")
    def test_student_indicate_that_the_article_was_helpful_58340(self):
        """Indicate that the article was helpful.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "Yes"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed
        """
        self.ps.test_updates["name"] = "t2.18.022" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.022", "58340"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58341 - 023 - Student | Negative feedback renders a feedback popup box
    @pytest.mark.skipif(str(58341) not in TESTS, reason="Excluded")
    def test_student_negative_feedback_renders_feedback_popup_box_58341(self):
        """Negative feedback renders a feedback popup box.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"

        Expected Result:
        The user is presented with a popup box that allows them to input
        feedback
        """
        self.ps.test_updates["name"] = "t2.18.023" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.023", "58341"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58342 - 024 - Student | Submit feedback for an article
    @pytest.mark.skipif(str(58342) not in TESTS, reason="Excluded")
    def test_student_submit_feedback_for_an_article_58342(self):
        """Submit feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed in the box
        """
        self.ps.test_updates["name"] = "t2.18.024" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.024", "58342"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58343 - 025 - Student | Close window after submitting feedback for an
    # article
    @pytest.mark.skipif(str(58343) not in TESTS, reason="Excluded")
    def test_student_close_window_after_submitting_feedback_for_58343(self):
        """Close window after submitting feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"
        Click "Close window"

        Expected Result:
        The popup box closes and the message "Thanks for your feedback"
        displays beneath "Feedback"
        """
        self.ps.test_updates["name"] = "t2.18.025" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.025", "58343"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58344 - 026 - Student | Cancel feedback
    @pytest.mark.skipif(str(58344) not in TESTS, reason="Excluded")
    def test_student_cancel_feedback_58344(self):
        """Cancel feedback.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        [optional] Enter feedback into text box
        Click "Cancel"

        Expected Result:
        The popup box closes
        """
        self.ps.test_updates["name"] = "t2.18.026" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.026", "58344"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58346 - 027 - Student | View related articles
    @pytest.mark.skipif(str(58346) not in TESTS, reason="Excluded")
    def test_student_view_related_articles_58346(self):
        """View related articles.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Related Articles"
        Click on one of the articles (if any)

        Expected Result:
        The user is presented with the related article
        """
        self.ps.test_updates["name"] = "t2.18.027" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.027", "58346"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58347 - 028 - Student | Submit a question to Customer Support
    @pytest.mark.skipif(str(58347) not in TESTS, reason="Excluded")
    def test_student_submit_a_question_to_customer_support_58347(self):
        """Submit a question to Customer Support.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to the bottom of the page
        Click "Contact Us"
        Fill out the required fields
        Enter "Submit"

        Expected Result:
        The message "Thank you for your message! We'll be back to you within
        one business day" is displayed
        """
        self.ps.test_updates["name"] = "t2.18.028" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.028", "58347"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True

    # 58348 - 029 - Student | View guided tutorials of Tutor
    @pytest.mark.skipif(str(58348) not in TESTS, reason="Excluded")
    def test_student_view_guided_tutorials_of_concept_coach_58348(self):
        """View guided tutorial of Tutor.

        Steps:


        Expected Result:

        """
        self.ps.test_updates["name"] = "t2.18.029" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.18", "t2.18.029", "58348"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates["passed"] = True
Example #41
0
 def setUp(self):
     """Pretest settings."""
     self.teacher = Teacher(username='', password='', site='')
     self.teacher.set_window_size(height=700, width=1200)
class TestIImproveQuestionManagement(unittest.TestCase):
    """CC2.11 - Improve Question Management."""

    def setUp(self):
        """Pretest settings."""

        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.student = Student(
            use_env_vars=True,
            existing_driver=self.teacher.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.teacher.driver.session_id),
            **self.ps.test_updates
        )
        self.student = None
        try:
            self.teacher.delete()
        except:
            pass

    # 14851 - 001 - Teacher | Review all questions
    @pytest.mark.skipif(str(14851) not in TESTS, reason='Excluded')
    def test_teacher_review_all_questions_14851(self):
        """Review all questions.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click "Question Library" from the user menu
        Select a section or chapter
        Click "Show Questions"

        Expected Result:
        The user is presented with all the questions for the section or chapter
        """
        self.ps.test_updates['name'] = 'cc2.11.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.001', '14851']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Question Library'
        ).click()
        self.teacher.find(
            By.XPATH,
            '//div[@class="section"]//span[@class="chapter-section" ' +
            'and @data-chapter-section="1.1"]'
        ).click()
        self.teacher.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.teacher.find(
            By.XPATH, '//button[text()="Show Questions"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="exercises"]')
            )
        )
        self.ps.test_updates['passed'] = True

    # 14852 - 002 - Teacher | Exclude certain questions
    @pytest.mark.skipif(str(14852) not in TESTS, reason='Excluded')
    def test_teacher_exclude_certain_questions_14852(self):
        """Exclude certain quesitons.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Question Library" from the user menu
        Select a section or chapter
        Click "Show Questions"
        Hover over the desired question and click "Exclude question"

        Expected Result:
        Question is grayed out
        """
        self.ps.test_updates['name'] = 'cc2.11.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.002', '14852']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Question Library'
        ).click()
        self.teacher.find(
            By.XPATH,
            '//div[@class="section"]//span[@class="chapter-section" ' +
            'and @data-chapter-section="1.2"]'
        ).click()
        self.teacher.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.teacher.find(
            By.XPATH, '//button[text()="Show Questions"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="exercises"]')
            )
        )
        self.teacher.sleep(1)
        i = 1
        question = None
        # loop finding a question that is not yet excleded
        # there are 9 question in the exact textbook and chpater this test
        # is searching. limiting loop at 7 incase questions are removed.
        while i < 8:
            question = self.teacher.find(
                By.XPATH,
                '//div[@class="exercises"]/div[' + str(i) + ']'
            )
            if ('is-selected' not in question.get_attribute('class')):
                break
            i += 1
        Assignment.scroll_to(self.teacher.driver, question)
        self.teacher.sleep(1)
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(question)
        # way to stall because not sure how to add wait in action chain
        for _ in range(50):
            actions.move_by_offset(-1, 0)
        actions.click()
        actions.move_by_offset(-50, -300)
        actions.perform()
        self.teacher.sleep(0.5)
        question_excluded = self.teacher.find(
            By.XPATH, '//div[@class="exercises"]/div[' + str(i) + ']'
        ).get_attribute('class')
        assert('is-selected' in question_excluded), 'question not excluded'
        self.ps.test_updates['passed'] = True

    # 14855 - 003 - Teacher | Pin tabs on top of screen when scrolled
    @pytest.mark.skipif(str(14855) not in TESTS, reason='Excluded')
    def test_teacher_pin_tabs_on_top_of_screen_when_scrolled_14855(self):
        """Pin tabs on top of screen when scrolled.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Question Library" from the user menu
        Select a section or chapter
        Click "Show Questions"
        Scroll down

        Expected Result:
        Tabs are pinned to top of the screen when scrolled
        """
        self.ps.test_updates['name'] = 'cc2.11.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.003', '14855']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Question Library'
        ).click()
        self.teacher.find(
            By.XPATH,
            '//div[@class="section"]//span[@class="chapter-section" ' +
            'and @data-chapter-section="1.2"]'
        ).click()
        self.teacher.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.teacher.find(
            By.XPATH, '//button[text()="Show Questions"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="exercises"]')
            )
        )
        self.teacher.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="pinned-header"]')
            )
        )
        self.ps.test_updates['passed'] = True

    # 14856 - 004 - Teacher | Make section links jumpable
    @pytest.mark.skipif(str(14856) not in TESTS, reason='Excluded')
    def test_teacher_make_section_links_jumpable_14856(self):
        """Make section links jumpable.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Question Library" from the user menu
        Select a section or chapter
        Click "Show Questions"
        Click on the section links at the top of the screen

        Expected Result:
        The screen scrolls to the selected questions
        """
        self.ps.test_updates['name'] = 'cc2.11.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.004', '14856']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Question Library'
        ).click()
        self.teacher.find(
            By.XPATH,
            '//div[@class="section"]//span[@class="chapter-section" ' +
            'and @data-chapter-section="1.2"]'
        ).click()
        self.teacher.find(
            By.XPATH,
            '//div[@class="section"]//span[@class="chapter-section" ' +
            'and @data-chapter-section="1.1"]'
        ).click()

        self.teacher.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.teacher.find(
            By.XPATH, '//button[text()="Show Questions"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="exercises"]')
            )
        )
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="pinned-header"]'
                 '//div[@class="section" and text()="1.2"]')
            )
        ).click()
        self.teacher.sleep(1)
        # click the heading as simple way to find that it is on screen
        # and not just visible but scrolled off screen
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="exercise-sections"]' +
                 '//span[@class="chapter-section" ' +
                 'and @data-chapter-section="1.2"]')
            )
        ).click()
        self.ps.test_updates['passed'] = True

    # 14858 - 005 - Teacher | Report errata about assessments in Concept Coach
    @pytest.mark.skipif(str(14858) not in TESTS, reason='Excluded')
    def test_teacher_report_errata_about_assessments_in_cc_14858(self):
        """Report errata about assessments in Concept Coach.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Question Library" from the user menu
        Select a section or chapter
        Click "Show Questions"
        Hover over the desired question and click "Question details"
        Click "Report an error"

        Expected Result:
        A new tab with the assessment errata form appears, with the assessment
        ID already filled in
        """
        self.ps.test_updates['name'] = 'cc2.11.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.005', '14858']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Question Library'
        ).click()
        self.teacher.find(
            By.XPATH,
            '//div[@class="section"]//span[@class="chapter-section" ' +
            'and @data-chapter-section="1.2"]'
        ).click()
        self.teacher.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.teacher.find(
            By.XPATH, '//button[text()="Show Questions"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="exercises"]')
            )
        )
        self.teacher.sleep(1)
        question = self.teacher.find(
            By.XPATH, '//div[@class="exercises"]/div[1]'
        )
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(question)
        # way to stall because not sure how to add wait in action chain
        for _ in range(50):
            actions.move_by_offset(1, 0)
        actions.click()
        actions.perform()
        self.teacher.sleep(0.5)
        exercise_id = self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//span[@class="exercise-tag" and contains(text(),"ID:")]')
            )
        ).text
        question = self.teacher.find(
            By.XPATH, '//div[@class="action report-error"]'
        ).click()
        window_with_form = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_form)
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[text()="Report Content Errors"]')
            )
        )
        self.teacher.find(
            By.XPATH, '//input[@value="' + exercise_id[4:] + '"]')

        self.ps.test_updates['passed'] = True

    # 14859 - 006 - Student | Report errata about assessments in Concept Coach
    @pytest.mark.skipif(str(14859) not in TESTS, reason='Excluded')
    def test_student_report_errata_about_assessments_in_cc_14859(self):
        """Report errata about assessments in Concept Coach.

        Steps:
        Click on a CC course, if there are more than one
        Click on a non-introductory section
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"
        Click "Report an error" on an assessment

        Expected Result:
        A new tab with the assessment errata form appears, with the assessment
        ID already filled in
        """
        self.ps.test_updates['name'] = 'cc2.11.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.11', 'cc2.11.006', '14859']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        # raise NotImplementedError(inspect.currentframe().f_code.co_name)
        self.student.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"cnx.org/contents/")]'
        ).click()
        # get to non-into section
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button//span[text()="Contents"]')
            )
        ).click()
        self.student.sleep(0.5)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]')
            )
        ).click()
        # open concept coach
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//span[contains(@class,"core breadcrumb-exercise")]')
            )
        ).click()
        exercise_id = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//span[@class="exercise-identifier-link"]' +
                 '/span[contains(text(),"@")]')
            )
        ).text
        self.teacher.find(By.LINK_TEXT, 'Report an error').click()
        window_with_form = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_form)
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[text()="Report Content Errors"]')
            )
        )
        self.teacher.find(
            By.XPATH, '//input[@value="' + exercise_id + '"]')
        self.ps.test_updates['passed'] = True
class 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 TestChooseCourse(unittest.TestCase):
    """T1.38 - Choose Course."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.user = None

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.user.driver.session_id),
            **self.ps.test_updates
        )
        try:
            self.user.delete()
        except:
            pass

    # Case C8254 - 001 - Student | Select a course
    @pytest.mark.skipif(str(8254) not in TESTS, reason='Excluded')
    def test_student_select_a_course_8254(self):
        """Select a course.

        Steps:
        Click on a Tutor course name

        Expected Result:
        The user selects a course and is presented with the dashboard.
        """
        self.ps.test_updates['name'] = 't1.38.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.001',
            '8254'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Student(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login()
        self.user.select_course(appearance='physics')

        assert('list' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True

    # Case C8255 - 002 - Student | Bypass the course picker
    @pytest.mark.skipif(str(8255) not in TESTS, reason='Excluded')
    def test_student_bypass_the_course_picker_8255(self):
        """Bypass the course picker.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account qas_01
        Click on the 'Sign in' button

        Expected Result:
        The user bypasses the course picker and is presented with the
        dashboard (because qas_01 is only enrolled in one course)
        """
        self.ps.test_updates['name'] = 't1.38.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.002',
            '8255'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Student(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login(username="******")
        assert('list' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True

    # Case C8256 - 003 - Teacher | Select a course
    @pytest.mark.skipif(str(8256) not in TESTS, reason='Excluded')
    def test_teacher_select_a_course_8256(self):
        """Select a course.

        Steps:
        Click on a Tutor course name

        Expected Result:
        The user selects a course and is presented with the calendar dashboard
        """
        self.ps.test_updates['name'] = 't1.38.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.003',
            '8256'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login()
        self.user.select_course(appearance='physics')
        assert('calendar' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True

    # Case C8257 - 004 - Teacher | Bypass the course picker
    @pytest.mark.skipif(str(8257) not in TESTS, reason='Excluded')
    def test_teacher_bypass_the_course_picker_8257(self):
        """Bypass the course picker.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account [ qateacher | password ] in the
            username and password text boxes
        Click on the 'Sign in' button

        Expected Result:
        The user bypasses the course picker and is presented with the
        calendar dashboard (because qateacher only has one course)
        """
        self.ps.test_updates['name'] = 't1.38.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.38',
            't1.38.004',
            '8257'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.user = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.user.login(username="******")
        assert('calendar' in self.user.current_url()), \
            'Not in a course'

        self.ps.test_updates['passed'] = True
class TestImproveCourseManagement(unittest.TestCase):
    """T2.07 - Improve Course Management."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.admin = Admin(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
            existing_driver=self.teacher.driver
        )

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.teacher.driver.session_id),
            **self.ps.test_updates
        )
        try:
            self.admin = None
            self.teacher.delete()
        except:
            pass

    # 14651 - 001 - Admin | View Student Use Statistics for Concept Coach
    # college assessments
    @pytest.mark.skipif(str(14651) not in TESTS, reason='Excluded')
    def test_admin_view_student_use_statistics_for_cc_college_asse_14651(self):
        """View Student Use Statistics for Concept Coach college assessments.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the admin account in the username and password text boxes
        Click on the 'Sign in' button
        Click "Admin" in the user menu
        Click "Stats"
        Click "Concept Coach"

        Expected Result:
        The user is presented with Concept Coach statistics
        """
        self.ps.test_updates['name'] = 't2.07.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.001',
            '14651'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.admin.login()
        self.admin.goto_admin_control()
        self.admin.sleep(5)
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Stats')
            )
        ).click()
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Concept Coach')
            )
        ).click()

        assert('/stats/concept_coach' in self.admin.current_url()), \
            'Not viewing Concept Coach stats'

        self.ps.test_updates['passed'] = True

    # 14652 - 002 - Teacher | Delegate teaching tasks to supporting instructors
    @pytest.mark.skipif(str(14652) not in TESTS, reason='Excluded')
    def test_teacher_delegate_teaching_tasks_to_supporting_instruc_14652(self):
        """Delegate teaching tasks to supporting instructors.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.07.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.002',
            '14652'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 14653 - 003 - Teacher | Move a student and their data to a new section
    @pytest.mark.skipif(str(14653) not in TESTS, reason='Excluded')
    def test_teacher_move_a_student_and_their_data_to_new_section_14653(self):
        """Move a student and their data to a new section.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Course Settings and Roster" from the user menu
        Click "Change Period" for the desired student and select a period

        Expected Result:
        Student is moved to new section with their data
        """
        self.ps.test_updates['name'] = 't2.07.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.003',
            '14653'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.select_course(appearance='physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        self.teacher.sleep(5)

        # Move the student to another period
        first = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]"
        ).text
        last = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]"
        ).text

        self.teacher.find(By.PARTIAL_LINK_TEXT, "Change Period").click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click()

        self.teacher.sleep(5)

        # Verify the move, then move the student back to the original period
        self.teacher.find(
            By.XPATH,
            "//div[@class='roster']/div[@class='settings-section periods']" +
            "/ul[@class='nav nav-tabs']/li[2]/a").click()
        roster = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr")
        index = 0
        for student in roster:
            if student.text.find(first) >= 0 and student.text.find(last) >= 0:
                self.teacher.driver.find_elements_by_partial_link_text(
                    "Change Period")[index].click()
                self.teacher.sleep(1)
                self.teacher.find(
                    By.XPATH,
                    "//ul[@class='nav nav-pills nav-stacked']/li/a").click()
                break
            index += 1

        self.teacher.sleep(2)
        self.teacher.find(
            By.XPATH,
            "//div[@class='roster']/div[@class='settings-section periods']" +
            "/ul[@class='nav nav-tabs']/li[1]/a").click()
        roster = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr")

        assert(first in roster[0].text and last in roster[0].text), \
            'error'

        self.ps.test_updates['passed'] = True

    # 14655 - 004 - Teacher | Drop a student from a section and hide their data
    @pytest.mark.skipif(str(14655) not in TESTS, reason='Excluded')
    def test_teacher_drop_student_from_section_and_hide_their_data_14655(self):
        """Drop a student from a section and hide their data.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Course Settings and Roster" from the user menu
        Click "Drop" for the desired student

        Expected Result:
        The student appears under the "Dropped Students" section
        """
        self.ps.test_updates['name'] = 't2.07.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.004',
            '14655'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.select_course(appearance='physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        self.teacher.sleep(5)

        # Drop the student
        first = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]"
        ).text
        last = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]"
        ).text
        self.teacher.find(By.PARTIAL_LINK_TEXT, "Drop").click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH,
            "//button[@class='-drop-student btn btn-danger']").click()

        self.teacher.sleep(5)

        # Verify the student was dropped and add back to active roster
        dropped = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='settings-section dropped-students']/table[@class" +
            "='roster table table-striped table-bordered table-condensed " +
            "table-hover']/tbody/tr")
        index = 0
        for student in dropped:
            if student.text.find(first) >= 0 and student.text.find(last) >= 0:
                self.teacher.driver.find_elements_by_partial_link_text(
                    "Add Back to Active Roster")[index].click()
                self.teacher.sleep(1)
                self.teacher.find(
                    By.XPATH,
                    "//button[@class='-undrop-student btn btn-success']"
                ).click()
                self.teacher.sleep(20)
                break
            index += 1

        self.ps.test_updates['passed'] = True

    # 14656 - 005 - Teacher | Drop a student from a section and don't hide
    # their data
    @pytest.mark.skipif(str(14656) not in TESTS, reason='Excluded')
    def test_teacher_drop_a_student_from_section_and_dont_hide_dat_14656(self):
        """Drop a student from a section and don't hide their data.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.07.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.005',
            '14656'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 14657 - 006 - Teacher | In Student Scores dropped students are not
    # displayed
    @pytest.mark.skipif(str(14657) not in TESTS, reason='Excluded')
    def test_teacher_in_student_scores_dropped_students_are_not_14657(self):
        """In Student Scores dropped students are not displayed.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Course Settings and Roster" from the calendar dashboard
        Click "Drop" for the desired student
        Click "Student Scores" from the user menu
        Click on the period from which you have dropped the student

        Expected Result:
        Dropped student should not be displayed in Student Scores
        """
        self.ps.test_updates['name'] = 't2.07.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.006',
            '14657'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.select_course(appearance='physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        self.teacher.sleep(5)

        # Drop the student
        first = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]"
        ).text
        last = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]"
        ).text

        self.teacher.find(By.PARTIAL_LINK_TEXT, "Drop").click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH,
            "//button[@class='-drop-student btn btn-danger']").click()

        self.teacher.sleep(5)

        # Go to student scores, verify the student is not seen
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Student Scores").click()
        self.teacher.sleep(10)

        odd_scores = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='fixedDataTableRowLayout_main public_fixedData" +
            "TableRow_main public_fixedDataTableRow_even public_fixedDataTa" +
            "ble_bodyRow']/div[@class='fixedDataTableRowLayout_body']/div" +
            "[@class='fixedDataTableCellGroupLayout_cellGroupWrapper'][1]/d" +
            "iv[@class='fixedDataTableCellGroupLayout_cellGroup']/div[@clas" +
            "s='fixedDataTableCellLayout_main public_fixedDataTableCell_" +
            "main'][1]/div[@class='fixedDataTableCellLayout_wrap1 public_fi" +
            "xedDataTableCell_wrap1']/div[@class='fixedDataTableCellLayout_w" +
            "rap2 public_fixedDataTableCell_wrap2']/div[@class='fixedDataTab" +
            "leCellLayout_wrap3 public_fixedDataTableCell_wrap3']/div[@class" +
            "='name-cell']/a[@class='student-name public_fixedDataTableCell" +
            "_cellContent']")
        even_scores = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='fixedDataTableRowLayout_main public_fixedDataTab" +
            "leRow_main public_fixedDataTableRow_highlighted public_fixedDa" +
            "taTableRow_odd public_fixedDataTable_bodyRow']/div[@class='fix" +
            "edDataTableRowLayout_body']/div[@class='fixedDataTableCellGrou" +
            "pLayout_cellGroupWrapper'][1]/div[@class='fixedDataTableCellGr" +
            "oupLayout_cellGroup']/div[@class='fixedDataTableCellLayout_mai" +
            "n public_fixedDataTableCell_main'][1]/div[@class='fixedDataTab" +
            "leCellLayout_wrap1 public_fixedDataTableCell_wrap1']/div[@clas" +
            "s='fixedDataTableCellLayout_wrap2 public_fixedDataTableCell_wr" +
            "ap2']/div[@class='fixedDataTableCellLayout_wrap3 public_fixedD" +
            "ataTableCell_wrap3']/div[@class='name-cell']/a[@class='student" +
            "-name public_fixedDataTableCell_cellContent']")

        found = False
        for student in odd_scores:
            if student.text.find(first) >= 0 and student.text.find(last) >= 0:
                found = True
                break

        if not found:
            for stud in even_scores:
                if stud.text.find(first) >= 0 and stud.text.find(last) >= 0:
                    found = True
                    break

        # Add back to active roster
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        dropped = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='settings-section dropped-students']/table[@class" +
            "='roster table table-striped table-bordered table-condensed ta" +
            "ble-hover']/tbody/tr")
        index = 0
        for student in dropped:
            if student.text.find(first) >= 0 and student.text.find(last) >= 0:
                self.teacher.driver.find_elements_by_partial_link_text(
                    "Add Back to Active Roster")[index].click()
                self.teacher.sleep(1)
                self.teacher.find(
                    By.XPATH,
                    "//button[@class='-undrop-student btn btn-success']"
                ).click()
                self.teacher.sleep(20)
                break
            index += 1

        if not found:
            self.ps.test_updates['passed'] = True

    # 14850 - 007 - Teacher | In Student Scores view moved students
    @pytest.mark.skipif(str(14850) not in TESTS, reason='Excluded')
    def test_teacher_in_student_scores_view_moved_students_14850(self):
        """In Student Scores view moved students.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Course Settings and Roster" from the calendar dashboard
        Click "Change Period" for the desired student
        Click on the desired period
        Click "Student Scores" from the user menu
        Click on the period to which the student was moved

        Expected Result:
        The user is presented with the moved student under their new period
        """
        self.ps.test_updates['name'] = 't2.07.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.007',
            '14850'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.select_course(appearance='physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        self.teacher.sleep(5)

        # Move the student to another period
        first = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[1]"
        ).text
        last = self.teacher.find(
            By.XPATH,
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr[1]/td[2]"
        ).text

        self.teacher.find(By.PARTIAL_LINK_TEXT, "Change Period").click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH, "//ul[@class='nav nav-pills nav-stacked']/li/a").click()

        self.teacher.sleep(5)

        # Go to student scores, verify the student is seen
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Student Scores").click()
        self.teacher.sleep(10)
        self.teacher.find(
            By.XPATH,
            "//nav[@class='collapse in']/ul[@class='nav nav-tabs']/li[2]/a"
        ).click()

        odd_scores = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='fixedDataTableRowLayout_main public_fixedData" +
            "TableRow_main public_fixedDataTableRow_even public_fixedDataTa" +
            "ble_bodyRow']/div[@class='fixedDataTableRowLayout_body']/div" +
            "[@class='fixedDataTableCellGroupLayout_cellGroupWrapper'][1]/d" +
            "iv[@class='fixedDataTableCellGroupLayout_cellGroup']/div[@clas" +
            "s='fixedDataTableCellLayout_main public_fixedDataTableCell_" +
            "main'][1]/div[@class='fixedDataTableCellLayout_wrap1 public_fi" +
            "xedDataTableCell_wrap1']/div[@class='fixedDataTableCellLayout_w" +
            "rap2 public_fixedDataTableCell_wrap2']/div[@class='fixedDataTab" +
            "leCellLayout_wrap3 public_fixedDataTableCell_wrap3']/div[@class" +
            "='name-cell']/a[@class='student-name public_fixedDataTableCell" +
            "_cellContent']")
        even_scores = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='fixedDataTableRowLayout_main public_fixedDataTab" +
            "leRow_main public_fixedDataTableRow_highlighted public_fixedDa" +
            "taTableRow_odd public_fixedDataTable_bodyRow']/div[@class='fix" +
            "edDataTableRowLayout_body']/div[@class='fixedDataTableCellGrou" +
            "pLayout_cellGroupWrapper'][1]/div[@class='fixedDataTableCellGr" +
            "oupLayout_cellGroup']/div[@class='fixedDataTableCellLayout_mai" +
            "n public_fixedDataTableCell_main'][1]/div[@class='fixedDataTab" +
            "leCellLayout_wrap1 public_fixedDataTableCell_wrap1']/div[@clas" +
            "s='fixedDataTableCellLayout_wrap2 public_fixedDataTableCell_wr" +
            "ap2']/div[@class='fixedDataTableCellLayout_wrap3 public_fixedD" +
            "ataTableCell_wrap3']/div[@class='name-cell']/a[@class='student" +
            "-name public_fixedDataTableCell_cellContent']")

        found = False
        for student in odd_scores:
            if student.text.find(first) >= 0 and student.text.find(last) >= 0:
                found = True
                break

        if found:
            for stud in even_scores:
                if stud.text.find(first) >= 0 and stud.text.find(last) >= 0:
                    found = True
                    break

        # Add student back to original period
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        self.teacher.sleep(10)
        self.teacher.find(
            By.XPATH,
            "//div[@class='roster']/div[@class='settings-section periods']" +
            "/ul[@class='nav nav-tabs']/li[2]/a").click()
        roster = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='period']/table[@class='roster table table-striped" +
            " table-bordered table-condensed table-hover']/tbody/tr")
        index = 0
        for student in roster:
            if student.text.find(first) >= 0 and student.text.find(last) >= 0:
                self.teacher.driver.find_elements_by_partial_link_text(
                    "Change Period")[index].click()
                self.teacher.sleep(1)
                self.teacher.find(
                    By.XPATH,
                    "//ul[@class='nav nav-pills nav-stacked']/li/a").click()
                break
            index += 1

        if found:
            self.ps.test_updates['passed'] = True

    # 14658 - 008 - Teacher | Require emails for all students for roster import
    @pytest.mark.skipif(str(14658) not in TESTS, reason='Excluded')
    def test_teacher_require_emails_for_all_students_for_roster_14658(self):
        """Require emails for all students for roster imports.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.07.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.008',
            '14658'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 14660 - 009 - Teacher | Set time zone for a course
    @pytest.mark.skipif(str(14660) not in TESTS, reason='Excluded')
    def test_teacher_set_time_zone_for_a_course_14660(self):
        """Set time zone for a course.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Course Settings and Roster"
        Click "Change Course Timezone"
        Select the desired timezone
        Click Save

        Expected Result:
        The time zone is set
        """
        self.ps.test_updates['name'] = 't2.07.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.009',
            '14660'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.select_course(appearance='physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, "Course Settings and Roster").click()
        self.teacher.sleep(5)

        # Change the timezone
        self.teacher.driver.find_elements_by_xpath(
            "//button[@class='edit-course btn btn-link']")[1].click()
        self.teacher.sleep(2)
        self.teacher.find(
            By.XPATH, "//div[@class='tutor-radio']/label").click()
        self.teacher.find(
            By.XPATH,
            "//button[@class='async-button -edit-course-" +
            "confirm btn btn-default']").click()
        self.teacher.sleep(5)

        # Verify the change and change the time back to Central
        self.teacher.driver.find_elements_by_xpath(
            "//button[@class='edit-course btn btn-link']")[1].click()

        assert('Central Time' not in self.teacher.find(
            By.XPATH, "//div[@class='tutor-radio active']/label").text), \
            'Not viewing Concept Coach stats'

        self.teacher.sleep(2)
        options = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='tutor-radio']/label")

        for timezone in options:
            if timezone.text.find('Central Time') >= 0:
                timezone.click()
                break

        self.teacher.find(
            By.XPATH,
            "//button[@class='async-button -edit-course-" +
            "confirm btn btn-default']").click()

        self.ps.test_updates['passed'] = True

    # 14661 - 010 - System | Distinguish between high school and college
    # courses
    @pytest.mark.skipif(str(14661) not in TESTS, reason='Excluded')
    def test_system_distinguish_between_hs_and_college_courses_14661(self):
        """Distinguish between high school and college courses.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.07.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.07',
            't2.07.010',
            '14661'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
class TestTutorWorksWithCNX(unittest.TestCase):
    """T1.27 - Tutor works with CNX."""

    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
        )

    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 C8182 - 001 - System | CNX needs to handle LaTeX in Exercises
    @pytest.mark.skipif(str(8182) not in TESTS, reason='Excluded')
    def test_system_cnx_needs_to_handle_latex_in_exercises_8182(self):
        """CNX needs to handle LaTeX in Exercises.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't1.27.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.27',
            't1.27.001',
            '8182'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # Case C8183 - 002 - System | CNX pulls exercises from Tutor
    @pytest.mark.skipif(str(8183) not in TESTS, reason='Excluded')
    def test_system_cnx_pulls_exercises_from_tutor_8183(self):
        """Story Text.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't1.27.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.27',
            't1.27.002',
            '8183'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
class TestEditCourseSettingsAndRoster(unittest.TestCase):
    """T1.42 - Edit Course Settings and Roster."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.teacher.login()
        self.teacher.select_course(appearance='physics')
        self.teacher.open_user_menu()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Course Settings and Roster')
            )
        ).click()
        self.teacher.page.wait_for_page_load()

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.teacher.driver.session_id),
            **self.ps.test_updates
        )
        try:
            self.teacher.delete()
        except:
            pass

    # Case C8258 - 001 - Teacher | Edit the course name
    @pytest.mark.skipif(str(8258) not in TESTS, reason='Excluded')
    def test_teacher_edit_the_course_name_8258(self):
        """Edit the course name.

        Steps:
        Click the "Rename Course" button that is next to the course name
        Enter a new course name
        Click the "Rename" button
        Click the X that is on the upper right corner of the dialogue box

        Expected Result:
        The course name is edited.
        (then put it back at the end)
        """
        self.ps.test_updates['name'] = 't1.42.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.001', '8258']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        course_name = self.teacher.driver.find_element(
            By.XPATH,
            '//div[@class="course-settings-title"]/span'
        ).text
        self.teacher.find(
            By.XPATH, '//button[contains(@class,"edit-course")]' +
            '//span[contains(text(),"Rename Course")]'
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@class,"form-control")]')
            )
        ).send_keys('_EDIT')
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-course-confirm")]'
        ).click()
        # check that it was edited
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="course-settings-title"]' +
                 '/span[contains(text(),"%s_EDIT")]' % course_name)
            )
        )
        # set it back
        self.teacher.sleep(1)
        self.teacher.driver.find_element(
            By.XPATH,
            '//button[contains(@class,"edit-course")]' +
            '//span[contains(text(),"Rename Course")]'
        ).click()
        for _ in range(len('_EDIT')):
            self.teacher.wait.until(
                expect.element_to_be_clickable(
                    (By.XPATH, '//input[contains(@class,"form-control")]')
                )
            ).send_keys(Keys.BACK_SPACE)
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-course-confirm")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="course-settings-title"]' +
                 '/span[text()="%s"]' % course_name)
            )
        )

        self.ps.test_updates['passed'] = True

    # Case C8259 - 002 - Teacher | Remove an instructor from the course
    @pytest.mark.skipif(str(8259) not in TESTS, reason='Excluded')
    def test_teacher_remove_an_instructor_from_a_course_8259(self):
        """Remove an instructor from the course.

        Steps:
        Click "Remove" for an instructor under the Instructors section
        Click "Remove" on the box that pops up

        Expected Result:
        The instructor is removed from the Instructors list.
        """
        self.ps.test_updates['name'] = 't1.42.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.002', '8259']
        self.ps.test_updates['passed'] = False

        self.teacher.logout()
        # add extra instructor through admin first
        admin = Admin(
            use_env_vars=True,
            existing_driver=self.teacher.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        admin.login()
        admin.get('https://tutor-qa.openstax.org/admin/courses/1/edit')
        admin.page.wait_for_page_load()
        teacher_name = 'Trent'
        admin.find(
            By.XPATH, '//a[contains(text(),"Teachers")]').click()
        admin.find(
            By.ID, 'course_teacher').send_keys(teacher_name)
        admin.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name)
            )
        ).click()
        admin.sleep(1)
        admin.find(
            By.LINK_TEXT, 'Main Dashboard').click()
        admin.page.wait_for_page_load()
        admin.logout()
        # redo set-up, but make sure to go to course 1
        self.teacher.login()
        self.teacher.get('https://tutor-qa.openstax.org/courses/1')
        self.teacher.open_user_menu()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Course Settings and Roster')
            )
        ).click()
        self.teacher.page.wait_for_page_load()
        # delete teacher
        teachers_list = self.teacher.find_all(
            By.XPATH, '//div[@class="teachers-table"]//tbody//tr')
        for x in range(len(teachers_list)):
            temp_first = self.teacher.find(
                By.XPATH,
                '//div[@class="teachers-table"]//tbody//tr[' +
                str(x + 1) + ']/td'
            ).text
            if temp_first == teacher_name:
                self.teacher.find(
                    By.XPATH,
                    '//div[@class="teachers-table"]//tbody//tr[' +
                    str(x + 1) + ']//td//span[contains(text(),"Remove")]'
                ).click()
                self.teacher.sleep(1)
                self.teacher.find(
                    By.XPATH, '//div[@class="popover-content"]//button'
                ).click()
                break
            if x == len(teachers_list) - 1:
                print('added teacher was not found, and not deleted')
                raise Exception
        deleted_teacher = self.teacher.driver.find_elements(
            By.XPATH, '//td[contains(text(),"%s")]' % teacher_name)
        assert(len(deleted_teacher) == 0), 'teacher not deleted'

        self.ps.test_updates['passed'] = True

    # Case C8260 - 003 - Teacher | Remove the last instructor from the course
    @pytest.mark.skipif(str(8260) not in TESTS, reason='Excluded')
    def test_teacher_remove_the_last_instructor_from_the_course_8260(self):
        """Remove the last instructor from the course.

        Steps:
        Click on the user menu in the upper right corner of the page
        Click "Course Roster"
        Click "Remove" for an instructor under the Instructors section
        Click "Remove" on the box that pops up

        Expected Result:
        The instructor is removed from the Instructors list.
        """
        self.ps.test_updates['name'] = 't1.42.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.003', '8260']
        self.ps.test_updates['passed'] = False

        raise NotImplementedError(inspect.currentframe().f_code.co_name)
        self.teacher.logout()
        # add extra instructor through admin first
        admin = Admin(
            use_env_vars=True,
            existing_driver=self.teacher.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        admin.login()
        admin.get('https://tutor-qa.openstax.org/admin/courses/1/edit')
        admin.page.wait_for_page_load()
        teacher_name = 'Trent'
        admin.find(
            By.XPATH, '//a[contains(text(),"Teachers")]').click()
        admin.find(
            By.ID, 'course_teacher').send_keys(teacher_name)
        admin.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//li[contains(text(),"%s")]' % teacher_name)
            )
        ).click()
        admin.sleep(1)
        admin.find(
            By.LINK_TEXT, 'Main Dashboard').click()
        admin.page.wait_for_page_load()
        admin.logout()
        # redo set-up, but make sure to go to course 1
        self.teacher.login()
        self.teacher.get('https://tutor-qa.openstax.org/courses/1')
        self.teacher.open_user_menu()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Course Settings and Roster')
            )
        ).click()
        self.teacher.page.wait_for_page_load()
        # delete teacher
        teachers_list = self.teacher.find_all(
            By.XPATH, '//div[@class="teachers-table"]//tbody//tr')
        for x in range(len(teachers_list)):
            temp_first = self.teacher.find(
                By.XPATH,
                '//div[@class="teachers-table"]//tbody//tr[' +
                str(x + 1) + ']/td'
            ).text
            if temp_first == teacher_name:
                self.teacher.find(
                    By.XPATH,
                    '//div[@class="teachers-table"]//tbody//tr[' +
                    str(x + 1) + ']//td//span[contains(text(),"Remove")]'
                ).click()
                self.teacher.sleep(1)
                self.teacher.find(
                    By.XPATH, '//div[@class="popover-content"]//button'
                ).click()
                break
            if x == len(teachers_list) - 1:
                print('added teacher was not found, and not deleted')
                raise Exception
        deleted_teacher = self.teacher.driver.find_elements(
            By.XPATH, '//td[contains(text(),"%s")]' % teacher_name)
        assert(len(deleted_teacher) == 0), 'teacher not deleted'

        self.ps.test_updates['passed'] = True

    # Case C8261 - 004 - Teacher | Add a period
    @pytest.mark.skipif(str(8261) not in TESTS, reason='Excluded')
    def test_teacher_add_a_period_8261(self):
        """Add a period.

        Steps:
        Click "+ Add Period"
        Enter a period name into the Period Name text box
        Click "Add"

        Expected Result:
        A new period is added.
        """
        self.ps.test_updates['name'] = 't1.42.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.004', '8261']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        period_name = 'automated_' + str(randint(0, 999))
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"add-period")]//button').click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@class,"form-control")]')
            )
        ).send_keys(period_name)
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-period-confirm")]'
        ).click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH, '//a[contains(text(),"'+period_name+'")]')

        self.ps.test_updates['passed'] = True

    # Case C8262 - 005 - Teacher | Rename a period
    @pytest.mark.skipif(str(8262) not in TESTS, reason='Excluded')
    def test_teacher_rename_a_period_8262(self):
        """Rename a period.

        Steps:
        Click "Rename Period"
        Enter a new period name into the Period Name text box
        Click "Rename"

        Expected Result:
        A period is renamed.
        """
        self.ps.test_updates['name'] = 't1.42.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.005', '8262']
        self.ps.test_updates['passed'] = False

        # create a period
        period_name = 'automated_' + str(randint(0, 999))
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"add-period")]//button').click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@class,"form-control")]')
            )
        ).send_keys(period_name)
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-period-confirm")]'
        ).click()
        self.teacher.sleep(1)
        # edit the period
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[contains(text(),"'+period_name+'")]')
            )
        ).click()
        self.teacher.find(
            By.XPATH, '//span[contains(@class,"rename-period")]/button'
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@class,"form-control")]')
            )
        ).send_keys('_EDIT')
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-period-confirm")]'
        ).click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH, '//a[contains(text(),"'+period_name+'_EDIT")]')

        self.ps.test_updates['passed'] = True

    # Case C8263 - 006 - Teacher | Archive an empty period
    @pytest.mark.skipif(str(8263) not in TESTS, reason='Excluded')
    def test_teacher_archive_an_empt_period_8263(self):
        """Archive an empty period.

        Steps:
        Click on an empty period
        Click "Archive Period"
        Click "Archive" on the dialogue box

        Expected Result:
        An empty period is archived.
        """
        self.ps.test_updates['name'] = 't1.42.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.006', '8263']
        self.ps.test_updates['passed'] = False

        # create a period
        period_name = 'automated_' + str(randint(0, 999))
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"add-period")]//button').click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@class,"form-control")]')
            )
        ).send_keys(period_name)
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-period-confirm")]'
        ).click()
        self.teacher.sleep(1)
        # edit the period
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[contains(text(),"'+period_name+'")]')
            )
        ).click()
        self.teacher.find(
            By.XPATH, '//a[contains(@class,"archive-period")]').click()
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"popover-content")]' +
            '//button[contains(@class,"archive")]').click()
        self.teacher.sleep(2)
        archived_period = self.teacher.find_all(
            By.XPATH, '//a[contains(text(),"'+period_name+'")]')
        assert(len(archived_period) == 0), 'period not archived'

        self.ps.test_updates['passed'] = True

    # Case C8264 - 007 - Teacher | Archive a non-empty period
    @pytest.mark.skipif(str(8264) not in TESTS, reason='Excluded')
    def test_teacher_archive_a_non_empty_period_8264(self):
        """Archive a non-empty period.

        Steps:
        Click on a non-empty period
        Click "Archive Period"
        Click Archive

        Expected Result:
        Period is archived
        """
        self.ps.test_updates['name'] = 't1.42.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.007', '8264']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        period_name = self.teacher.find(
            By.XPATH, '//ul[@role="tablist"]//a[@role="tab"]').text
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[contains(text(),"'+period_name+'")]')
            )
        ).click()
        self.teacher.find(
            By.XPATH, '//a[contains(@class,"archive-period")]').click()
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"popover-content")]' +
            '//button[contains(@class,"archive")]').click()
        self.teacher.find(
            By.XPATH, '//span[contains(text(),"View Archived")]').click()
        self.teacher.find(
            By.XPATH, '//div[@class="modal-body"]//td[contains(text(),"' +
            period_name + '")]')
        # add the section back
        periods = self.teacher.find_all(
            By.XPATH, '//div[@class="modal-body"]//table//tbody//tr')
        for x in range(len(periods)):
            temp_period = self.teacher.find(
                By.XPATH, '//div[@class="modal-body"]//table//tbody' +
                '//tr['+str(x+1)+']/td').text
            if temp_period == period_name:
                self.teacher.find(
                    By.XPATH,
                    '//div[@class="modal-body"]//table//tbody//tr[' +
                    str(x+1) + ']//button//span[contains(text(),"Unarchive")]'
                ).click()
                break

        self.ps.test_updates['passed'] = True

    # Case C8265 - 008 - Teacher | Move a student to another period
    @pytest.mark.skipif(str(8265) not in TESTS, reason='Excluded')
    def test_teacher_mover_a_student_to_another_period_8265(self):
        """Move a student to another period.

        Steps:
        Click on the user menu in the upper right corner of the page
        Click "Course Roster"
        Click "Change Period" for a student under the Roster section
        Click the desired period to move a student

        Expected Result:
        A student is moved to another period
        """
        self.ps.test_updates['name'] = 't1.42.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.008', '8265']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.find(
            By.XPATH, '//a[@aria-describedby="change-period"]').click()
        student_name = self.teacher.find(
            By.XPATH, '//div[@class="roster"]//td').text
        element = self.teacher.find(
            By.XPATH, '//div[@class="popover-content"]//a')
        period_name = element.text
        element.click()
        self.teacher.sleep(1)
        self.teacher.find(
            By.XPATH, '//li/a[contains(text(),"'+period_name+'")]').click()
        self.teacher.driver.find_element(
            By.XPATH, '//td[contains(text(),"%s")]' % student_name)

        self.ps.test_updates['passed'] = True

    # Case C8266 - 009 - Teacher | Drop a student
    @pytest.mark.skipif(str(8266) not in TESTS, reason='Excluded')
    def test_teacher_drop_a_student_8266(self):
        """Drop a student.

        Steps:
        Click on the user menu in the upper right corner of the page
        Click "Course Roster"
        Click "Drop" for a student under the Roster section
        Click "Drop" in the box that pops up

        Expected Result:
        A student is dropped from the course and
        is put under the Dropped Students section
        """
        self.ps.test_updates['name'] = 't1.42.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.009', '8266']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        student_name = self.teacher.find(
            By.XPATH, '//div[@class="roster"]//td').text
        self.teacher.find(
            By.XPATH, '//a[@aria-describedby="drop-student"]').click()
        self.teacher.find(
            By.XPATH, '//div[@class="popover-content"]//button').click()
        self.teacher.sleep(1)
        # check that student was droped
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"dropped-students")]' +
            '//td[contains(text(),"%s")]' % student_name
        )

        self.ps.test_updates['passed'] = True

    # Case C8267 - 010 - Teacher | Readd a dropped student
    @pytest.mark.skipif(str(8267) not in TESTS, reason='Excluded')
    def test_teacher_readd_a_dropped_student_8267(self):
        """Readd a dropped student.

        Steps:
        Click "Add Back to Active Roster" for a student under
            the Dropped Students section
        Click "Add" on the box that pops up

        Expected Result:
        A student is added back to the course
        """
        self.ps.test_updates['name'] = 't1.42.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.010', '8267']
        self.ps.test_updates['passed'] = False

        # drop a student (to make sure there is someone to add back)
        student_name = self.teacher.find(
            By.XPATH, '//div[@class="roster"]//td').text
        self.teacher.find(
            By.XPATH, '//a[@aria-describedby="drop-student"]').click()
        self.teacher.find(
            By.XPATH, '//div[@class="popover-content"]//button').click()
        self.teacher.sleep(1)
        # add a student back (not necessarily the same student)
        element = self.teacher.find(
            By.XPATH, '//div[contains(@class,"dropped-students")]' +
            '//span[contains(text(),"Add Back to Active Roster")]')
        self.teacher.driver.execute_script(
            'return arguments[0].scrollIntoView();', element)
        self.teacher.driver.execute_script('window.scrollBy(0, -80);')
        element.click()
        self.teacher.find(
            By.XPATH, '//div[@class="popover-content"]//button').click()
        # check that student was added back
        self.teacher.find(
            By.XPATH,
            '//div[@class="roster"]//td[contains(text(),"%s")]' % student_name)

        self.ps.test_updates['passed'] = True

    # Case C58356 - 011 - Teacher | Unarchive an empty period
    @pytest.mark.skipif(str(58356) not in TESTS, reason='Excluded')
    def test_teacher_unarchive_an_empty_period_58356(self):
        """Unarchive an empty period.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account [ teacher001 ] and password in the boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name
        Click on the user menu in the upper right corner of the page
        Click "Course Settings and Roster"
        Click "View Archived Period(s)"
        Click Unarchived period next to selected course

        Expected Result:
        Period is made active.
        """
        self.ps.test_updates['name'] = 't1.42.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.42', 't1.42.011', '58356']
        self.ps.test_updates['passed'] = False

        # create a period
        period_name = 'automated_011_' + str(randint(0, 999))
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"add-period")]//button').click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@class,"form-control")]')
            )
        ).send_keys(period_name)
        self.teacher.find(
            By.XPATH,
            '//button[contains(@class,"edit-period-confirm")]'
        ).click()
        self.teacher.sleep(1)
        # archive the period
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[contains(text(),"'+period_name+'")]')
            )
        ).click()
        self.teacher.find(
            By.XPATH, '//a[contains(@class,"archive-period")]').click()
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"popover-content")]' +
            '//button[contains(@class,"archive")]').click()
        self.teacher.sleep(2)
        archived_period = self.teacher.find_all(
            By.XPATH, '//a[contains(text(),"'+period_name+'")]')
        assert(len(archived_period) == 0), 'period not archived'
        # unarchive the period
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"view-archived-periods")]//button'
        ).click()
        self.teacher.sleep(1)
        rows = self.teacher.find_all(
            By.XPATH, '//div[@class="modal-content"]//tbody/tr')
        for row in rows:
            temp_name = row.find_element(By.XPATH, "./td[1]").text
            if temp_name == period_name:
                row.find_element(
                    By.XPATH,
                    "./td[3]//button[contains(@class,'unarchive-section')]"
                ).click()
                self.teacher.find(
                    By.XPATH,
                    '//div[@class="modal-content"]//button[@class="close"]'
                ).click()
                break
        # check that period is no longer archived
        self.teacher.find(
            By.XPATH, '//a[contains(text(),"'+period_name+'")]')

        self.ps.test_updates['passed'] = True
class TestWorkAnExternalAssignment(unittest.TestCase):
    """T1.48 - Work an external assignment."""

    def setUp(self):
        """Pretest settings."""
        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(
            use_env_vars=True,
            existing_driver=self.student.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.teacher.login()

        # Create an external assignment for the student to work
        self.teacher.select_course(appearance='physics')
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.ID, 'add-assignment')
            )
        ).click()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, 'Add External Assignment').click()
        assert('externals/new' in self.teacher.current_url()), \
            'Not on the add an external assignment page'

        self.teacher.find(
            By.XPATH, "//input[@id = 'reading-title']").send_keys('Epic 48')
        self.teacher.find(
            By.XPATH, "//textarea[@class='form-control empty']").send_keys(
            "instructions go here")
        self.teacher.find(
            By.XPATH, "//input[@id = 'hide-periods-radio']").click()

        # Choose the first date calendar[0], second is calendar[1]
        # and set the open date to today
        self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__input-container']")[0].click()
        self.teacher.driver.find_element_by_xpath(
            "//div[@class = 'datepicker__day datepicker__day--today']").click()

        # Choose the second date calendar[1], first is calendar[0]
        self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__input-container']")[1].click()
        while(self.teacher.find(
            By.XPATH,
            "//span[@class = 'datepicker__current-month']"
        ).text != 'December 2016'):
            self.teacher.find(
                By.XPATH,
                "//a[@class = 'datepicker__navigation datepicker__" +
                "navigation--next']").click()

        # Choose the due date of December 31, 2016
        weekends = self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__day datepicker__day--weekend']")
        for day in weekends:
            if day.text == '31':
                due = day
                due.click()
                break

        self.teacher.find(By.XPATH, "//input[@id='external-url']").send_keys(
            "google.com")
        self.teacher.sleep(5)

        # Publish the assignment
        self.teacher.find(
            By.XPATH,
            "//button[@class='async-button -publish btn btn-primary']").click()
        self.teacher.sleep(60)
        self.student.login()

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.student.driver.session_id),
            **self.ps.test_updates
        )
        try:

            # Delete the assignment
            assert('calendar' in self.teacher.current_url()), \
                'Not viewing the calendar dashboard'

            spans = self.teacher.driver.find_elements_by_tag_name('span')
            for element in spans:
                if element.text.endswith('2016'):
                    month = element

            # Change the calendar date if necessary
            while (month.text != 'December 2016'):
                self.teacher.find(
                    By.XPATH,
                    "//a[@class = 'calendar-header-control next']").click()

            # Select the newly created assignment and delete it
            assignments = self.teacher.driver.find_elements_by_tag_name(
                'label')
            for assignment in assignments:
                if assignment.text == 'Epic 48':
                    assignment.click()
                    self.teacher.find(
                        By.XPATH,
                        "//a[@class='btn btn-default -edit-assignment']"
                    ).click()
                    self.teacher.find(
                        By.XPATH,
                        "//button[@class='async-button delete-link " +
                        "pull-right btn btn-default']").click()
                    self.teacher.find(
                        By.XPATH, "//button[@class='btn btn-primary']").click()
                    self.teacher.sleep(5)
                    break
        except:
            pass
        try:
            self.teacher.driver.refresh()
            self.teacher.sleep(5)

            self.teacher = None
            self.student.delete()
        except:
            pass

    # Case C8281 - 001 - Student | Click on an external assignment
    @pytest.mark.skipif(str(8281) not in TESTS, reason='Excluded')
    def test_student_click_on_a_external_assignment_8281(self):
        """Click on an external assignment.

        Steps:
        Click on an external assignment under the tab "This Week"
        on the dashboard

        Expected Result:
        The user is presented with the assignment link and instructions
        """
        self.ps.test_updates['name'] = 't1.48.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.48',
            't1.48.001',
            '8281'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        assignments = self.student.driver.find_elements_by_xpath(
            "//div[@class='task row external workable']")
        for assignment in assignments:
            if (assignment.text.find('Epic 48') >= 0):
                assignment.click()
                break

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        self.student.sleep(5)

        self.ps.test_updates['passed'] = True

    # Case C8282 - 002 - Student | Read the directions below the assignment
    # link or hover over the info icon in the footer
    @pytest.mark.skipif(str(8282) not in TESTS, reason='Excluded')
    def test_student_read_directions_below_or_hover_over_info_icon_8282(self):
        """Read directions below assignment link or hover over the info icon.

        Steps:
        Click on an external assignment under the tab "This Week"
            on the dashboard
        Hover the cursor over the info icon in the footer

        Expected Result:
        The user is presented with the directions for the assignment
        """
        self.ps.test_updates['name'] = 't1.48.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.48',
            't1.48.002',
            '8282'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        assignments = self.student.driver.find_elements_by_xpath(
            "//div[@class='task row external workable']")
        for assignment in assignments:
            if (assignment.text.find('Epic 48') >= 0):
                assignment.click()
                break

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        instructions = self.student.driver.find_elements_by_tag_name("p")
        flag = False
        for instruction in instructions:
            if (instruction.text == 'instructions go here'):
                flag = True
                break

        assert(flag), \
            'Did not read instructions'

        self.ps.test_updates['passed'] = True

    # Case C8283 - 003 - Student | Click the assignment link
    @pytest.mark.skipif(str(8283) not in TESTS, reason='Excluded')
    def test_student_click_the_assignment_link_8283(self):
        """Click the assignment link.

        Steps:
        Click on an external assignment under the tab "This Week"
            on the dashboard
        Click on the link to the external assignment

        Expected Result:
        The user is presented with the external assignment
        """
        self.ps.test_updates['name'] = 't1.48.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.48',
            't1.48.003',
            '8283'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        assignments = self.student.driver.find_elements_by_xpath(
            "//div[@class='task row external workable']")
        for assignment in assignments:
            if (assignment.text.find('Epic 48') >= 0):
                assignment.click()
                break

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        link = self.student.driver.find_element_by_link_text(
            'Epic 48')
        original = self.student.current_url()
        self.student.driver.get(link.get_attribute("href"))

        assert('google' in self.student.current_url()), \
            'Not viewing assignment link'

        self.student.sleep(5)
        self.student.driver.get(original)

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        self.ps.test_updates['passed'] = True

    # Case C8284 - 004 - Student | Close the assignment tab or window
    @pytest.mark.skipif(str(8284) not in TESTS, reason='Excluded')
    def test_student_close_the_assignment_8284(self):
        """Close the assignment tab or window.

        Steps:
        Click on an external assignment under the tab "This Week"
            on the dashboard
        Click on the link to the external assignment
        Close the assignment tab

        Expected Result:
        The assignment tab is closed and the user is presented with the
        external assignment link and instructions on Tutor
        """
        self.ps.test_updates['name'] = 't1.48.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.48',
            't1.48.004',
            '8284'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        assignments = self.student.driver.find_elements_by_xpath(
            "//div[@class='task row external workable']")
        for assignment in assignments:
            if (assignment.text.find('Epic 48') >= 0):
                assignment.click()
                break

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        link = self.student.driver.find_element_by_link_text(
            'Epic 48')
        original = self.student.current_url()
        self.student.driver.get(link.get_attribute("href"))

        assert('google' in self.student.current_url()), \
            'Not viewing assignment link'

        self.student.sleep(5)
        self.student.driver.get(original)

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        self.ps.test_updates['passed'] = True

    # Case C8285 - 005 - Student | Click the Back To Dashboard button to
    # finish the assignment
    @pytest.mark.skipif(str(8285) not in TESTS, reason='Excluded')
    def test_student_click_back_to_dashboard_button_8285(self):
        """Click the Back To Dashboard button to finish the assignment.

        Steps:
        Click on an external assignment under the tab "This Week"
            on the dashboard
        Click on the link to the external assignment
        Close the assignment tab
        Click "Back To Dashboard"

        Expected Result:
        The user is presented with the dashboard
        """
        self.ps.test_updates['name'] = 't1.48.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.48',
            't1.48.005',
            '8285'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        assignments = self.student.driver.find_elements_by_xpath(
            "//div[@class='task row external workable']")
        for assignment in assignments:
            if (assignment.text.find('Epic 48') >= 0):
                assignment.click()
                break

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        link = self.student.driver.find_element_by_link_text(
            'Epic 48')
        original = self.student.current_url()
        self.student.driver.get(link.get_attribute("href"))

        assert('google' in self.student.current_url()), \
            'Not viewing assignment link'

        self.student.sleep(5)
        self.student.driver.get(original)

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        self.student.find(By.LINK_TEXT, 'Back To Dashboard').click()

        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        self.ps.test_updates['passed'] = True

    # Case C8286 - 006 - Student | Verify the assignment status as Clicked
    @pytest.mark.skipif(str(8286) not in TESTS, reason='Excluded')
    def test_student_verify_assignment_status_as_clicked_8286(self):
        """Verify the assignment status as Clicked.

        Steps:
        Click on an external assignment under the tab "This Week"
            on the dashboard
        Click on the link to the external assignment
        Close the assignment tab
        Click "Back To Dashboard"

        Expected Result:
        The external assignment is marked as "Clicked" in the Progress column
        on the dashboard
        """
        self.ps.test_updates['name'] = 't1.48.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.48',
            't1.48.006',
            '8286'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        assignments = self.student.driver.find_elements_by_xpath(
            "//div[@class='task row external workable']")
        for assignment in assignments:
            if (assignment.text.find('Epic 48') >= 0):
                assignment.click()
                break

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        link = self.student.driver.find_element_by_link_text(
            'Epic 48')
        original = self.student.current_url()
        self.student.driver.get(link.get_attribute("href"))

        assert('google' in self.student.current_url()), \
            'Not viewing assignment link'

        self.student.sleep(5)
        self.student.driver.get(original)

        assert('tasks' in self.student.current_url()), \
            'Not viewing assignment page'

        assert('steps' in self.student.current_url()), \
            'Not viewing assignment page'

        self.student.find(By.LINK_TEXT, 'Back To Dashboard').click()

        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        externals = self.student.driver.find_elements_by_xpath(
            "//div[@class = 'task row external workable']")

        for assignment in externals:
            if assignment.text.find("Clicked") >= 0 \
                    and assignment.text.find("Epic 48") >= 0:
                self.ps.test_updates['passed'] = True
                break
    def setUp(self):
        """Pretest settings."""
        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(
            use_env_vars=True,
            existing_driver=self.student.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.teacher.login()

        # Create an external assignment for the student to work
        self.teacher.select_course(appearance='physics')
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.ID, 'add-assignment')
            )
        ).click()
        self.teacher.find(
            By.PARTIAL_LINK_TEXT, 'Add External Assignment').click()
        assert('externals/new' in self.teacher.current_url()), \
            'Not on the add an external assignment page'

        self.teacher.find(
            By.XPATH, "//input[@id = 'reading-title']").send_keys('Epic 48')
        self.teacher.find(
            By.XPATH, "//textarea[@class='form-control empty']").send_keys(
            "instructions go here")
        self.teacher.find(
            By.XPATH, "//input[@id = 'hide-periods-radio']").click()

        # Choose the first date calendar[0], second is calendar[1]
        # and set the open date to today
        self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__input-container']")[0].click()
        self.teacher.driver.find_element_by_xpath(
            "//div[@class = 'datepicker__day datepicker__day--today']").click()

        # Choose the second date calendar[1], first is calendar[0]
        self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__input-container']")[1].click()
        while(self.teacher.find(
            By.XPATH,
            "//span[@class = 'datepicker__current-month']"
        ).text != 'December 2016'):
            self.teacher.find(
                By.XPATH,
                "//a[@class = 'datepicker__navigation datepicker__" +
                "navigation--next']").click()

        # Choose the due date of December 31, 2016
        weekends = self.teacher.driver.find_elements_by_xpath(
            "//div[@class = 'datepicker__day datepicker__day--weekend']")
        for day in weekends:
            if day.text == '31':
                due = day
                due.click()
                break

        self.teacher.find(By.XPATH, "//input[@id='external-url']").send_keys(
            "google.com")
        self.teacher.sleep(5)

        # Publish the assignment
        self.teacher.find(
            By.XPATH,
            "//button[@class='async-button -publish btn btn-primary']").click()
        self.teacher.sleep(60)
        self.student.login()
Example #50
0
class TestViewClassScores(unittest.TestCase):
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
        else:
            self.teacher = Teacher(use_env_vars=True)
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)

        self.teacher.login()

        # go to student scores
        self.teacher.select_course(appearance='biology')
        self.teacher.driver.find_element(By.LINK_TEXT,
                                         'Student Scores').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//span[contains(text(), "Student Scores")]'))).click()

    def tearDown(self):
        """Test destructor."""
        if not LOCAL_RUN:
            self.ps.update_job(job_id=str(self.teacher.driver.session_id),
                               **self.ps.test_updates)
        try:
            self.teacher.delete()
        except:
            pass

    @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded')
    def test_review_student_scores(self):
        '''
        Go to https://tutor-qa.openstax.org/
        Click on the 'Login' button
        Enter the teacher user account [ teacher01 | password ] in the username
        and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name

        Click "Student Scores" from the calendar dashboard
        ***The user is presented with scores at due date (t2.10.06)***

        Click on the orange flag in the upper right corner of a progress cell
        for the desired student
        ***The user is presented with the current score (t2.10.07)***

        Period tabs are displayed
        ***Period tabs are displayed (t1.23.02)***

        Click on the tab for the desired period
        ***Scores for selected period are displayed in table (t1.23.01)***

        Click on the name of an arbitrary student
        ***Performance Forecast for selected student is displayed (t1.23.05)***

        Click on the name of the student to open a drop down menu
        In the drop down menu click the name of selected student
        ***Performance Forecast for second selected student is displayed
        (t1.23.06)***

        Click on the info icon next to the student's name
        ***Information about Performance Forecast is displayed. (t1.23.07)***

        Click on the "Return to Scores" button
        ***User at Student scores page on the first tab (t1.23.08)***

        Click on "Student Name" on the table [this will make the names in
        reverse alphabetical order by last name]
        Click on "Student Name" on the table again [this will make the names in
        alphabetical order by last name]
        ***The students are sorted alphabetically by last name. (t1.23.09)***

        Click "Progress" button
        ***Students are sorted by completion of selected assignment.
        (t1.23.10)***

        Click on the tab for selected section
        ***Due date for selected assignment is displayed in the cell below the
        assignment name (t1.23.011)***

        Corresponds to...
        t2.10 06,07
        t1.23 1,3,5 --> 11
        '''

        # t1.23.01 --> Scores for selected period are displayed in table
        assert ('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        # (t1.23.02) --> Period tabs are displayed
        current_period = 0
        period_tabs = self.teacher.wait.until(
            expect.visibility_of_elements_located(
                (By.XPATH,
                 '//span[contains(@class, "tab-item-period-name")]')))
        period_tabs[current_period + 1].click()

        # DO SOMETHING HERE TO WAIT FOR THIS TO BE CLICKABLE
        period_tabs[current_period].click()

        # (t2.10.06) -->  The user is presented with scores at due date
        #  Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="course-scores-container"]')))

        # t2.10.07 --> The user is presented with the current score
        scroll_bar = self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"ScrollbarLayout_faceHorizontal")]')
        scroll_width = scroll_bar.size['width']
        scroll_total_size = self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"ScrollbarLayout_mainHorizontal")]'
        ).size['width']
        bar = scroll_width
        while (bar < scroll_total_size):
            try:
                late_caret = self.teacher.find(
                    By.XPATH, '//div[@class="late-caret accepted"]')
                late_caret.click()
                pie_progress = late_caret.findElement(
                    By.XPATH, "/..//svg[contains(@class,'pie-progress')]")
                print(pie_progress)

                # self.teacher.find(
                #     By.XPATH,
                #     '//div[contains(@class,"late-status")]' +
                #     '//span[text()="due date"]'
                # )
                # break
            except (NoSuchElementException, ElementNotVisibleException,
                    WebDriverException):
                bar += scroll_width
                if scroll_total_size <= bar:
                    print("No Late assignments for this class :(")
                    raise Exception
                # drag scroll bar instead of scrolling
                actions = ActionChains(self.teacher.driver)
                actions.move_to_element(scroll_bar)
                actions.click_and_hold()
                actions.move_by_offset(scroll_width, 0)
                actions.release()
                actions.perform()

        # t1.23.05 --> Performance Forecast for selected student is displayed
        # Test steps and verification assertions
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(@class,"name-cell")]'))).click()
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//span[contains(text(), "Performance Forecast for")]')))

        # (t1.23.06) --> Performance Forecast for second selected student is
        # displayed
        self.teacher.find(By.ID, 'student-selection').click()
        student_select = self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(@role, "menuitem")]' +
                 '//span[contains(@class,"-name")]')))

        student_name = student_select.text
        student_select.click()

        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//span[contains(text(), "' + student_name + '")]')))

        # (t1.23.07 --> Information about Performance Forecast is displayed.
        self.teacher.find(By.XPATH,
                          '//button[contains(@class,"info-link")]').click()
        self.teacher.driver.find_element(
            By.XPATH, '//div[contains(@class,"tooltip-inner")]')

        # (t1.23.08 --> User at Student scores page on the first tab
        self.teacher.find(By.LINK_TEXT, 'Return to Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        # NOTE: ## signifies the selectors that possibly need editing

        # (t1.23.09 --> The students are sorted alphabetically by last name.

        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[contains(text(),"Name and Student ID")]'))).click()

        # WATCH OUT-- THERE'S MULTIPLE HEADER-CELLS
        self.teacher.find(
            By.XPATH, '//div[contains(@class,"header-row")]' +
            '//div[contains(@class,"is-descending")]')

        # self.teacher.find(
        #     By.XPATH, '//div[contains(text(),"Name and Student ID")]')
        # .click() ##
        #
        #
        # self.teacher.find(
        #     By.XPATH,
        #     '//div[contains(@class,"header-cell")]' +
        #     '//div[contains(@class,"is-ascending")]')

        # t1.23.10 --> Students are sorted by completion of selected
        # assignment.

        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"scores-cell")]' +
                 '//div[contains(text(),"Progress")]'))).click()

        self.teacher.find(
            By.XPATH, '//div[contains(@class,"scores-cell")]' +
            '//div[contains(@class,"is-descending")]')

        # self.teacher.driver.find_element(
        #     By.XPATH,
        #     '//div[contains(@class,"scores-cell")]' + ##
        #     '//div[contains(text(),"Progress")]' ##
        # ).click()
        # self.teacher.driver.find_element(
        #     By.XPATH,
        #     '//div[contains(@class,"scores-cell")]' + ##
        #     '//div[contains(@class,"is-ascending")]') ##

        # t1.23.11 --> Due date for selected assignment is displayed in
        # the cell below the assignment name

        assignment_cell = self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[contains(@data-assignment-type,"reading")]')))
        assignment_cell.find_element(
            By.XPATH, '//following-sibling::div[contains(@class,"due")]')
class TestImproveScoresReporting(unittest.TestCase):
    """T2.08 - Improve Scores Reporting."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(use_env_vars=True,
                               pasta_user=self.ps,
                               capabilities=self.desired_capabilities)

        self.teacher.login()

    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

    # 14671 - 001 - Teacher | View a Scores Export for my students' work
    @pytest.mark.skipif(str(14671) not in TESTS, reason='Excluded')
    def test_teacher_view_a_scores_export_for_my_students_work_14671(self):
        """View a Scores Export for my students' work.

        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 Tutor course name
        Click "Student Scores" from calendar dashboard
        Click "Export"

        Expected Result:
        The user is presented with a scores export
        """
        self.ps.test_updates['name'] = 't2.08.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.001', '14671']
        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

    '''
    # 14672 - 002 - Teacher | Import Tutor high school Student Scores export
    # into a gradebook
    @pytest.mark.skipif(str(14672) not in TESTS, reason='Excluded')
    def test_teacher_import_tutor_hs_student_scores_export_14672(self):
        """Import Tutor high school Student Scores export into a gradebook.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.08.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't2',
            't2.08',
            't2.08.002',
            '14672'
        ]
        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
    '''
    '''
    # 14674 - 003 - Teacher | Import Tutor college Student Scores export into
    # an LMS
    @pytest.mark.skipif(str(14674) not in TESTS, reason='Excluded')
    def test_teacher_import_tutor_college_student_scores_14674(self):
        """Import Tutor college Student Scores export into an LMS.

        Steps:


        Expected Result:

        """
        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',
            '14674'
        ]
        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
    '''
    '''
    # 14826 - 004 - Teacher | Import Tutor college Student Scores into an LMS
    @pytest.mark.skipif(str(14826) not in TESTS, reason='Excluded')
    def test_teacher_import_tutor_college_student_scores_into_lms_14826(self):
        """Import Tutor college Student Scores into an LMS.

        Steps:


        Expected Result:

        """
        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',
            '14826'
        ]
        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
    '''

    # 14827 - 005 - Teacher | View the overall score column
    @pytest.mark.skipif(str(14827) not in TESTS, reason='Excluded')
    def test_teacher_view_the_overall_score_column_14827(self):
        """View the overall score column.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard

        Expected Result:
        The user is presented with the overall score column
        """
        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', '14827']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.select_course(appearance='college_physics')

        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Student Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        self.teacher.sleep(5)

        self.teacher.find(By.XPATH, "//div[@class='overall-header-cell']")

        self.teacher.sleep(5)

        self.ps.test_updates['passed'] = True

    # 14828 - 006 - Teacher | Overall score percentage does not change format
    # when selecting Number in the Percentage/Number toggle
    @pytest.mark.skipif(str(14828) not in TESTS, reason='Excluded')
    def test_teacher_overall_score_percentage_does_not_change_form_14828(self):
        """Overall score percentage does not change format.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Click "Number"

        Expected Result:
        Overall score percentage does not change format when selecting Number
        in the Percentage/Number toggle
        """
        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', '14828']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.select_course(appearance='college_physics')

        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Student Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        self.teacher.sleep(5)

        average1 = self.teacher.find(By.XPATH, "//div[@class='average']").text
        self.teacher.find(By.XPATH,
                          "//button[@class='btn btn-sm btn-default']").click()
        self.teacher.sleep(3)
        average2 = self.teacher.find(By.XPATH, "//div[@class='average']").text

        assert(average1 == average2), \
            'Overall average is not the same between percentage and number'

        self.ps.test_updates['passed'] = True

    # 14829 - 007 - Teacher | No score is displayed for readings
    @pytest.mark.skipif(str(14829) not in TESTS, reason='Excluded')
    def test_teacher_no_score_is_displayed_for_reading_14829(self):
        """No score is displayed for readings.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Look for a reading assignment

        Expected Result:
        The user is presented with progress icon but no score
        """
        self.ps.test_updates['name'] = 't2.08.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.007', '14829']
        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

    # 14830 - 008 - Teacher | The class average info icon displays a definition
    # of how class and overall scores are calculated
    @pytest.mark.skipif(str(14830) not in TESTS, reason='Excluded')
    def test_teacher_the_class_average_info_icon_displayed_a_defin_14830(self):
        """The class average info icon displays a definition.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Click on the info icon next to "Class Average"

        Expected Result:
        The class average info icon displays a definition of how class and
        overall scores are calculated
        """
        self.ps.test_updates['name'] = 't2.08.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.008', '14830']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.select_course(appearance='college_physics')

        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Student Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        self.teacher.sleep(5)
        self.teacher.find(
            By.XPATH,
            "//i[@class='tutor-icon fa fa-info-circle clickable']").click()
        self.teacher.sleep(2)
        self.teacher.find(By.XPATH, "//div[@class='popover-content']")

        self.ps.test_updates['passed'] = True

    # 14831 - 009 - Teacher | Accept late work
    @pytest.mark.skipif(str(14831) not in TESTS, reason='Excluded')
    def test_teacher_accept_late_work_14831(self):
        """Accept late work.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Click on the orange triangle in the upper right corner of a progress
            cell
        Click "Accept late score"

        Expected Result:
        The late score replaces the score at due date
        """
        self.ps.test_updates['name'] = 't2.08.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.009', '14831']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.select_course(appearance='college_physics')

        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Student Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        self.teacher.sleep(10)

        found = False

        scrollbar = self.teacher.find(
            By.XPATH, "//div[@class='ScrollbarLayout_main " +
            "ScrollbarLayout_mainHorizontal public_Scrollbar_main " +
            "public_Scrollbar_mainOpaque']")
        scrollbar.click()

        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(scrollbar)
        actions.click(scrollbar)
        actions.perform()

        newbar = self.teacher.find(
            By.XPATH, "//div[@class='ScrollbarLayout_main " +
            "ScrollbarLayout_mainHorizontal public_Scrollbar_main " +
            "public_Scrollbar_mainOpaque public_Scrollbar_mainActive']")
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(newbar)
        actions.click(newbar)
        actions.perform()
        scrolls = 0
        # Four arrow rights bring a new assignment into view, try to bring
        # Bring three new assignments into view at a time
        for num in range(100):
            for num1 in range(12):
                newbar.send_keys(Keys.ARROW_RIGHT)
            if len(
                    self.teacher.driver.find_elements_by_xpath(
                        "//div[@class='late-caret']")) > 0:
                for num2 in range(5):
                    newbar.send_keys(Keys.ARROW_RIGHT)
                while not found:
                    try:
                        caret = self.teacher.find(
                            By.XPATH, "//div[@class='late-caret']")

                        self.teacher.sleep(3)
                        caret.click()

                        self.teacher.find(
                            By.XPATH,
                            "//button[@class='late-button btn btn-default']"
                        ).click()
                        """
                        self.teacher.find_elements_by_xpath(
                            By.XPATH, "//div[@class='late-caret accepted']"
                        )[index].click()

                        self.teacher.find(
                            By.XPATH,
                            "//button[@class='late-button btn btn-default']"
                        ).click()
                        """
                        found = True
                        break

                    except:

                        if scrolls == 20:
                            break
                        try:
                            scrollbar = self.teacher.find(
                                By.XPATH,
                                "//div[@class='ScrollbarLayout_main " +
                                "ScrollbarLayout_mainVertical " +
                                "public_Scrollbar_main']")

                            scrollbar.click()

                        except:
                            pass

                        newbar = self.teacher.find(
                            By.XPATH, "//div[@class='ScrollbarLayout_main " +
                            "ScrollbarLayout_mainVertical " +
                            "public_Scrollbar_main " +
                            "public_Scrollbar_mainActive']")

                        actions = ActionChains(self.teacher.driver)
                        actions.move_to_element(newbar)
                        actions.click(newbar)
                        actions.perform()
                        for i in range(3):
                            scrolls += 1
                            newbar.send_keys(Keys.ARROW_DOWN)

                break

        lates = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='late-caret accepted']")

        revert = False
        if found:
            for item in lates:
                try:
                    item.click()
                    self.teacher.find(
                        By.XPATH,
                        "//button[@class='late-button btn btn-default']"
                    ).click()
                    revert = True
                    break

                except:
                    pass

        self.teacher.sleep(5)
        assert(found), \
            'Not found'

        assert(revert), \
            'Didnt revert'

        self.ps.test_updates['passed'] = True

    # 14832 - 010 - Teacher | Un-accept late work
    @pytest.mark.skipif(str(14832) not in TESTS, reason='Excluded')
    def test_teacher_unaccept_late_work_14832(self):
        """Un-accept late work.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Click on the gray triangle in the upper right corner of a progress cell
        Click "Use this score"

        Expected Result:
        The score is converted back to the score at due date
        """
        self.ps.test_updates['name'] = 't2.08.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.010', '14832']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.select_course(appearance='college_physics')

        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Student Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        self.teacher.sleep(10)

        found = False

        scrollbar = self.teacher.find(
            By.XPATH, "//div[@class='ScrollbarLayout_main " +
            "ScrollbarLayout_mainHorizontal public_Scrollbar_main " +
            "public_Scrollbar_mainOpaque']")
        scrollbar.click()

        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(scrollbar)
        actions.click(scrollbar)
        actions.perform()

        newbar = self.teacher.find(
            By.XPATH, "//div[@class='ScrollbarLayout_main " +
            "ScrollbarLayout_mainHorizontal public_Scrollbar_main " +
            "public_Scrollbar_mainOpaque public_Scrollbar_mainActive']")
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(newbar)
        actions.click(newbar)
        actions.perform()
        scrolls = 0
        # Four arrow rights bring a new assignment into view, try to bring
        # Bring three new assignments into view at a time
        for num in range(100):
            for num1 in range(12):
                newbar.send_keys(Keys.ARROW_RIGHT)
            if len(
                    self.teacher.driver.find_elements_by_xpath(
                        "//div[@class='late-caret accepted']")) > 0:
                for num2 in range(3):
                    newbar.send_keys(Keys.ARROW_RIGHT)
                while not found:
                    try:

                        caret = self.teacher.find(
                            By.XPATH, "//div[@class='late-caret accepted']")
                        self.teacher.sleep(2)
                        caret.click()
                        self.teacher.sleep(5)

                        self.teacher.find(
                            By.XPATH,
                            "//button[@class='late-button btn btn-default']"
                        ).click()
                        self.teacher.sleep(5)
                        """
                        self.teacher.find_elements_by_xpath(
                            By.XPATH, "//div[@class='late-caret accepted']"
                        )[index].click()

                        self.teacher.find(
                            By.XPATH,
                            "//button[@class='late-button btn btn-default']"
                        ).click()
                        """
                        found = True
                        break

                    except:

                        if scrolls == 20:
                            break
                        try:
                            scrollbar = self.teacher.find(
                                By.XPATH,
                                "//div[@class='ScrollbarLayout_main " +
                                "ScrollbarLayout_mainVertical " +
                                "public_Scrollbar_main']")

                            scrollbar.click()

                        except:
                            pass

                        newbar = self.teacher.find(
                            By.XPATH, "//div[@class='ScrollbarLayout_main " +
                            "ScrollbarLayout_mainVertical " +
                            "public_Scrollbar_main " +
                            "public_Scrollbar_mainActive']")

                        actions = ActionChains(self.teacher.driver)
                        actions.move_to_element(newbar)
                        actions.click(newbar)
                        actions.perform()
                        for i in range(1):
                            scrolls += 1
                            newbar.send_keys(Keys.ARROW_DOWN)

                break

        lates = self.teacher.driver.find_elements_by_xpath(
            "//div[@class='late-caret']")

        revert = False
        if found:
            for item in lates:
                try:
                    item.click()
                    self.teacher.find(
                        By.XPATH,
                        "//button[@class='late-button btn btn-default']"
                    ).click()
                    revert = True
                    break

                except:
                    pass

        self.teacher.sleep(5)
        assert(found), \
            'Not found'

        assert(revert), \
            'Didnt revert'

        self.ps.test_updates['passed'] = True

    # 14833 - 011 - Teacher | When accepting late work, the progress icon
    # changes to reflect the last worked progress
    @pytest.mark.skipif(str(14833) not in TESTS, reason='Excluded')
    def test_teacher_when_accepting_late_work_the_progress_icon_ch_14833(self):
        """The progress icon changes to reflect the last worked progress.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Click on the orange triangle in the upper right corner of a
            progress cell
        Click "Accept late score"

        Expected Result:
        The progress icon changes to reflect the last worked progress
        """
        self.ps.test_updates['name'] = 't2.08.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.011', '14833']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.select_course(appearance='college_physics')

        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

        self.teacher.find(By.PARTIAL_LINK_TEXT, 'Student Scores').click()

        assert('scores' in self.teacher.current_url()), \
            'Not viewing Student Scores'

        self.teacher.sleep(10)

        found = False

        # Setup scrollbar for scrolling
        scrollbar = self.teacher.find(
            By.XPATH, "//div[@class='ScrollbarLayout_main " +
            "ScrollbarLayout_mainHorizontal public_Scrollbar_main " +
            "public_Scrollbar_mainOpaque']")
        scrollbar.click()

        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(scrollbar)
        actions.click(scrollbar)
        actions.perform()

        newbar = self.teacher.find(
            By.XPATH, "//div[@class='ScrollbarLayout_main " +
            "ScrollbarLayout_mainHorizontal public_Scrollbar_main " +
            "public_Scrollbar_mainOpaque public_Scrollbar_mainActive']")
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(newbar)
        actions.click(newbar)
        actions.perform()
        scrolls = 0

        p = False
        for i in range(6):
            newbar.send_keys(Keys.PAGE_UP)
        self.teacher.sleep(3)
        # Four arrow rights bring a new assignment into view, try to bring
        # Bring three new assignments into view at a time
        for num in range(100):
            for num1 in range(12):
                newbar.send_keys(Keys.ARROW_RIGHT)
            if len(
                    self.teacher.driver.find_elements_by_xpath(
                        "//div[@class='late-caret']")) > 0:
                for num2 in range(3):
                    newbar.send_keys(Keys.ARROW_RIGHT)

                while not found:
                    try:
                        caret = self.teacher.find(
                            By.XPATH, "//div[@class='late-caret']")

                        try:
                            parent = caret.find_element_by_xpath(
                                "..").find_element_by_xpath("..")
                        except:
                            pass
                        try:
                            worked = parent.find_element_by_class_name(
                                "worked")
                        except:
                            pass
                        try:
                            not_started = worked.find_elements_by_class_name(
                                "not-started")
                        except:
                            pass

                        try:
                            if len(worked.find_elements_by_tag_name(
                                    'path')) > 0:
                                p = True

                        except:
                            pass

                        caret1 = caret.find_element_by_xpath("..")

                        caret1.click()
                        self.teacher.find(
                            By.XPATH,
                            "//button[@class='late-button btn btn-default']"
                        ).click()
                        found = True
                        break

                    # Scroll down if the late assignment is not immediately
                    # visible, continue to scroll until found
                    except:

                        if scrolls == 20:
                            break
                        try:
                            scrollbar = self.teacher.find(
                                By.XPATH,
                                "//div[@class='ScrollbarLayout_main " +
                                "ScrollbarLayout_mainVertical " +
                                "public_Scrollbar_main']")

                            scrollbar.click()

                        except:
                            pass

                        newbar = self.teacher.find(
                            By.XPATH, "//div[@class='ScrollbarLayout_main " +
                            "ScrollbarLayout_mainVertical " +
                            "public_Scrollbar_main " +
                            "public_Scrollbar_mainActive']")

                        actions = ActionChains(self.teacher.driver)
                        actions.move_to_element(newbar)
                        actions.click(newbar)
                        actions.perform()
                        for i in range(1):
                            scrolls += 1
                            newbar.send_keys(Keys.ARROW_DOWN)

                break

        revert = False
        diff = False

        # Case if assignment was not started at all before due date
        if len(not_started) > 0:
            slice_late = worked.find_elements_by_tag_name('circle')
            assert(slice_late[0].get_attribute('class') == 'slice late'), \
                'No change'

            diff = True

        # Case if assignment was partially complete before due date
        else:
            assert (p)
            assert(len(worked.find_elements_by_tag_name('path')) == 0), \
                'No change'

            diff = True

        assert(diff), \
            'No change'

        item = worked.find_element_by_xpath(
            "//div[@class='late-caret accepted']")

        item.click()
        self.teacher.find(
            By.XPATH,
            "//button[@class='late-button btn btn-default']").click()
        revert = True

        self.teacher.sleep(5)
        assert(found), \
            'Not found'

        assert(revert), \
            'Didnt revert'

        self.ps.test_updates['passed'] = True

    # 14834 - 012 - Teacher | Assignments that are not due yet are not
    # displayed
    @pytest.mark.skipif(str(14834) not in TESTS, reason='Excluded')
    def test_teacher_assignments_that_are_not_due_yet_are_not_disp_14834(self):
        """Assignment that is not due yet is not displayed.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.08.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.012', '14834']
        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

    # 14835 - 013 - Teacher | Supress columns in Score Report
    @pytest.mark.skipif(str(14835) not in TESTS, reason='Excluded')
    def test_teacher_suppress_columns_in_score_report_14835(self):
        """Supress columns in Score Report.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.08.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.013', '14835']
        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

    # 14836 - 014 - Teacher | External assignments are not included in the
    # scores export
    @pytest.mark.skipif(str(14836) not in TESTS, reason='Excluded')
    def test_teacher_external_assignments_are_not_included_in_the_14836(self):
        """External assignments are not included in the scores export.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click "Student Scores" from calendar dashboard
        Click "Export"

        Expected Result:
        External assignments are not included in the scores export
        """
        self.ps.test_updates['name'] = 't2.08.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.014', '14836']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
class 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))
Example #54
0
class TestGuideMonitorSupportAndTrainUsers(unittest.TestCase):
    """T2.18 - Guide, Monitor, Support, and Train Users."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(use_env_vars=True,
                               pasta_user=self.ps,
                               capabilities=self.desired_capabilities)

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(job_id=str(self.teacher.driver.session_id),
                           **self.ps.test_updates)
        try:
            self.teacher.delete()
        except:
            pass

    # 14752 - 001 - User | In-app Notification of downtime
    @pytest.mark.skipif(str(14752) not in TESTS, reason='Excluded')
    def test_user_inapp_notification_of_downtime_14752(self):
        """In-app Notification of downtime.

        Steps:

        Go to Tutor
        Log in as admin
        Click "Admin" from the user menu
        Click "System Setting"
        Click "Notifications"
        Enter a new notification into the text box
        Click "Add"
        Log out of admin
        Log in as teacher01

        Expected Result:
        An orange header with the notification pops up when you sign in
        """
        self.ps.test_updates['name'] = 't2.18.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.001', '14752']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 14751 - 002 - Teacher | Directed to a "No Courses" page when not in any
    # courses yet
    @pytest.mark.skipif(str(14751) not in TESTS, reason='Excluded')
    def test_teacher_directed_to_a_no_courses_page_when_not_in_any_14751(self):
        """Directed to a "No Courses" page when not in any courses yet.

        Steps:
        Go to tutor-qa.openstax.org
        Sign in as demo_teacher; password

        Expected Result:
        The message "We cannot find an OpenStax course associated with your
        account" displays with help links below
        """
        self.ps.test_updates['name'] = 't2.18.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.002', '14751']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58279 - 003 - Teacher | View "Getting Started with Tutor" Guide
    @pytest.mark.skipif(str(58279) not in TESTS, reason='Excluded')
    def test_teacher_view_getting_started_with_tutor_guide_58279(self):
        """View "Getting Started with Tutor" Guide.

        Steps:
        Click "Tutor Instructors. Get help"

        Expected Result:
        Tutor Help Center opens in another tab with the Getting Started guide
        """
        self.ps.test_updates['name'] = 't2.18.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.003', '58279']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58280 - 004 - Teacher | Access Tutor Help Center after registering for
    # a course
    @pytest.mark.skipif(str(58280) not in TESTS, reason='Excluded')
    def test_teacher_access_tutor_help_center_after_registering_58280(self):
        """Access Tutor Help Center after registering for a course.

        Steps:
        Go to Tutor
        Sign in as teacher01
        Click on a Tutor course if the user is in more than one
        Click "Get Help" from the user menu in the upper right corner of the
            screen

        Expected Result:
        The user is presented with the Tutor Help Center
        """
        self.ps.test_updates['name'] = 't2.18.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.004', '58280']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58284 - 005 - Teacher | Submit a question
    @pytest.mark.skipif(str(58284) not in TESTS, reason='Excluded')
    def test_teacher_submit_a_question_58284(self):
        """Submit a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter

        Expected Result:
        The user is presented with search results
        """
        self.ps.test_updates['name'] = 't2.18.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.005', '58284']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58352 - 006 - Teacher | View "Contact Us" button after submitting a
    # question
    @pytest.mark.skipif(str(58352) not in TESTS, reason='Excluded')
    def test_teacher_view_contact_us_button_after_submitting_quest_58352(self):
        """View "Contact Us" button after submitting a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Scroll to the bottom of the screen

        Expected Result:
        "Contact Us" button exists
        """
        self.ps.test_updates['name'] = 't2.18.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.006', '58352']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58288 - 007 - Teacher | View an article after submitting a question
    @pytest.mark.skipif(str(58288) not in TESTS, reason='Excluded')
    def test_teacher_view_an_article_after_submitting_a_question_58288(self):
        """View an article after submitting a question.

        Steps:

        Click "Get Help" from the user menu in the upper right corner of the
        screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result

        Expected Result:
        The user is presented with an article containing answer to the question
        """
        self.ps.test_updates['name'] = 't2.18.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.007', '58288']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58313 - 008 - Teacher | Indicate that the article was helpful
    @pytest.mark.skipif(str(58313) not in TESTS, reason='Excluded')
    def test_teacher_indicate_that_the_article_was_helpful_58313(self):
        """Indicate that the article was helpful.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "Yes"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed
        """
        self.ps.test_updates['name'] = 't2.18.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.008', '58313']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58314 - 009 - Teacher | Negative feedback renders a feedback popup box
    @pytest.mark.skipif(str(58314) not in TESTS, reason='Excluded')
    def test_teacher_negative_feedback_renders_feedback_popup_box_58314(self):
        """Negative feedback renders a feedback popup box.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"

        Expected Result:
        The user is presented with a popup box that allows them to input
        feedback
        """
        self.ps.test_updates['name'] = 't2.18.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.009', '58314']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58315 - 010 - Teacher | Submit feedback for an article
    @pytest.mark.skipif(str(58315) not in TESTS, reason='Excluded')
    def test_teacher_submit_feedback_for_an_article_58315(self):
        """Submit feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed in the box
        """
        self.ps.test_updates['name'] = 't2.18.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.010', '58315']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58322 - 011 - Teacher | Close window after submitting feedback for an
    # article
    @pytest.mark.skipif(str(58322) not in TESTS, reason='Excluded')
    def test_teacher_close_window_after_submitting_feedback_for_58322(self):
        """Close window after submitting feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"
        Click "Close window"

        Expected Result:
        The popup box closes and the message "Thanks for your feedback"
        displays beneath "Feedback"
        """
        self.ps.test_updates['name'] = 't2.18.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.011', '58322']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58316 - 012 - Teacher | Cancel feedback
    @pytest.mark.skipif(str(58316) not in TESTS, reason='Excluded')
    def test_teacher_cancel_feedback_before_making_changes_58316(self):
        """Cancel feedback.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        [optional] Enter feedback into the text box
        Click "Cancel"

        Expected Result:
        The popup box closes
        """
        self.ps.test_updates['name'] = 't2.18.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.012', '58316']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58318 - 013 - Teacher | View related articles
    @pytest.mark.skipif(str(58318) not in TESTS, reason='Excluded')
    def test_teacher_view_related_articles_58318(self):
        """View related articles.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Related Articles"
        Click on one of the articles (if any)

        Expected Result:
        The user is presented with the related article
        """
        self.ps.test_updates['name'] = 't2.18.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.013', '58318']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58319 - 014 - Teacher | Submit a question to Customer Support
    @pytest.mark.skipif(str(58319) not in TESTS, reason='Excluded')
    def test_teacher_submit_a_question_to_customer_support_58319(self):
        """Submit a question to Customer Support.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        CLick "Search" or press enter
        Click on a search result
        Scroll to the bottom of the page
        CLick "Contact Us"
        Fill out the required fields
        Enter "Submit"

        Expected Result:
        The message "Thank you for your message! We'll be back to you within
        one business day" is displayed
        """
        self.ps.test_updates['name'] = 't2.18.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.014', '58319']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 14755 - 015 - Teacher | View guided tutorials of Tutor
    @pytest.mark.skipif(str(14755) not in TESTS, reason='Excluded')
    def test_teacher_view_guided_tutorials_of_concept_coach_14755(self):
        """View guided tutorials of Tutor.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.18.015' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.015', '14755']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 14750 - 016 - Student | Directed to a "No Courses" page when not in any
    # courses yet
    @pytest.mark.skipif(str(14750) not in TESTS, reason='Excluded')
    def test_student_directed_to_a_no_courses_page_when_not_in_any_14750(self):
        """Directed to a "No Courses" page when not in any courses yet.

        Steps:
        Go to Tutor
        Log in as qa_student_37003

        Expected Result:
        The message "We cannot find an OpenStax course associated with your
        account" displays with help links
        """
        self.ps.test_updates['name'] = 't2.18.016' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.016', '14750']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58336 - 017 - Student | View "Getting Started with Tutor" Guide
    @pytest.mark.skipif(str(58336) not in TESTS, reason='Excluded')
    def test_student_view_getting_started_with_tutor_guide_58336(self):
        """View "Getting Started with Tutor" Guide.

        Steps:
        Click "Tutor Students. Get help"

        Expected Result:
        Tutor Help Center opens in another tab with the Getting Started guide
        """
        self.ps.test_updates['name'] = 't2.18.017' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.017', '58336']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58337 - 018 - Student | Access Tutor Help Center after registering for a
    # course
    @pytest.mark.skipif(str(58337) not in TESTS, reason='Excluded')
    def test_student_access_tutor_help_center_after_registering_58337(self):
        """Access Tutor Help Center after registering for a course.

        Steps:
        Go to Tutor
        Sign in as student01
        Click on a Tutor course if the user is in more than one
        Click "Get Help" from the user menu in the upper right corner of the
            screen

        Expected Result:
        The user is presented with the Tutor Help Center
        """
        self.ps.test_updates['name'] = 't2.18.018' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.018', '58337']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58338 - 019 - Student | Submit a question
    @pytest.mark.skipif(str(58338) not in TESTS, reason='Excluded')
    def test_student_submit_a_question_58338(self):
        """Submit a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter

        Expected Result:
        The user is presented with search results
        """
        self.ps.test_updates['name'] = 't2.18.019' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.019', '58338']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58353 - 020 - Student | View "Contact Us" button after submitting a
    # question
    @pytest.mark.skipif(str(58353) not in TESTS, reason='Excluded')
    def test_student_view_contact_us_button_after_submitting_quest_58353(self):
        """View "Contact Us" button after submitting a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Scroll to the bottom of the page

        Expected Result:
        "Contact Us" button exists
        """
        self.ps.test_updates['name'] = 't2.18.020' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.020', '58353']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58339 - 021 - Student | View an article after submitting a question
    @pytest.mark.skipif(str(58339) not in TESTS, reason='Excluded')
    def test_student_view_an_article_after_submitting_a_question_58339(self):
        """View an article after submitting a question.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result

        Expected Result:
        The user is presented with an article containing answer to the question
        """
        self.ps.test_updates['name'] = 't2.18.021' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.021', '58339']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58340 - 022 - Student | Indicate that the article was helpful
    @pytest.mark.skipif(str(58340) not in TESTS, reason='Excluded')
    def test_student_indicate_that_the_article_was_helpful_58340(self):
        """Indicate that the article was helpful.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "Yes"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed
        """
        self.ps.test_updates['name'] = 't2.18.022' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.022', '58340']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58341 - 023 - Student | Negative feedback renders a feedback popup box
    @pytest.mark.skipif(str(58341) not in TESTS, reason='Excluded')
    def test_student_negative_feedback_renders_feedback_popup_box_58341(self):
        """Negative feedback renders a feedback popup box.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"

        Expected Result:
        The user is presented with a popup box that allows them to input
        feedback
        """
        self.ps.test_updates['name'] = 't2.18.023' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.023', '58341']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58342 - 024 - Student | Submit feedback for an article
    @pytest.mark.skipif(str(58342) not in TESTS, reason='Excluded')
    def test_student_submit_feedback_for_an_article_58342(self):
        """Submit feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"

        Expected Result:
        A message that says "Thanks for your feedback!" is displayed in the box
        """
        self.ps.test_updates['name'] = 't2.18.024' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.024', '58342']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58343 - 025 - Student | Close window after submitting feedback for an
    # article
    @pytest.mark.skipif(str(58343) not in TESTS, reason='Excluded')
    def test_student_close_window_after_submitting_feedback_for_58343(self):
        """Close window after submitting feedback for an article.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        Enter feedback into the box that pops up
        Click "Submit"
        Click "Close window"

        Expected Result:
        The popup box closes and the message "Thanks for your feedback"
        displays beneath "Feedback"
        """
        self.ps.test_updates['name'] = 't2.18.025' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.025', '58343']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58344 - 026 - Student | Cancel feedback
    @pytest.mark.skipif(str(58344) not in TESTS, reason='Excluded')
    def test_student_cancel_feedback_58344(self):
        """Cancel feedback.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Feedback"
        Click "No"
        [optional] Enter feedback into text box
        Click "Cancel"

        Expected Result:
        The popup box closes
        """
        self.ps.test_updates['name'] = 't2.18.026' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.026', '58344']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58346 - 027 - Student | View related articles
    @pytest.mark.skipif(str(58346) not in TESTS, reason='Excluded')
    def test_student_view_related_articles_58346(self):
        """View related articles.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to "Related Articles"
        Click on one of the articles (if any)

        Expected Result:
        The user is presented with the related article
        """
        self.ps.test_updates['name'] = 't2.18.027' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.027', '58346']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58347 - 028 - Student | Submit a question to Customer Support
    @pytest.mark.skipif(str(58347) not in TESTS, reason='Excluded')
    def test_student_submit_a_question_to_customer_support_58347(self):
        """Submit a question to Customer Support.

        Steps:
        Click "Get Help" from the user menu in the upper right corner of the
            screen
        Enter a question or search words into the search engine
        Click "Search" or press enter
        Click on a search result
        Scroll to the bottom of the page
        Click "Contact Us"
        Fill out the required fields
        Enter "Submit"

        Expected Result:
        The message "Thank you for your message! We'll be back to you within
        one business day" is displayed
        """
        self.ps.test_updates['name'] = 't2.18.028' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.028', '58347']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True

    # 58348 - 029 - Student | View guided tutorials of Tutor
    @pytest.mark.skipif(str(58348) not in TESTS, reason='Excluded')
    def test_student_view_guided_tutorials_of_concept_coach_58348(self):
        """View guided tutorial of Tutor.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 't2.18.029' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.18', 't2.18.029', '58348']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)

        self.ps.test_updates['passed'] = True
Example #55
0
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

    '''
    def test_teacher_view_instructor_notification_112523(self):
        """View an active instructor-only system notification.

        Steps:

        Expected Result:

        """
        self.ps.test_updates['name'] = 't1.57.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.57', 't1.57.010', '112523']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'System Setting'))).click()
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Notifications'))).click()
        self.admin.sleep(5)

        self.admin.find(
            By.XPATH,
            "//div[3]//input[@id='message']").send_keys('automated test')

        self.admin.driver.find_elements_by_xpath(
            "//input[@class='btn btn-default']")[1].click()

        self.admin.sleep(5)

        # View notification as student
        teacher = Teacher(use_env_vars=True)
        teacher.login()
        teacher.select_course(appearance='physics')
        teacher.sleep(10)
        notifs = teacher.driver.find_elements_by_xpath(
            "//div[@class='notification system']/span")

        found = False

        for notif in notifs:
            if notif.text.find("automated test") >= 0:
                found = True

        teacher.delete()

        # Delete notification
        notif = self.admin.driver.find_elements_by_xpath(
            "//div[@class='col-xs-12']")

        for index, n in enumerate(notif):
            if n.text.find('automated test') >= 0:
                self.admin.driver.find_elements_by_xpath(
                    "//a[@class='btn btn-warning']")[index].click()
                self.admin.driver.switch_to_alert().accept()
                self.ps.test_updates['passed'] = True
                break

        self.admin.sleep(5)

        notif = self.admin.driver.find_elements_by_xpath(
            "//div[@class='col-xs-12']")

        assert (found), 'notification not seen'

        self.ps.test_updates['passed'] = True
class TestTeacherViews(unittest.TestCase):
    """CC1.13 - Teacher Views."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        self.teacher.login()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()

    def tearDown(self):
        """Test destructor."""
        self.ps.update_job(
            job_id=str(self.teacher.driver.session_id),
            **self.ps.test_updates
        )
        try:
            self.teacher.delete()
        except:
            pass

    # Case C7609 - 001 - Teacher | View the Concept Coach dashboard
    @pytest.mark.skipif(str(7609) not in TESTS, reason='Excluded')
    def test_teacher_view_the_concept_coach_dashboard_7609(self):
        """View the Concept Coach dashboard.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name

        Expected Result:
        The user is presented with the Concept Coach dashbaord
        """
        self.ps.test_updates['name'] = 'cc1.13.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.001', '7609']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assert('cc-dashboard' in self.teacher.current_url()), \
            'not at Concept Coach Dashboard'

        self.ps.test_updates['passed'] = True

    # Case C7610 - 002 - Teacher | Switch between concurrently running courses
    @pytest.mark.skipif(str(7610) not in TESTS, reason='Excluded')
    def test_teacher_switch_between_concurrently_running_courses_7610(self):
        """Able to switch between concurrently running courses.

        Steps:
        Click on the OpenStax logo in the left corner of the header

        Expected Result:
        The user is presented with a list of Concept Coach courses
        Is able to switch to another course
        """
        self.ps.test_updates['name'] = 'cc1.13.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.002', '7610']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        url1 = self.teacher.current_url().split('courses')[1]
        self.teacher.driver.find_element(
            By.XPATH, '//a//i[@class="ui-brand-logo"]'
        ).click()
        try:
            self.teacher.driver.find_element(
                By.XPATH,
                '//a[contains(@href,"/cc-dashboard") ' +
                'and not(contains(@href,"'+str(url1)+'"))]'
            ).click()
        except NoSuchElementException:
            print('Only one CC course, cannot go to another')
            raise Exception
        assert('cc-dashboard' in self.teacher.current_url()), \
            'not at Concept Coach Dashboard'
        assert(url1 != self.teacher.current_url()), \
            'went to same course'

        self.ps.test_updates['passed'] = True

    # Case C7611 - 003 - Teacher | View links on dashboard to course materials
    @pytest.mark.skipif(str(7611) not in TESTS, reason='Excluded')
    def test_teacher_view_links_on_dashboard_to_course_materials_7611(self):
        """View links on dashboard to course materials.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name

        Expected Result:
        On header there is a link to 'Homework PDF', and 'Online Book'
        """
        self.ps.test_updates['name'] = 'cc1.13.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.003', '7611']
        self.ps.test_updates['passed'] = False

        # HW pdf
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Homework PDF")]'
        ).click()
        coursename = self.teacher.driver.find_element(
            By.XPATH, '//div[@class="cc-dashboard"]/div'
        ).get_attribute('data-appearance')
        coursename = coursename.replace('_', '-')
        home = os.getenv("HOME")
        files = os.listdir(home + '/Downloads')
        for i in range(len(files)):
            if (coursename in files[i]) and (files[i][-4:] == '.pdf'):
                break
            else:
                if i == len(files)-1:
                    raise Exception
        # online book
        self.teacher.driver.find_element(
            By.XPATH, '//a//span[contains(text(),"Online Book")]'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('cnx' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'
        self.teacher.driver.switch_to_window(
            self.teacher.driver.window_handles[0])
        # assignment links
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Assignment Links")]'
        ).click()
        assert('assignment-links' in self.teacher.current_url()), \
            'not viewing Assignment Links'

        self.ps.test_updates['passed'] = True

    # Case C7612 - 004 - Teacher | Able to copy a system-generated message
    # with a student code, links, and other information
    @pytest.mark.skipif(str(7612) not in TESTS, reason='Excluded')
    def test_able_to_copy_a_system_generated_message_with_a_student_7612(self):
        """Copy a system-generated message with a student code, links, etc.

        Steps:
        Click on the user menu in the right corner of the header
        Click "Course Roster"
        Click "Get Student Enrollment Code"
        Copy the system generated message

        Expected Result:
        The user is able to copy the system generated message
        """
        self.ps.test_updates['name'] = 'cc1.13.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.004', '7612']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Course Settings and Roster")]'
        ).click()
        self.teacher.driver.find_element(
            By.XPATH, '//span[contains(text(),"student enrollment code")]'
        ).click()
        self.teacher.driver.find_element(
            By.XPATH,
            '//*[contains(text(),"Send the following enrollment instruction")]'
        )

        element = self.teacher.driver.find_element(
            By.XPATH,
            '//div[contains(@class,"enrollment-code-modal")]'
        )
        element.find_element(
            By.XPATH,
            './/*[contains(text(),"To register for Concept Coach:")]'
        )

        self.ps.test_updates['passed'] = True

    # Case C7613 - 005 - Teacher | Periods are relabeled as sections for all
    # courses
    @pytest.mark.skipif(str(7613) not in TESTS, reason='Excluded')
    def test_teacher_periods_are_relabeled_as_sections_for_all_cour_7613(self):
        """Period is relabeled as section for college courses.

        Steps:
        Go to user menu
        Click on course roster
        Check that there is an '+ add section' button instead
            of an '+ add period' button

        Expected Result:
        There is an '+ add section' button instead of an '+ add period' button
        """
        self.ps.test_updates['name'] = 'cc1.13.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.005', '7613']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Course Settings and Roster")]'
        ).click()
        self.teacher.driver.find_element(
            By.XPATH,
            '//li[contains(@class,"add-period")]//span[text()="Section"]'
        )

        self.ps.test_updates['passed'] = True

    # Case C7614 - 006 - Teacher | View a score report
    @pytest.mark.skipif(str(7614) not in TESTS, reason='Excluded')
    def test_teacher_view_a_score_report_7614(self):
        """View a score report.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"

        Expected Result:
        The user is presented with a score report
        """
        self.ps.test_updates['name'] = 'cc1.13.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.006', '7614']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )

        self.ps.test_updates['passed'] = True

    # Case C7615 - 007 - Teacher | View a report showing an individual
    # student's work pages
    @pytest.mark.skipif(str(7615) not in TESTS, reason='Excluded')
    def test_teacher_view_a_report_showing_an_individual_students_7615(self):
        """View a report showing an individual student's work pages.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"
        Click on the percentage in the "Score" column

        Expected Result:
        Individual student's work is shown
        """
        self.ps.test_updates['name'] = 'cc1.13.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.007', '7614']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[contains(@class,"scores-cell")]' +
            '/div[@class="score"]'
        ).click()
        assert('steps' in self.teacher.current_url()), \
            "Not taken to individual student's work for assignment"

        self.ps.test_updates['passed'] = True

    # Case C7616 - 008 - Teacher | View a summary report showing a class's work
    # pages
    @pytest.mark.skipif(str(7616) not in TESTS, reason='Excluded')
    def test_teacher_view_a_summary_report_showing_a_class_work_pag_7616(self):
        """View a summary report showing a class's work pages.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"
        Click on the desired period tab

        Expected Result:
        The user is presented with a summary report
        """
        self.ps.test_updates['name'] = 'cc1.13.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.008', '7616']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        periods = self.teacher.driver.find_elements(
            By.XPATH, '//span[contains(@class,"tab-item-period-name")]'
        )
        for period in periods:
            period.click()

        self.ps.test_updates['passed'] = True

    # Case C7617 - 009 - Teacher | View the aggregate student scores
    @pytest.mark.skipif(str(7617) not in TESTS, reason='Excluded')
    def test_teacher_view_the_aggregate_student_scores_7617(self):
        """View the aggregate student scores.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"

        Expected Result:
        The user is presented with Student scores
        """
        self.ps.test_updates['name'] = 'cc1.13.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.009', '7617']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH, '//div[contains(@class,"course-scores-container")]')

        self.ps.test_updates['passed'] = True

    # Case C7618 - 010 - Teacher | View scores for an individual student's
    # scores
    @pytest.mark.skipif(str(7618) not in TESTS, reason='Excluded')
    def test_teacher_view_scores_for_an_individual_student_scores_7618(self):
        """View scores for an individual student's scores.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"
        Scroll to the desired student

        Expected Result:
        The user is presented with scores for an individual student
        """
        self.ps.test_updates['name'] = 'cc1.13.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.010', '7618']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[contains(@class,"name-cell")]'
        )

        self.ps.test_updates['passed'] = True

    # Case C7619 - 011 - Teacher | View an individual student's question set
    # for an assignment
    @pytest.mark.skipif(str(7619) not in TESTS, reason='Excluded')
    def test_teacher_view_an_individual_student_question_set_7619(self):
        """View an individual student's question set for an assignment.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"
        Click on a student's score for the desired assignment

        Expected Result:
        The user is presented with a student's question set for the assignment
        """
        self.ps.test_updates['name'] = 'cc1.13.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.011', '7619']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[contains(@class,"scores-cell")]' +
            '/div[@class="score"]'
        ).click()
        breadcrumbs = self.teacher.driver.find_elements(
            By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]'
        )
        for i in range(len(breadcrumbs)-1):
            self.teacher.driver.find_element(
                By.XPATH,
                '//span[contains(@class,"openstax-breadcrumbs-")' +
                'and contains(@data-reactid,"step-' + str(i) + '")]'
            ).click()

        self.ps.test_updates['passed'] = True

    # Case C7620 - 012 - Teacher | View an assignment summary
    @pytest.mark.skipif(str(7620) not in TESTS, reason='Excluded')
    def test_teacher_view_an_assignment_summary_7620(self):
        """View an assignment summary.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"
        Click on a student's score for the desired assignment
        Click "Summary"

        Expected Result:
        The user is presented with an assignmnent summary
        """
        self.ps.test_updates['name'] = 'cc1.13.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.012', '7620']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[contains(@class,"scores-cell")]' +
            '/div[@class="score"]'
        ).click()
        self.teacher.driver.find_element(
            By.XPATH,
            '//span[contains(@class,"openstax-breadcrumbs-")' +
            'and contains(@data-reactid,"-end-")]'
        ).click()
        self.teacher.sleep(0.5)
        breadcrumbs_answered = self.teacher.driver.find_elements(
            By.XPATH,
            '//span[contains(@class,"openstax-breadcrumbs-")' +
            'and contains(@class,"completed")]'
        )
        question_cards = self.teacher.driver.find_elements(
            By.XPATH, '//div[contains(@class,"openstax-exercise-card")]'
        )
        assert(len(question_cards) == len(breadcrumbs_answered)), \
            'all answered questions not in summary'

        self.ps.test_updates['passed'] = True

    # Case C7622 - 013 - Teacher | Download student scores
    @pytest.mark.skipif(str(7622) not in TESTS, reason='Excluded')
    def test_teacher_download_student_scores_7622(self):
        """Download student scores.

        Steps:
        Click the user menu in the right corner of the header
        Click "Student Scores"
        Click "Export"

        Expected Result:
        Student scores are downloaded in an excel spreadsheet
        """
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH, '//div[contains(@class,"export-button")]//button'
        ).click()
        # wait for it to export. It says generating when still not done
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[contains(@class,"export-button")]//button' +
                 '//span[text()="Export"]')
            )
        )
        # check that it was downloaded
        coursename = self.teacher.driver.find_element(
            By.XPATH, '//div[@class="course-name"]').text
        coursename = coursename.replace(' ', '_') + "_Scores"
        home = os.getenv("HOME")
        files = os.listdir(home + '/Downloads')
        for i in range(len(files)):
            if (coursename in files[i]) and (files[i][-5:] == '.xlsx'):
                break
            else:
                if i == len(files)-1:
                    raise Exception

        self.ps.test_updates['passed'] = True

    # Case C7624 - 014 - Teacher | Exercise IDs are shown for each assessment
    @pytest.mark.skipif(str(7624) not in TESTS, reason='Excluded')
    def test_teacher_exercise_ids_are_shown_for_each_assessment_7624(self):
        """Exercise IDs are shown for each assessment.

        Steps:
        Click the user menu in the right corner of the header
        Click "Question Library"
        Select a chapter
        Click "Show Questions"

        Expected Result:
        Exercise IDs are shown for each assessment in the bottom right hand
        corner of the box holding the question.
        """
        self.ps.test_updates['name'] = 'cc1.13.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.13', 'cc1.13.014', '7624']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(text(),"Student Scores")]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Student Scores"]')
            )
        )
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[contains(@class,"scores-cell")]' +
            '/div[@class="score"]'
        ).click()
        breadcrumbs = self.teacher.driver.find_elements(
            By.XPATH, '//span[contains(@class,"openstax-breadcrumbs-")]'
        )
        for i in range(len(breadcrumbs)-1):
            self.teacher.driver.find_element(
                By.XPATH,
                '//span[contains(@class,"exercise-identifier-link")]' +
                '//span[contains(text(),"ID")]'
            )
            self.teacher.driver.find_element(
                By.XPATH,
                '//span[contains(@class,"openstax-breadcrumbs-")' +
                'and contains(@data-reactid,"step-' + str(i) + '")]'
            ).click()

        self.ps.test_updates['passed'] = True