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()
     self.student = Student(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
         )
         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,
         )
Exemple #4
0
 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
         )
     else:
         self.student = Student(
             use_env_vars=True
         )
     self.student.login()
     self.student.select_course(title='College Physics with Courseware')
     self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
     self.wait.until(
         expect.visibility_of_element_located((
             By.XPATH,
             '//button[contains(@class,"practice")]'
         ))
     ).click()
     self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
     self.student.login()
 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.student.username = os.getenv('STUDENT_USER_CC')
     self.student.login()
     self.student.sleep(5)  # for CNX redirect
Exemple #6
0
class TestStaxingTutorStudent(unittest.TestCase):
    """Staxing case tests."""
    def setUp(self):
        """Pretest settings."""
        self.student = Student(use_env_vars=True, driver_type=DRIVER)
        self.student.set_window_size(height=700, width=1200)

    def tearDown(self):
        """Test destructor."""
        try:
            self.student.delete()
        except Exception:
            pass
 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'
Exemple #8
0
 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.student.login()
     self.student.select_course(appearance='physics')
     self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
     self.wait.until(
         expect.visibility_of_element_located(
             (By.XPATH,
              '//button[contains(@class,"practice")]//span'))).click()
Exemple #9
0
class TestStaxingConceptCoachStudent(unittest.TestCase):
    """Staxing case tests."""

    def setUp(self):
        """Pretest settings."""
        self.student = Student(use_env_vars=True)
        self.student.set_window_size(height=700, width=1200)

    def tearDown(self):
        """Test destructor."""
        try:
            self.student.driver.quit()
        except:
            pass
 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
     )
Exemple #11
0
    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
Exemple #12
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
 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 test_student_view_a_cc_book_and_see_the_widget_7748(self):
        """View a Concept Coach book and see the widget.

        Steps:
        go to tutor-qa
        login as a student
        click on a concept coach book
        Click on the 'Contents +' button
        Click on the a chapter in the contents
        Click on a section other than the introduction
        Scroll down

        Expected Result:
        Concept Coach widget visible
        """
        self.ps.test_updates['name'] = 'cc1.06.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.06',
            'cc1.06.001',
            '7748'
        ]
        self.ps.test_updates['passed'] = False

        # login and go to cc course
        student = Student(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
            username=os.getenv('STUDENT_USER'),
            password=os.getenv('STUDENT_PASSWORD')
        )
        student.login()
        student.driver.find_element(
            By.XPATH, '//a[contains(@href,"cnx.org/contents")]'
        ).click()
        # go to section 1.1 then cc widget
        student.page.wait_for_page_load()
        student.driver.find_element(
            By.XPATH,
            '//button[@class="toggle btn"]//span[contains(text(),"Contents")]'
        ).click()
        student.sleep(0.5)
        student.driver.find_element(
            By.XPATH,
            '//span[@class="chapter-number" and text()="1.1"]'
        ).click()
        student.page.wait_for_page_load()
        student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        student.driver.find_element(
            By.XPATH,
            '//div[@class="concept-coach-launcher"]'
        )
        student.delete()
        self.ps.test_updates['passed'] = True
 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
     )
    def test_student_click_on_openstax_logo_to_return_to_dashboard_8280(self):
        """Click on the OpenStax logo to return to the dashboard.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the View All Topics button
        Click on the OpenStax logo

        Expected Result:
        The user is returned to their dashboard
        """
        self.ps.test_updates['name'] = 't1.45.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.013', '8280']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.logout()
        student2 = Student(
            username=os.getenv('STUDENT_USER_ONE_COURSE'),
            password=os.getenv('STUDENT_PASSWORD'),
            existing_driver=self.student.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        student2.login()
        student2.page.wait_for_page_load()
        student2.open_user_menu()
        student2.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"Performance Forecast") ' +
                 'and @role="menuitem"]')
            )
        ).click()
        self.student.driver.find_element(
            By.XPATH,
            '//i[contains(@class,"ui-brand-logo")]'
        ).click()
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard 011'

        self.ps.test_updates['passed'] = True
Exemple #17
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 test_student_doesnt_see_end_of_page_exercise_sections_7750(self):
        """Doesn't see end-of-page exercise sections.

        Steps:
        Go to Tutor
        Login as a student
        Click on a concept coach book
        Click on the 'Contents +' button
        Click on the a chapter in the contents
        Click on a section other than the introduction
        Scroll down

        Expected Result:
        End-of-page exercise sections are not displayed.
        """
        self.ps.test_updates['name'] = 'cc1.06.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.06',
            'cc1.06.003',
            '7750'
        ]
        self.ps.test_updates['passed'] = False

        # login and go to cc course
        student = Student(
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
            username=os.getenv('STUDENT_USER'),
            password=os.getenv('STUDENT_PASSWORD')
        )
        student.login()
        student.driver.find_element(
            By.XPATH, '//a[contains(@href,"cnx.org/contents")]'
        ).click()
        # go to section 1.1 then cc widget
        student.page.wait_for_page_load()
        student.driver.find_element(
            By.XPATH,
            '//button[@class="toggle btn"]//span[contains(text(),"Contents")]'
        ).click()
        student.sleep(0.5)
        student.driver.find_element(
            By.XPATH,
            '//span[@class="chapter-number" and text()="1.1"]'
        ).click()
        student.page.wait_for_page_load()
        questions = student.driver.find_elements(
            By.XPATH,
            '//section[@data-depth="1" and not(@class)]' +
            '//div[@data-type="exercise"]'
        )
        assert(len(questions) == 0), "questions found at the end of chapter"
        student.delete()
        self.ps.test_updates['passed'] = True
 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'
Exemple #20
0
    def test_student_view_a_cc_book_and_see_the_widget_7748(self):
        """View a Concept Coach book and see the widget.

        Steps:
        go to tutor-qa
        login as a student
        click on a concept coach book
        Click on the 'Contents +' button
        Click on the a chapter in the contents
        Click on a section other than the introduction
        Scroll down

        Expected Result:
        Concept Coach widget visible
        """
        self.ps.test_updates['name'] = 'cc1.06.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.06', 'cc1.06.001', '7748']
        self.ps.test_updates['passed'] = False

        # login and go to cc course
        student = Student(use_env_vars=True,
                          pasta_user=self.ps,
                          capabilities=self.desired_capabilities,
                          username=os.getenv('STUDENT_USER'),
                          password=os.getenv('STUDENT_PASSWORD'))
        student.login()
        student.driver.find_element(
            By.XPATH, '//a[contains(@href,"cnx.org/contents")]').click()
        # go to section 1.1 then cc widget
        student.page.wait_for_page_load()
        student.driver.find_element(
            By.XPATH,
            '//button[@class="toggle btn"]//span[contains(text(),"Contents")]'
        ).click()
        student.sleep(0.5)
        student.driver.find_element(
            By.XPATH,
            '//span[@class="chapter-number" and text()="1.1"]').click()
        student.page.wait_for_page_load()
        student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Jump to Concept Coach'))).click()
        student.driver.find_element(By.XPATH,
                                    '//div[@class="concept-coach-launcher"]')
        student.delete()
        self.ps.test_updates['passed'] = True
Exemple #21
0
    def test_student_doesnt_see_end_of_page_exercise_sections_7750(self):
        """Doesn't see end-of-page exercise sections.

        Steps:
        Go to Tutor
        Login as a student
        Click on a concept coach book
        Click on the 'Contents +' button
        Click on the a chapter in the contents
        Click on a section other than the introduction
        Scroll down

        Expected Result:
        End-of-page exercise sections are not displayed.
        """
        self.ps.test_updates['name'] = 'cc1.06.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.06', 'cc1.06.003', '7750']
        self.ps.test_updates['passed'] = False

        # login and go to cc course
        student = Student(use_env_vars=True,
                          pasta_user=self.ps,
                          capabilities=self.desired_capabilities,
                          username=os.getenv('STUDENT_USER'),
                          password=os.getenv('STUDENT_PASSWORD'))
        student.login()
        student.driver.find_element(
            By.XPATH, '//a[contains(@href,"cnx.org/contents")]').click()
        # go to section 1.1 then cc widget
        student.page.wait_for_page_load()
        student.driver.find_element(
            By.XPATH,
            '//button[@class="toggle btn"]//span[contains(text(),"Contents")]'
        ).click()
        student.sleep(0.5)
        student.driver.find_element(
            By.XPATH,
            '//span[@class="chapter-number" and text()="1.1"]').click()
        student.page.wait_for_page_load()
        questions = student.driver.find_elements(
            By.XPATH, '//section[@data-depth="1" and not(@class)]' +
            '//div[@data-type="exercise"]')
        assert (len(questions) == 0), "questions found at the end of chapter"
        student.delete()
        self.ps.test_updates['passed'] = True
 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.student.login()
     self.student.select_course(appearance='physics')
     self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
     self.wait.until(
         expect.visibility_of_element_located((
             By.XPATH,
             '//button[contains(@class,"practice")]//span'
         ))
     ).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)
     # 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_student_click_on_openstax_logo_to_return_to_dashboard_8280(self):
        """Click on the OpenStax logo to return to the dashboard.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the View All Topics button
        Click on the OpenStax logo

        Expected Result:
        The user is returned to their dashboard
        """
        self.ps.test_updates['name'] = 't1.45.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.013', '8280']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.logout()
        student2 = Student(
            username=os.getenv('STUDENT_USER_ONE_COURSE'),
            password=os.getenv('STUDENT_PASSWORD'),
            existing_driver=self.student.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        student2.login()
        student2.page.wait_for_page_load()
        student2.open_user_menu()
        student2.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"Performance Forecast") ' +
                 'and @role="menuitem"]')
            )
        ).click()
        self.student.driver.find_element(
            By.XPATH,
            '//i[contains(@class,"ui-brand-logo")]'
        ).click()
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard 011'

        self.ps.test_updates['passed'] = True
class TestTutorStudent(unittest.TestCase):
    """Tutor | Teacher"""
    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)
        else:
            self.student = Student(use_env_vars=True)

        # 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.student.delete()
        except:
            pass

    @pytest.mark.skipif(str(162248) not in TESTS, reason='Excluded')
    def test_not_in_course_go_no_courses_page_and_tutor_guide_162248(self):
        """
        Go to tutor qa
        Log in as a student with no courses
        ***Message "We cannot find an OpenStax course associated with your
        account displays with help links***

        Click "Tutor Students. Get help >"
        ***Tutor Help Center opens in another tab with the Getting Started
        guide*** click "Add a Course"

        https://trello.com/c/kc8R2kJO/
        22-student-not-in-any-courses-directed
        -to-a-no-courses-page-and-tutor-guide
        """

        self.ps.test_updates['name'] = 'tutor_help_center_student_162248' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = \
            ['tutor', 'help_center', 'student', '162248']
        self.ps.test_updates['passed'] = False

        # log in as a student with 0 courses
        self.student.login(username=os.getenv('STUDENT_USER_DEMO'),
                           password=os.getenv('STUDENT_DEMO_PASSWORD'))
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CSS_SELECTOR, '.panel-body .lead:first-of-type')))
        self.student.find(By.XPATH,
                          ".//*[contains(text(),'Tutor Students')]").click()
        # go to new tab that opens and check that it is the support page
        window_with_help = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_help)
        self.student.find(By.XPATH, './/*[contains(text(),"Support")]')

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

    # NOT DONE
    @pytest.mark.skipif(str(162252) not in TESTS, reason='Excluded')
    def test_student_questions_why_info_icon_reporting_errata_162252(self):
        """
        Prerequisite: Student needs a homework/reading assignment

        Go to https://tutor-qa.openstax.org/
        Log in as a student
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name
        Click on a homework or reading assignment
        Click on the "Report an error" link in the bottom right corner
        ***A new tab with the assessment errata form appears, with the
        assessment ID already filled in***

        Enter text into the free response text box
        Click "Answer"
        Click on "Why?" next to the message "Now choose from one of the
        following options"
        ***The user is presented with information about why two-step
        problems***

        Then continue working the homework until a spaced practice question
        comes up
        Click on the info icon in the top right of the question box next to
        spaced practice
        ***User is presented with a separate message for spaced practice***

        Expected result:

        ***At the bottom of a homework question there should be a link back to
        the content***

        Corresponding test cases: T2.10 006, 008, T2.11 008

        """

        self.ps.test_updates['name'] = 'tutor_homework_student_162252' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = \
            ['tutor', 'homework', 'student', '162252']
        self.ps.test_updates['passed'] = False

        self.student.login()
        self.student.random_course
        # try clicking on a homework
        try:
            homeworks = self.student.find_all(
                By.XPATH, ".//*[@class='-this-week panel panel-default']" +
                "//*[@class='icon icon-lg icon-homework']")
            homeworks[randint(0, len(homeworks) - 1)].click()
            assignment = 'homework'
        # try clicking on a reading if a homework isn't available
        except:
            readings = self.student.find_all(
                By.XPATH, ".//*[@class='-this-week panel panel-default']" +
                "//*[@class='icon icon-lg icon-reading']")
            readings[randint(0, len(readings) - 1)].click()
            assignment = 'reading'

        if assignment == 'homework':
            try:
                # if a short answer is immediately present
                self.student.find(
                    By.CSS_SELECTOR,
                    ".openstax-question>textarea").send_keys('testing')
                self.student.find(By.CSS_SELECTOR, ".async-button").click()
                self.student.page.wait_for_page_load()
                # check for why icon
                self.student.find(
                    By.XPATH,
                    ".//*[@class='text-info' and contains(text(),'Why?')]")
                self.student.find(By.CSS_SELECTOR, "a[href*='errata']").click()
                self.student.sleep(1)
                # self.student.driver.switch_to().window(handles[1])
                # self.student.sleep(1)
                # self.student.browser.driver.close()
                # self.student.sleep(1)
                # self.student.browser.driver.switch_to().window(handles[0])
                # self.student.sleep(1)
            except:
                # if a multiple choice is immediately present
                self.student.find(
                    By.XPATH,
                    ".//*[@class='text-info' and contains(text(),'Why?')]")
                '''self.student.scroll_to(report)
                report = self.student.find(By.CSS_SELECTOR,
                "a[href*='errata']")
                report.click()
                self.student.sleep(1)
                self.student.driver.switch_to.window(handles[1])
                self.student.sleep(1)
                self.student.browser.driver.close();
                self.student.sleep(1)
                self.student.browser.driver.switch_to.window(handles[0])
                self.student.sleep(1)'''

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

    # NOTE THAT IT WILL ONLY PASS IF THE COURSE HAS LATE ASSIGNMENTS
    @pytest.mark.skipif(str(162253) not in TESTS, reason='Excluded')
    def test_student_late_icons_162253(self):
        """
        Go to tutor qa
        Log in as a student with late assignments(homework, reading, external
        assignment)

        Expected result:

        ***Observe the late icons (this is the red clock) for homework,
        reading, and external assignment***

        Corresponding test cases: T2.10 021,023,025
        https://trello.com/c/644uscZ2/115-late-icons-for-assignments-working-properly
        """
        self.ps.test_updates['name'] = 'tutor_assignments_student_162253' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = \
            ['tutor', 'assignments', 'student', '162253']
        self.ps.test_updates['passed'] = False

        # log in as a student
        self.student.login()
        self.student.random_course()
        # check for late icon
        self.student.find(By.CSS_SELECTOR, ".info.late")

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

    # NOT FINISHED
    @pytest.mark.skipif(str(162254) not in TESTS, reason='Excluded')
    def test_reading_assign_milestones_section_number_header_162254(self):
        """
        Login as student
        Click on a tutor course
        Click "Browse the Book" or select "Browse the Book" from the user menu
        Select a section from the contents
        ***Section numbers listed in the header***

        Go to tutor-qa.openstax.org
        Log in as a student
        Click on a course that has a reading assignment
        Click on a reading assignment
        ***Section numbers listed in the header***

        Click on the right arrow
        ***The progress bar at the top reflects how far along you are as you
        read***

        ***At the start of each new section, the section number is displayed***

        Click on the icon next to the calendar on the header

        Expected result:

        ***The user is presented with prior milestones***

        Corresponding test cases: T2.13 001, 002, 004, 006
        """
        self.ps.test_updates['name'] = 'tutor_reading_student_162254' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = \
            ['tutor', 'reading', 'student', '162254']
        self.ps.test_updates['passed'] = False

        self.student.login()
        self.student.random_course()
        self.student.browse_book()
        self.student.sleep(3)
        original_window = self.student.driver.window_handles[0]
        book = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(book)
        # click on a random section
        sections = self.student.find_all(By.CSS_SELECTOR, ".section")
        num = randint(0, len(sections))
        sections[num].click()
        # find the title
        self.student.find(By.CSS_SELECTOR, ".title")
        self.student.driver.switch_to_window(original_window)
        self.student.find(By.CSS_SELECTOR, ".icon.icon-lg.icon-reading") \
            .click()
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
    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()
class TestDeliveringAssignments(unittest.TestCase):
    """CC1.12 - Delivering Assignments."""
    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)
        else:
            self.student = Student(use_env_vars=True, )

    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)
        try:
            self.student.delete()
        except:
            pass

    '''
    # Case C7738 - 001 - System | PDF is available for download for
    # CC derived copy
    @pytest.mark.skipif(str(7738) not in TESTS, reason='Excluded')
    def test_system_pdf_is_available_for_download_7738(self):
        """PDF is available for download for a Concept Coach derived copy.

        Steps:
        got to https://cnx.org/
        select a textbook
        Scroll to the bottom of the page
        Click on the 'Downloads' button
        Click on the 'PDF' link
        Click on 'Download for Free'

        Expected Result:
        The book is downloaded as a PDF.
        """
        self.ps.test_updates['name'] = 'cc1.12.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.001', '7738']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://cnx.org/')
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"book")]/a/img')

            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"media-header")]')
            )
        )
        self.student.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.student.driver.find_element(
            By.XPATH, '//div[@class="media-footer"]//li[@id="downloads-tab"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="downloads tab-content"]' +
                 '//td//a[contains(text(),".pdf")]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        element = self.student.driver.find_element(
            By.XPATH,
            '//a[contains(text(),"Download for Free")]'
        )
        coursename = element.get_attribute('href')
        coursename = coursename.split('/')[-1]
        element.click()
        self.student.sleep(1)
        # check that it was downloaded
        home = os.getenv("HOME")
        print(home + '/Downloads' + coursename)
        os.path.isfile(home + '/Downloads' + coursename)

        self.ps.test_updates['passed'] = True
    '''
    '''
    # Case C7741 - 002 - System | Webview table of contents matches the PDF
    # numbering
    @pytest.mark.skipif(str(7741) not in TESTS, reason='Excluded')
    def test_system_webview_table_of_contents_matches_the_pdf_numbe_7741(self):
        """Webview table of contents matches the PDF numbering.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Online Book' button
        Return to initial tab/window with tutor
        Click on 'HW PDF' -- a pdf will be downloaded

        Expected Result:
        The table of content numberings match between the web view and PDF.
        """
        self.ps.test_updates['name'] = 'cc1.12.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.002', '7741']
        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 C7742 - 003 - Student | Find the CC book from an online search
    @pytest.mark.skipif(str(7742) not in TESTS, reason='Excluded')
    def test_student_find_the_cc_book_from_an_online_search_7742(self):
        """Find the Concept Coach book from an online search.

        Steps:
        Search the title of the book, with 'openstax' through a search engine

        Expected Result:
        The search returns a link to the book
        """
        self.ps.test_updates['name'] = 'cc1.12.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.003', '7742']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://www.google.com')
        self.student.page.wait_for_page_load()
        actions = ActionChains(self.student.driver)
        actions.send_keys('openstax concept coach biology')
        actions.send_keys(Keys.RETURN)
        actions.perform()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"Biology with Concept Coach")]')))
        self.student.driver.find_element(
            By.XPATH, '//cite[contains(text(),"https://cnx.org/")]')

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

    # Case C7743 - 004 - Student | Find the Concept Coach book from CNX
    @pytest.mark.skipif(str(7743) not in TESTS, reason='Excluded')
    def test_student_find_the_cc_book_from_cnx_7743(self):
        """Find the Concept Coach book from CNX.

        Steps:
        Go to CNX
        Click search
        Click Advance Search
        Search the name of the book in the title text box
        (include 'with Concept Coach' in the search)

        Expected Result:
        The book is displayed in the results
        """
        self.ps.test_updates['name'] = 'cc1.12.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.004', '7743']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://cnx.org/browse')
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH,
            '//a[contains(text(),"Search") and @href="/browse"]').click()
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH, '//a[contains(@class,"advanced-search btn")]').click()
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH,
            '//input[@name="title"]').send_keys('Biology with Concept Coach')
        self.student.driver.find_element(By.XPATH,
                                         '//button[@type="submit"]').click()
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//td//a[contains(text(),"Biology with Concept Coach")]')))

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

    # Case C7746 - 005 - User | View the chapter and section number before the
    # CNX page module title
    @pytest.mark.skipif(str(7746) not in TESTS, reason='Excluded')
    def test_user_view_the_chapter_and_section_number_before_cnx_7746(self):
        """View the chapter and section number before the CNX page module title.

        Steps:
        Go to a Concept Coach book
        If the contents is not already open, Click on contents
        Click on a chapter
        Click on a section

        Expected Result:
        The chapter and section appear before the name of the module.
        """
        self.ps.test_updates['name'] = 'cc1.12.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.005', '7746']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://cnx.org/')
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"book")]/a/img'))).click()
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"media-header")]')))
        self.student.driver.find_element(
            By.XPATH, '//div[@class="media-toolbar"]' +
            '//button[contains(@class,"toggle")]' +
            '//span[contains(text(),"Contents")]').click()
        self.student.sleep(0.5)
        self.student.driver.find_element(
            By.XPATH,
            '//span[@class="chapter-number" and text()="1.1"]').click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[@class="title-chapter" and text()="1.1"]')))

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

    '''
class TestImproveLoginRegistrationEnrollment(unittest.TestCase):
    """CC2.09 - Improve Login, Registration, Enrollment."""

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

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

    def get_enrollemnt_code(self, number=0):
        """
        Steps:
        Sign in as teacher
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"

        Return value: code, enrollemnt_url
            code - enrollment code
            enrollemnt_url - url of book for course
        """
        self.teacher.login()
        if number != 0:
            cc_courses = self.teacher.find_all(
                By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
            )
            cc_courses[number].click()
        else:
            self.teacher.find(
                By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
            ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Course Settings and Roster'
        ).click()
        self.teacher.find(
            By.XPATH, '//span[contains(text(),"Your student enrollment code")]'
        ).click()
        self.teacher.sleep(1)
        code = self.teacher.find(
            By.XPATH, '//p[@class="code"]'
        ).text
        enrollement_url = self.teacher.find(
            By.XPATH, '//textarea'
        ).text
        enrollement_url = enrollement_url.split('\n')[5]
        self.teacher.find(
            By.XPATH, '//button[@class="close"]'
        ).click()
        self.teacher.sleep(0.5)
        self.teacher.logout()
        return code, enrollement_url

    def create_user(self, start_num, end_num):
        """
        creates a new user and return the username
        """
        self.student.get("http://accounts-qa.openstax.org")
        num = str(randint(start_num, end_num))
        self.student.find(By.LINK_TEXT, 'Sign up').click()
        self.student.find(
            By.ID, 'identity-login-button').click()
        self.student.find(
            By.ID, 'signup_first_name').send_keys('first_name_001')
        self.student.find(
            By.ID, 'signup_last_name').send_keys('last_name_001')
        self.student.find(
            By.ID, 'signup_email_address').send_keys('*****@*****.**')
        self.student.find(
            By.ID, 'signup_username').send_keys('automated_09_'+num)
        self.student.find(
            By.ID, 'signup_password'
        ).send_keys(os.getenv('STUDENT_PASSWORD'))
        self.student.find(
            By.ID, 'signup_password_confirmation'
        ).send_keys(os.getenv('STUDENT_PASSWORD'))
        self.student.find(By.ID, 'signup_i_agree').click()
        self.student.find(
            By.ID, 'create_account_submit').click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Sign out')
            )
        ).click()
        print('automated_09_'+num)
        return 'automated_09_'+num

    # 14820 - 001 - Teacher | Register for teaching a CC course as new faculty
    @pytest.mark.skipif(str(14820) not in TESTS, reason='Excluded')
    def test_teacher_register_for_teaching_cc_course_as_new_facult_14820(self):
        """Register for teaching a CC course as new faculty.

        Steps:

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

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

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

    # 14819 - 002 - Teacher | Register for teaching a CC course as
    # returning faculty for the same book
    @pytest.mark.skipif(str(14819) not in TESTS, reason='Excluded')
    def test_teacher_register_for_teaching_cc_course_as_returning_14819(self):
        """Register for teaching a CC course as returning faculty.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click "Course Settings and Roster" from the user menu
        Click "Add Section"
        Create a name when prompted
        Click "Add"
        Click on the sections from previous semesters
        Click "Archive Section"

        Expected Result:
        A new section is added and the old sections are archived
        """
        self.ps.test_updates['name'] = 'cc2.09.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.002', '14819']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.LINK_TEXT, 'Course Settings and Roster'
        ).click()
        # add a new section
        new_section_name = "new_section_" + str(randint(100, 999))
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"add-period")]//button')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//input[@type="text"]')
            )
        ).send_keys(new_section_name)
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[@class="modal-content"]//button/span[text()="Add"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//li//a[@role="tab" and text()="' + new_section_name + '"]')
            )
        )
        # revove old section
        old_section_name = self.teacher.find(By.XPATH, '//a[@role="tab"]').text
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//li//a[@role="tab" and text()="' + old_section_name + '"]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(@class,"archive-period")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@role="tooltip"]//button' +
                 '//span[contains(text(),"Archive")]')
            )
        ).click()
        self.teacher.sleep(2)
        archived = self.teacher.driver.find_elements(
            By.XPATH,
            '//li//a[@role="tab" and text()="' + old_section_name + '"]')
        assert(len(archived) == 0), ' not archived'

        # arhive new section and re-add old section as clean-up
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//li//a[@role="tab" and text()="' + new_section_name + '"]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(@class,"archive-period")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@role="tooltip"]//button' +
                 '//span[contains(text(),"Archive")]')
            )
        ).click()

        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[contains(@class,"view-archived-periods")]//button')
            )
        ).click()
        periods = self.teacher.driver.find_elements(
            By.XPATH, '//div[@class="modal-content"]//tbody//tr'
        )
        for period in periods:
            try:
                period.find_element(
                    By.XPATH, ".//td[text()='" + old_section_name + "']")
                period.find_element(
                    By.XPATH,
                    ".//td//span[contains(@class,'restore-period')]//button"
                ).click()
                break
            except NoSuchElementException:
                if period == periods[-1]:
                    raise Exception

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

    # 14759 - 003 - Student | Sign up and enroll in a CC course
    @pytest.mark.skipif(str(14759) not in TESTS, reason='Excluded')
    def test_teacher_sign_up_and_enroll_in_a_cc_course_14759(self):
        """Sign up and enroll in a CC course.

        Steps:
        Sign in as teacher
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"
        Copy and paste the URL into an incognito window
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"
        Click Sign Up
        Click Sign up with a password
        Fill in the required fields
        Click "Create Account"
        Enter the numerical enrollment code you get from the teacher
        Click "Enroll"
        Enter school issued ID, OR skip this step for now

        Expected Result:
        The user is presented with a message that confirms enrollment
        Is redirected to the CC assignment
        """
        self.ps.test_updates['name'] = 'cc2.09.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.003', '14759']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        code, enrollement_url = self.get_enrollemnt_code()
        rand_username = self.create_user(100, 999)
        self.student.get(enrollement_url)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH, '//div[text()="Sign in"]'
        ).click()
        self.student.sleep(0.5)
        login_window = self.student.driver.window_handles[1]
        cc_window = self.student.driver.window_handles[0]
        self.student.driver.switch_to_window(login_window)
        print(rand_username)
        self.student.find(
            By.ID, 'auth_key').send_keys(rand_username)
        print(self.student.password)
        self.student.find(
            By.ID, 'password').send_keys(self.student.password)
        self.student.find(
            By.XPATH, '//button[text()="Sign in"]').click()
        try:
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
        except NoSuchElementException:
            pass
        self.student.driver.switch_to_window(cc_window)
        self.student.sleep(1)
        self.student.find(
            By.XPATH, '//input[@placeholder="enrollment code"]'
        ).send_keys(code)
        self.student.find(
            By.XPATH, '//button/span[text()="Enroll"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[@class="skip"]')
            )
        ).click()
        # check for confirmation message
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//*[contains(text(),"You have successfully joined")]')
            )
        )

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

    # 14862 - 004 - Student | Sign in and enroll in a CC course
    @pytest.mark.skipif(str(14862) not in TESTS, reason='Excluded')
    def test_teacher_sign_in_and_enroll_in_a_cc_course_14862(self):
        """Sign in and enroll in a CC course.

        Steps:
        Sign in as teacher100
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"
        Copy and paste the URL into an incognito window
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"
        Click Sign In
        Sign in as student71
        Enter the numerical enrollment code you get from the teacher
        Click "Enroll"
        Enter school issued ID, OR skip this step for now

        Expected Result:
        The user is presented with a message that confirms enrollment
        Is redirected to the CC assignment
        """
        self.ps.test_updates['name'] = 'cc2.09.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.004', '14862']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        code, enrollement_url = self.get_enrollemnt_code()
        # use a new student so that when run a second time no issues
        # with student already being enrolled in course
        rand_username = self.create_user(100, 999)
        self.student.get(enrollement_url)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH, '//div[text()="Sign in"]'
        ).click()
        self.student.sleep(0.5)
        login_window = self.student.driver.window_handles[1]
        cc_window = self.student.driver.window_handles[0]
        self.student.driver.switch_to_window(login_window)
        self.student.find(
            By.ID, 'auth_key').send_keys(rand_username)
        self.student.find(
            By.ID, 'password').send_keys(self.student.password)
        self.student.find(
            By.XPATH, '//button[text()="Sign in"]').click()
        try:
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
        except NoSuchElementException:
            pass
        self.student.driver.switch_to_window(cc_window)
        self.student.sleep(1)
        self.student.find(
            By.XPATH, '//input[@placeholder="enrollment code"]'
        ).send_keys(code)
        self.student.find(
            By.XPATH, '//button/span[text()="Enroll"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[@class="skip"]')
            )
        ).click()
        # check for confirmation message
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//*[contains(text(),"You have successfully joined")]')
            )
        )

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

    # 14771 - 005 - User | View a message that says you need an enrollment code
    # before signing up
    @pytest.mark.skipif(str(14771) not in TESTS, reason='Excluded')
    def test_user_view_a_message_that_says_you_need_an_enrollment_14771(self):
        """View a message that says you need an enrollment code before signing up.

        Steps:
        Sign in as teacher100
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"
        Copy and paste the URL into an incognito window
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"

        Expected Result:
        The user is presented with a message that says "Sign up with your
        enrollment code. If you don't have an enrollment code, contact your
        instructor."
        """
        self.ps.test_updates['name'] = 'cc2.09.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.005', '14771']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        code, enrollement_url = self.get_enrollemnt_code()
        self.student.get(enrollement_url)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//p[@class="code-required"]')
            )
        )

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

    # 14821 - 006 - Student | Jump to CC from the top of the reading
    @pytest.mark.skipif(str(14821) not in TESTS, reason='Excluded')
    def test_student_jump_to_cc_from_the_top_of_the_reading_14821(self):
        """Jump to CC from the top of the reading.

        Steps:
        If the user has more than one course, click on a CC course name
        Click on a non-introductory section
        Click "Jump to Concept Coach"

        Expected Result:
        The screen jumps to the "Launch Concept Coach" button
        """
        self.ps.test_updates['name'] = 'cc2.09.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.006', '14821']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.find(
            By.XPATH, '//a[contains(@href,"cnx")]'      # possibly change
        ).click()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button//span[text()="Contents"]')
            )
        ).click()
        self.student.sleep(0.5)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]')
            )
        ).click()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        )

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

    # 14822 - 007 - Teacher | Jump to CC from the top of the reading
    @pytest.mark.skipif(str(14822) not in TESTS, reason='Excluded')
    def test_teacher_jump_to_cc_from_the_top_of_the_reading_14822(self):
        """Jump to CC from the top of the reading.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Online Book"
        Click on a non-introductory section
        Click "Jump to Concept Coach"

        Expected Result:
        The screen jumps to the "Launch Concept Coach" button
        """
        self.ps.test_updates['name'] = 'cc2.09.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.007', '14822']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        # open book
        self.teacher.driver.find_element(
            By.XPATH, '//a//span[contains(text(),"Online Book")]'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('cnx' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'
        # get to non-introductory section of book
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button//span[text()="Contents"]')
            )
        ).click()
        self.student.sleep(0.5)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]')
            )
        ).click()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        )
        self.ps.test_updates['passed'] = True
Exemple #30
0
class TestIImproveQuestionManagement(unittest.TestCase):
    """CC2.11 - Improve Question Management."""
    def setUp(self):
        """Pretest settings."""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # 100129 - 007 - Admin | View list of excluded assesments
    @pytest.mark.skipif(str(100129) not in TESTS, reason='Excluded')
    def test_admin_view_list_of_excluded_assesments_100129(self):
        """View list of excluded assesments.

        Steps:

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

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

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

    # 100130 - 008 - Admin | Export the list of excluded assesments to CSV
    @pytest.mark.skipif(str(100130) not in TESTS, reason='Excluded')
    def test_admin_export_the_list_of_excluded_assesments_to_csv_100130(self):
        """Export the list of excluded assesments to CSV.

        Steps:

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

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

        self.ps.test_updates['passed'] = True
class 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 TestViewTheListDashboard(unittest.TestCase):
    """T1.45 - View the list dashboard."""

    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.student.login()

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

    # Case C8268 - 001 - Student | View the assignment list
    @pytest.mark.skipif(str(8268) not in TESTS, reason='Excluded')
    def test_student_view_the_assignemnt_list_8268(self):
        """View the assignment list.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        The User is presented with their assignment list
        """
        self.ps.test_updates['name'] = 't1.45.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.001', '8268']
        self.ps.test_updates['passed'] = False

        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard'

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

    # Case C8269 - 002 - Student | View the performance forecast using the
    # dashboard button
    @pytest.mark.skipif(str(8269) not in TESTS, reason='Excluded')
    def test_student_performance_forecast_using_dashboard_button_8269(self):
        """View the performance forecast using the dashboard button.

        Steps:
        If the user has more than one course, select a Tutor course
        Click the View All Topics button

        Expected Result:
        The User is presented with their performance forecast
        """
        self.ps.test_updates['name'] = 't1.45.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.002', '8269']
        self.ps.test_updates['passed'] = False

        self.student.select_course(appearance='physics')
        performance = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button[contains(@class,"view-performance-forecast")]')
            )
        )
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', performance)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        performance.click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C8270 - 003 - Student | View the performance forecast using the menu
    @pytest.mark.skipif(str(8270) not in TESTS, reason='Excluded')
    def test_student_view_performance_forecast_using_the_menu_link_8270(self):
        """View the performance forecast using the menu link.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the user menu
        Click on the Performance Forecast option

        Expected Result:
        The User is presented with their performance forecast
        """
        self.ps.test_updates['name'] = 't1.45.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.003', '8270']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'viewPerformanceForecast')
            )
        ).click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C8271 - 004 - Student | View the assignments for the current week
    @pytest.mark.skipif(str(8271) not in TESTS, reason='Excluded')
    def test_student_view_the_assignemnts_for_the_current_week_8271(self):
        """View the assignments for the current week.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        The Assignemnts for the current week are displayed
        """
        self.ps.test_updates['name'] = 't1.45.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.004', '8271']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'This Week')
            )
        )

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

    # Case C8272 - 005 - Student | View the upcoming assignments
    @pytest.mark.skipif(str(8272) not in TESTS, reason='Excluded')
    def test_student_view_the_upcoming_assignemnts_8272(self):
        """View the upcoming assignments.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        The Upcoming Assignemnts are displayed
        """
        self.ps.test_updates['name'] = 't1.45.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.005', '8272']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        try:
            self.student.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"-upcoming")]')
                )
            )
        except TimeoutException:
            self.student.driver.find_element(
                By.XPATH, '//div[contains(text(),"No upcoming events")]')

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

    # Case C8273 - 006 - Student | View past work
    @pytest.mark.skipif(str(8273) not in TESTS, reason='Excluded')
    def test_student_view_past_work_8273(self):
        """View past work.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the All Past Work tab

        Expected Result:
        The Past work is displayed
        """
        self.ps.test_updates['name'] = 't1.45.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.006', '8273']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        past_work = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'All Past Work')
            )
        )
        past_work.click()
        assert(past_work.get_attribute('aria-selected') == 'true'),\
            'not viewing past work'

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

    # Case C8274 - 007 - Student | Check which assignments were late
    @pytest.mark.skipif(str(8274) not in TESTS, reason='Excluded')
    def test_student_check_which_assignments_were_late_8274(self):
        """Check which assignments were late.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the All Past Work tab

        Expected Result:
        Late Assignemnts have a red clock icon next to their progress status
        """
        self.ps.test_updates['name'] = 't1.45.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.007', '8274']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'All Past Work')
            )
        ).click()
        late = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//i[contains(@class,"info late")]')
            )
        )
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', late)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        late.click()

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

    # Case C8275 - 008 - Student | View recent performance forecast topics
    @pytest.mark.skipif(str(8275) not in TESTS, reason='Excluded')
    def test_student_view_recent_performance_topics_8275(self):
        """View recent performance forecast topics.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        Recent topics are displayed on the dashboard under performance forecast
        """
        self.ps.test_updates['name'] = 't1.45.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.008', '8275']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//h2[contains(@class, "recent")]')
            )
        )
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class, "guide-group")]')
            )
        )

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

    # Case C8276 - 009 - Student | Open the refrence book using the dashboard
    # button
    @pytest.mark.skipif(str(8276) not in TESTS, reason='Excluded')
    def test_student_open_the_refrence_book_using_dashboard_button_8276(self):
        """Open the refrence book using the dashboard button.

        Steps:
        If the user has more than one course, select a Tutor course
        Click the Browse The Book button

        Expected Result:
        The refrence book is opened in a new tab or window
        """
        self.ps.test_updates['name'] = 't1.45.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.009', '8276']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        book = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(@class,"view-reference-guide")]' +
                 '//div[contains(text(),"Browse the Book")]')
            )
        )
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', book)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        book.click()
        window_with_book = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_book)
        assert('book' in self.student.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C8277 - 010 - Student | Open the refrence book using the menu link
    @pytest.mark.skipif(str(8277) not in TESTS, reason='Excluded')
    def test_student_open_the_refrence_book_using_the_menu_link_8277(self):
        """Open the refrence book using the menu link.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the user menu
        Click the Browse The Book option

        Expected Result:
        The refrence book is opened in a new tab or window
        """
        self.ps.test_updates['name'] = 't1.45.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.010', '8277']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'view-reference-guide')
            )
        ).click()
        window_with_book = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_book)
        assert('book' in self.student.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C8278 - 011 - Student | Click on the course name to return to the
    # dasboard
    @pytest.mark.skipif(str(8278) not in TESTS, reason='Excluded')
    def test_student_click_on_course_name_to_return_to_dashboard_8278(self):
        """Click on the course name to return to the dashboard.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the View All Topics button
        Click on the course name

        Expected Result:
        The user is returned to their dashboard
        """
        self.ps.test_updates['name'] = 't1.45.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.011', '8278']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button[contains(@class,"view-performance-forecast")]')
            )
        ).click()
        self.student.driver.find_element(
            By.XPATH, '//a[contains(@aria-describedby,"course-name-tooltip")]'
        ).click()
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard 011'

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

    # Case C8279 - 012 - Student | Click on the OpneStax logo to return to the
    # course picker
    @pytest.mark.skipif(str(8279) not in TESTS, reason='Excluded')
    def test_student_click_on_openstax_logo_return_to_course_picker_8279(self):
        """Click on the OpenStax logo to return to the course picker.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the OpenStax logo

        Expected Result:
        The user is returned to the course picker
        """
        self.ps.test_updates['name'] = 't1.45.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.012', '8279']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.driver.find_element(
            By.XPATH, '//i[contains(@class,"ui-brand-logo")]').click()
        assert('dashboard' in self.student.current_url()), \
            'Not viewing the course picker 012'

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

    # Case C8280 - 013 - Student | Click on the course OpenStax logo to return
    # to the dasboard
    @pytest.mark.skipif(str(8280) not in TESTS, reason='Excluded')
    def test_student_click_on_openstax_logo_to_return_to_dashboard_8280(self):
        """Click on the OpenStax logo to return to the dashboard.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the View All Topics button
        Click on the OpenStax logo

        Expected Result:
        The user is returned to their dashboard
        """
        self.ps.test_updates['name'] = 't1.45.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.013', '8280']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.logout()
        student2 = Student(
            username=os.getenv('STUDENT_USER_ONE_COURSE'),
            password=os.getenv('STUDENT_PASSWORD'),
            existing_driver=self.student.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities
        )
        student2.login()
        student2.page.wait_for_page_load()
        student2.open_user_menu()
        student2.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"Performance Forecast") ' +
                 'and @role="menuitem"]')
            )
        ).click()
        self.student.driver.find_element(
            By.XPATH,
            '//i[contains(@class,"ui-brand-logo")]'
        ).click()
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard 011'

        self.ps.test_updates['passed'] = True
class TestViewTheListDashboard(unittest.TestCase):
    """T1.45 - View the list dashboard."""
    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)
        else:
            self.student = Student(use_env_vars=True)
        self.student.login()

    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)
        try:
            self.student.delete()
        except:
            pass

    # Case C162191 - 001 - Student | View the Performance Forecast and its
    # functions
    @pytest.mark.skipif(str(162191) not in TESTS, reason='Excluded')
    def test_student_view_personal_performance_forecast_162191(self):
        """
        #STEPS
        Go to OpenStax Tutor QA
        Click on the 'Login' button
        Enter the student user account [  |  ] in the username and password
        text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name

        Click on the user menu in the upper right corner
        Click on "Performance Forecast"
        ***The user is presented with personal Performance Forecast***
        ***The performance color key is presented to the user (next to the
        'Return to Dashboard' button)***
        ***The user is presented with up to four problematic sections under My
        Weaker Areas***

        Hover the cursor over the info icon that is next to the "Performance
        Forecast" header
        ***Info icon shows an explanation of the data.***

        Scroll to Individual Chapters section
        ***The user is presented with chapters listed on the left and their
        sections on the right.***
        ***The user is presented with the "Practice More To Get Forecast"
        button under a section without
        enough data instead of a color bar.***


        Click on a chapter bar
        # EXPECTED RESULT
        ***The user is presented with up to five practice assessments for that
        chapter***

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

        # Test steps and verification assertions
        self.student.select_course(appearance='college_physics')
        self.student.page.wait_for_page_load()

        # View Personal Performance Forecast
        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'viewPerformanceGuide'))).click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

        # View Performance Color Key
        self.student.wait.until(
            expect.visibility_of_element_located((By.CLASS_NAME, 'guide-key')))

        self.student.sleep(5)

        # User is presented with 4 problematic sections
        weak = self.student.driver.find_elements_by_xpath(
            "//div[@class='chapter-panel weaker']/div[@class='sections']" +
            "/div[@class='section']")

        self.student.sleep(5)

        assert(len(weak) <= 4), \
            'More than four weaker sections'

        # Info icon shows an explanation of data
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'info-link'))).click()

        self.student.sleep(5)

        # User is presented with chapters listed on the left and their sections
        # on the right
        # Get all the chapter panels
        panels = self.student.driver.find_elements_by_class_name(
            'chapter-panel')

        # Should be one chapter button for each panel, at least one section
        # button per panel
        for panel in panels:
            chapter = panel.find_elements_by_class_name('chapter')
            sections = panel.find_elements_by_class_name('sections')
            assert(len(sections) > 0), \
                'no sections found'
            assert(chapter[0].location.get('x') <=
                   sections[0].location.get('x')), \
                'section to the left of chapter'
        self.student.sleep(5)

        # User is presented with the "Practice More To Get Forecast" button
        # under a section without
        # enough data instead of a color bar

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.find(By.CLASS_NAME, 'no-data')

        # User is presented with up to five practice assesments for that
        # chapter

        self.student.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, "//div[@class='chapter']/button"))).click()

        assert('practice' in self.student.current_url()), \
            'Not presented with practice problems'

        self.student.sleep(5)
        breadcrumbs = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumb-exercise")]')
        assert(len(breadcrumbs) <= 5), \
            "more than 5 questions"

        self.ps.test_updates['passed'] = True
class TestCNXNavigation(unittest.TestCase):
    """CC1.05 - CNX Navigation."""

    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)

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

    # Case C7625 - 001 - Student | Log into Concept Coach for a course on CNX
    @pytest.mark.skipif(str(7625) not in TESTS, reason="Excluded")
    def test_student_log_into_cc_for_a_course_on_cnx_7625(self):
        """Log into Concept Coach for a course on CNX.

        Steps:
        Go to tutor-qa
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name

        Expected Result:
        The student logs into Concept Coach
        """
        self.ps.test_updates["name"] = "cc1.05.001" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["cc1", "cc1.05", "cc1.05.001", "7625"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.driver.get(self.student.url)
        self.student.page.wait_for_page_load()
        # check to see if the screen width is normal or condensed
        if self.student.driver.get_window_size()["width"] <= self.student.CONDENSED_WIDTH:
            # get small-window menu toggle
            is_collapsed = self.student.driver.find_element(By.XPATH, '//button[contains(@class,"navbar-toggle")]')
            # check if the menu is collapsed and, if yes, open it
            if "collapsed" in is_collapsed.get_attribute("class"):
                is_collapsed.click()
        self.student.wait.until(expect.visibility_of_element_located((By.LINK_TEXT, "Login"))).click()
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(By.ID, "auth_key").send_keys(self.student.username)
        self.student.driver.find_element(By.ID, "password").send_keys(self.student.password)
        # click on the sign in button
        self.student.driver.find_element(By.XPATH, '//button[text()="Sign in"]').click()
        self.student.page.wait_for_page_load()
        assert "dashboard" in self.student.current_url(), "Not taken to dashboard: %s" % self.student.current_url()
        self.student.driver.find_element(By.XPATH, '//a[contains(@href,"cnx.org/contents/")]').click()
        assert "cnx.org/contents/" in self.student.current_url(), (
            "Not taken to dashboard: %s" % self.student.current_url()
        )

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

    # Case C7626 - 002 - Student | Following CC login author links are not seen
    @pytest.mark.skipif(str(7626) not in TESTS, reason="Excluded")
    def test_student_following_cc_login_author_links_are_not_seen_7626(self):
        """Following Concept Coach login author links are not seen.

        Steps:
        Go to tutor-qa
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name

        Expected Result:
        Author links should not be seen
        """
        self.ps.test_updates["name"] = "cc1.05.002" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["cc1", "cc1.05", "cc1.05.002", "7626"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.driver.find_element(By.XPATH, '//a[contains(@href,"cnx.org/contents/")]').click()
        self.student.page.wait_for_page_load()
        # check that it says by OpenStax instead of by another author
        self.student.driver.find_element(
            By.XPATH,
            '//span[@ class="collection-authors"]' + '//span[@class="list-comma" and text()="OpenStax College"]',
        )
        self.ps.test_updates["passed"] = True

    # Case C7627 - 003 - Student | Able to use the table of contents to
    # navigate the book without impacting the reading assignment
    @pytest.mark.skipif(str(7627) not in TESTS, reason="Excluded")
    def test_student_able_to_use_the_table_of_contents_to_navigate_7627(self):
        """Navigate the book without impacting the reading assignment.

        Steps:
        Click on the "Contents" button

        Expected Result:
        The user is able to navigate the book without impacting the reading
        assignment
        """
        self.ps.test_updates["name"] = "cc1.05.003" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["cc1", "cc1.05", "cc1.05.003", "7627"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.driver.find_element(By.XPATH, '//a[contains(@href,"cnx.org/contents/")]').click()
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH, '//button[@class="toggle btn"]//span[contains(text(),"Contents")]'
        ).click()
        self.student.sleep(0.5)
        element = self.student.driver.find_element(
            By.XPATH, '//span[@class="name-wrapper"]' + '//span[@class="chapter-number"]'
        )
        chapter = element.text
        element.click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[@class="title-chapter" and text()="' + chapter + '"]')
            )
        )

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

    # Case C7628 - 004 - Student | Able to search within the book
    @pytest.mark.skipif(str(7628) not in TESTS, reason="Excluded")
    def test_student_able_to_search_within_the_book_7628(self):
        """Able to search within the book.

        Steps:
        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.004" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["cc1", "cc1.05", "cc1.05.004", "7628"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.driver.find_element(By.XPATH, '//a[contains(@href,"cnx.org/contents/")]').click()
        self.student.page.wait_for_page_load()
        self.student.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...
        self.student.wait.until(expect.visibility_of_element_located((By.XPATH, '//div[@class="result-count"]')))

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

    # Case C7629 - 005 - Teacher | Able to search within the book
    @pytest.mark.skipif(str(7629) not in TESTS, reason="Excluded")
    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

    # Case C7630 - 006 - Admin | CNX URLs are shorter
    @pytest.mark.skipif(str(7630) not in TESTS, reason="Excluded")
    def test_admin_cnx_urls_are_shorter_7630(self):
        """CNX URLs are shorter.

        Steps:
        Go to https://demo.cnx.org/scripts/settings.js
        Scroll down to the bottom of the page under "conceptCoach"

        Expected Result:
        CNX URLs are shorter than the first URL
        """
        self.ps.test_updates["name"] = "cc1.05.006" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["cc1", "cc1.05", "cc1.05.006", "7630"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.get("https://demo.cnx.org/scripts/settings.js")
        # get the text in the concept coach section
        page_text = (
            self.student.wait.until(expect.visibility_of_element_located((By.TAG_NAME, "pre")))
            .text.split("uuids")[1]
            .splitlines()
        )
        # loop through the lines that are the cnx urls only
        for i in range(1, len(page_text) - 9, 2):
            line_1 = page_text[i]
            line_2 = page_text[i + 1]
            print(line_1)
            print(line_2)
            assert line_1.find("'", 14) > line_2.find("'", 14), "CNX URLs aren't shorter"
        self.ps.test_updates["passed"] = True
class TestUserLogin(unittest.TestCase):
    """T1.36 - User login."""

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

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

    # Case C8238 - 001 - Admin | Log into Tutor
    @pytest.mark.skipif(str(8238) not in TESTS, reason='Excluded')
    def test_admin_log_into_tutor_8238(self):
        """Log into Tutor.

        Steps:
        Click on the 'Login' button
        Enter the admin account in the username and password text boxes
        Click on the 'Sign in' button

        Expected Result:
        User is logged in
        """
        self.ps.test_updates['name'] = 't1.36.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.001', '8238']
        self.ps.test_updates['passed'] = False

        self.admin.get(self.admin.url)
        self.admin.page.wait_for_page_load()
        # check to see if the screen width is normal or condensed
        if self.admin.driver.get_window_size()['width'] <= \
                self.admin.CONDENSED_WIDTH:
            # get small-window menu toggle
            is_collapsed = self.admin.find(
                By.XPATH,
                '//button[contains(@class,"navbar-toggle")]'
            )
            # check if the menu is collapsed and, if yes, open it
            if('collapsed' in is_collapsed.get_attribute('class')):
                is_collapsed.click()
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Login')
            )
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.ID, 'auth_key'
        ).send_keys(self.admin.username)
        self.admin.find(
            By.ID, 'password'
        ).send_keys(self.admin.password)
        # click on the sign in button
        self.admin.find(
            By.XPATH,
            '//button[text()="Sign in"]'
        ).click()
        self.admin.page.wait_for_page_load()
        assert('dashboard' in self.admin.current_url()), \
            'Not taken to dashboard: %s' % self.admin.current_url()

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

    # Case C8239 - 002 - Admin | Access the Admin Console
    @pytest.mark.skipif(str(8239) not in TESTS, reason='Excluded')
    def test_admin_access_the_admin_console_8239(self):
        """Access the Admin console.

        Steps:
        Click on the 'Login' button
        Enter the admin account in the username and password text boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the Admin option

        Expected Result:
        User is presented with the admin console
        """
        self.ps.test_updates['name'] = 't1.36.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.002', '8239']
        self.ps.test_updates['passed'] = False

        # self.user = admin
        self.admin.login()
        self.admin.open_user_menu()
        self.admin.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Admin')
            )
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.XPATH, '//h1[contains(text(),"Admin Console")]')

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

    # Case C8240 - 003 - Admin | Log out
    @pytest.mark.skipif(str(8240) not in TESTS, reason='Excluded')
    def test_admin_log_out_8240(self):
        """Log out.

        Steps:
        Click on the 'Login' button
        Enter the admin account in the username and password text boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the Log out option

        Expected Result:
        The User is signed out
        """
        self.ps.test_updates['name'] = 't1.36.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.003', '8240']
        self.ps.test_updates['passed'] = False

        self.admin.login()
        self.admin.open_user_menu()
        self.admin.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@value,"Log Out")]')
            )
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.XPATH, '//div[contains(@class,"tutor-home")]')

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

    # Case C8241 - 004 - Content Analyst | Log into Tutor
    @pytest.mark.skipif(str(8241) not in TESTS, reason='Excluded')
    def test_content_analyst_log_into_tutor_8241(self):
        """Log into Tutor.

        Steps:
        Click on the 'Login' button
        Enter the content analyst account in the username and password boxes
        Click on the 'Sign in' button

        Expected Result:
        The user is signed in
        """
        self.ps.test_updates['name'] = 't1.36.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.004', '8241']
        self.ps.test_updates['passed'] = False

        self.content.get(self.content.url)
        self.content.page.wait_for_page_load()
        # check to see if the screen width is normal or condensed
        if self.content.driver.get_window_size()['width'] <= \
           self.content.CONDENSED_WIDTH:
            # get small-window menu toggle
            is_collapsed = self.content.find(
                By.XPATH,
                '//button[contains(@class,"navbar-toggle")]'
            )
            # check if the menu is collapsed and, if yes, open it
            if('collapsed' in is_collapsed.get_attribute('class')):
                is_collapsed.click()
        self.content.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Login')
            )
        ).click()
        self.content.page.wait_for_page_load()
        self.content.find(
            By.ID,
            'auth_key'
        ).send_keys(self.content.username)
        self.content.find(
            By.ID,
            'password'
        ).send_keys(self.content.password)
        # click on the sign in button
        self.content.find(
            By.XPATH,
            '//button[text()="Sign in"]'
        ).click()
        self.content.page.wait_for_page_load()
        assert('dashboard' in self.content.current_url()), \
            'Not taken to dashboard: %s' % self.content.current_url()

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

    # Case C8242 - 005 - Content Analyst | Access the QA Viewer
    @pytest.mark.skipif(str(8242) not in TESTS, reason='Excluded')
    def test_content_analyst_access_the_qa_viewer_8242(self):
        """Access the QA Viewer.

        Steps:
        Click on the 'Login' button
        Enter the content analyst account in the username and password boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the QA Content option

        Expected Result:
        The user is presented with the QA viewer
        """
        self.ps.test_updates['name'] = 't1.36.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.005', '8242']
        self.ps.test_updates['passed'] = False

        self.content.login()
        self.content.open_user_menu()
        self.content.wait.until(
            expect.element_to_be_clickable((
                By.XPATH,
                '//a[contains(text(),"QA Content") and @role="menuitem"]'
            ))
        ).click()
        self.content.page.wait_for_page_load()
        assert('/qa' in self.content.current_url()), \
            'Not taken to the QA viewer: %s' % self.content.current_url()

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

    # Case C8243 - 006 - Content Analyst | Access the Content Analyst Console
    @pytest.mark.skipif(str(8243) not in TESTS, reason='Excluded')
    def test_content_analyst_access_the_content_analyst_console_8243(self):
        """Access the Content Annalyst Console.

        Steps:
        Click on the 'Login' button
        Enter the content analyst account in the username and password boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the Content Analyst option

        Expected Result:
        The user is presented with the Content Analyst Console
        """
        self.ps.test_updates['name'] = 't1.36.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.006', '8243']
        self.ps.test_updates['passed'] = False

        self.content.login()
        self.content.open_user_menu()
        self.content.wait.until(
            expect.element_to_be_clickable((
                By.XPATH,
                '//a[contains(text(),"Content Analyst") and @role="menuitem"]'
            ))
        ).click()
        self.content.page.wait_for_page_load()
        self.content.find(
            By.XPATH,
            '//h1[contains(text(),"Content Analyst Console")]'
        )

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

    # Case C8244 - 007 - Content Analyst | Log out
    @pytest.mark.skipif(str(8244) not in TESTS, reason='Excluded')
    def test_content_analyst_log_out_8244(self):
        """Log out.

        Steps:
        Click on the 'Login' button
        Enter the content analyst account in the username and password boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the Log out option

        Expected Result:
        The user is logged out
        """
        self.ps.test_updates['name'] = 't1.36.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.007', '8244']
        self.ps.test_updates['passed'] = False

        self.content.login()
        self.content.open_user_menu()
        self.content.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@value,"Log Out")]')
            )
        ).click()
        self.content.page.wait_for_page_load()
        self.content.find(
            By.XPATH,
            '//div[contains(@class,"tutor-home")]'
        )

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

    # Case C8245 - 008 - Student | Log into Tutor
    @pytest.mark.skipif(str(8245) not in TESTS, reason='Excluded')
    def test_student_log_into_tutor_8245(self):
        """Log into Tutor.

        Steps:
        Click on the 'Login' button
        Enter the student account in the username and password text boxes
        Click on the 'Sign in' button

        Expected Result:
        The user is logged in
        """
        self.ps.test_updates['name'] = 't1.36.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.008', '8245']
        self.ps.test_updates['passed'] = False

        self.student.get(self.student.url)
        self.student.page.wait_for_page_load()
        # check to see if the screen width is normal or condensed
        if self.student.driver.get_window_size()['width'] <= \
           self.student.CONDENSED_WIDTH:
            # get small-window menu toggle
            is_collapsed = self.student.find(
                By.XPATH,
                '//button[contains(@class,"navbar-toggle")]'
            )
            # check if the menu is collapsed and, if yes, open it
            if('collapsed' in is_collapsed.get_attribute('class')):
                is_collapsed.click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Login')
            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.ID,
            'auth_key'
        ).send_keys(self.student.username)
        self.student.find(
            By.ID,
            'password'
        ).send_keys(self.student.password)
        # click on the sign in button
        self.student.find(
            By.XPATH,
            '//button[text()="Sign in"]'
        ).click()
        self.student.page.wait_for_page_load()
        assert('dashboard' in self.student.current_url()), \
            'Not taken to dashboard: %s' % self.student.current_url()

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

    # Case C8246 - 009 - Teacher | Log into Tutor
    @pytest.mark.skipif(str(8246) not in TESTS, reason='Excluded')
    def test_teacher_log_into_tutor_8246(self):
        """Log into Tutor.

        Steps:
        Click on the 'Login' button
        Enter the teacher account in the username and password text boxes
        Click on the 'Sign in' button

        Expected Result:
        The user is logged in
        """
        self.ps.test_updates['name'] = 't1.36.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.009', '8246']
        self.ps.test_updates['passed'] = False

        self.teacher.get(self.teacher.url)
        self.teacher.page.wait_for_page_load()
        # check to see if the screen width is normal or condensed
        if self.teacher.driver.get_window_size()['width'] <= \
           self.teacher.CONDENSED_WIDTH:
            # get small-window menu toggle
            is_collapsed = self.teacher.find(
                By.XPATH,
                '//button[contains(@class,"navbar-toggle")]'
            )
            # check if the menu is collapsed and, if yes, open it
            if('collapsed' in is_collapsed.get_attribute('class')):
                is_collapsed.click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Login')
            )
        ).click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.ID,
            'auth_key'
        ).send_keys(self.teacher.username)
        self.teacher.find(
            By.ID,
            'password'
        ).send_keys(self.teacher.password)
        # click on the sign in button
        self.teacher.find(
            By.XPATH,
            '//button[text()="Sign in"]'
        ).click()
        self.teacher.page.wait_for_page_load()
        assert('dashboard' in self.teacher.current_url()),\
            'Not taken to dashboard: %s' % self.teacher.current_url()

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

    # Case C58271 - 010 - Student | Log out
    @pytest.mark.skipif(str(58271) not in TESTS, reason='Excluded')
    def test_content_analyst_log_out_58271(self):
        """Log out.

        Steps:
        Click on the 'Login' button
        Enter the student account in the username and password boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the Log out option

        Expected Result:
        The user is logged out
        """
        self.ps.test_updates['name'] = 't1.36.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.010', '58271']
        self.ps.test_updates['passed'] = False

        self.student.login()
        self.student.open_user_menu()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@value,"Log Out")]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH,
            '//div[contains(@class,"tutor-home")]'
        )

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

    # Case C58272 - 011 - Teacher | Log out
    @pytest.mark.skipif(str(58272) not in TESTS, reason='Excluded')
    def test_teacher_log_out_58272(self):
        """Log out.

        Steps:
        Click on the 'Login' button
        Enter the teacher account in the username and password boxes
        Click on the 'Sign in' button
        Click on the user menu
        Click on the Log out option

        Expected Result:
        The user is logged out
        """
        self.ps.test_updates['name'] = 't1.36.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.011', '58272']
        self.ps.test_updates['passed'] = False

        self.teacher.login()
        self.teacher.open_user_menu()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//input[contains(@value,"Log Out")]')
            )
        ).click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"tutor-home")]'
        )

        self.ps.test_updates['passed'] = True
class TestViewStudentPerformance(unittest.TestCase):
    """T1.50 - View Student Performance."""

    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.student.login()

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

    # Case C8287 - 001 - Student | View the personal Performance Forecast
    @pytest.mark.skipif(str(8287) not in TESTS, reason='Excluded')
    def test_student_view_personal_performance_forecast_8287(self):
        """View the personal Performance Forecast.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"

        Expected Result:
        The user is presented with personal Performance Forecast
        """
        self.ps.test_updates['name'] = 't1.50.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.001',
            '8287'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()

        self.student.sleep(5)

        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'

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

    # Case C8288 - 002 - Student | Info icon shows an explanation of the data
    @pytest.mark.skipif(str(8288) not in TESTS, reason='Excluded')
    def test_student_info_icon_shows_explanation_of_the_data_8288(self):
        """Info icon shows an explanation of the data.

        Steps:
        Click on the user menu in the upper right corner of the page
        Click on "Performance Forecast"
        Hover the cursor over the info icon that is next to the
        "Performance Forecast" header

        Expected Result:
        Info icon shows an explanation of the data
        """
        self.ps.test_updates['name'] = 't1.50.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.002',
            '8288'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'

        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'info-link')
            )
        ).click()

        self.student.sleep(5)

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

    # Case C8289 - 003 - Student | View the performance color key
    @pytest.mark.skipif(str(8289) not in TESTS, reason='Excluded')
    def test_student_view_the_performance_color_key_8289(self):
        """View the performance color key.

        Steps:
        Click on the user menu in the upper right corner of the page
        Click on "Performance Forecast"

        Expected Result:
        The performance color key is presented to the user
        (next to the 'Return to Dashboard' button)
        """
        self.ps.test_updates['name'] = 't1.50.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.003',
            '8289'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'

        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'guide-key')
            )
        )

        self.student.sleep(5)

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

    # Case C8290 - 004 - Student | Return To Dashboard button
    # returns to the list dashboard
    @pytest.mark.skipif(str(8290) not in TESTS, reason='Excluded')
    def test_student_return_to_dashboard_button_8290(self):
        """Return To Dashboard button returns to the list dashboard.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"
        Click on "Return To Dashboard"

        Expected Result:
        The user is presented with the list dashboard
        """
        self.ps.test_updates['name'] = 't1.50.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.004',
            '8290'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.sleep(5)
        self.student.open_user_menu()
        self.student.wait.until(
            expect.presence_of_element_located(
                (By.LINK_TEXT, 'Dashboard')
            )
        ).click()

        self.student.sleep(5)

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

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

    # Case C8291 - 005 - Student | A student with zero answers does not
    # show section breakdowns
    @pytest.mark.skipif(str(8291) not in TESTS, reason='Excluded')
    def test_student_no_answers_does_not_show_breakdown_8291(self):
        """A student with zero answers does not show section breakdowns.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account [ student532 | password ] in the
            username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"

        Expected Result:
        The user is presented with blank performance forecast with no
        section breakdowns w/ the words "You have not worked any questions yet"
        """
        self.ps.test_updates['name'] = 't1.50.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.005',
            '8291'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.logout()
        self.student.driver.get("https://tutor-qa.openstax.org/")
        self.student.login(username="******",
                           url="https://tutor-qa.openstax.org/")

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.find(By.CLASS_NAME, "no-data-message")
        self.student.sleep(5)

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

    # Case C8292 - 006 - Student | My Weaker Areas shows up to four problematic
    # sections
    @pytest.mark.skipif(str(8292) not in TESTS, reason='Excluded')
    def test_student_weaker_areas_shows_up_to_four_sections_8292(self):
        """My Weaker Areas shows up to four problematic sections.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"

        Expected Result:
        The user is presented with up to four problematic sections under
        My Weaker Areas
        """
        self.ps.test_updates['name'] = 't1.50.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.006',
            '8292'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'

        weak = self.student.driver.find_elements_by_xpath(
            "//div[@class='chapter-panel weaker']/div[@class='sections']" +
            "/div[@class='section']")

        self.student.sleep(5)

        assert(len(weak) >= 1), \
            'Less than four weaker sections'

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

    # Case C8293 - 007 - Student | Chapters are listed on the left with their
    # sections to the right
    @pytest.mark.skipif(str(8293) not in TESTS, reason='Excluded')
    def test_student_chapter_listed_on_left_with_section_on_right_8293(self):
        """Chapter are listed on the left with their sections to the right.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"
        Scroll to Individual Chapters section

        Expected Result:
        The user is presented with chapters listed on the left and their
        sections on the right
        """
        self.ps.test_updates['name'] = 't1.50.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.007',
            '8293'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'

        self.student.page.wait_for_page_load()

        # Get all the chapter panels
        panels = self.student.driver.find_elements_by_class_name(
            'chapter-panel')

        # Should be one chapter button for each panel, at least one section
        # button per panel
        for panel in panels:
            chapter = panel.find_elements_by_class_name('chapter')
            sections = panel.find_elements_by_class_name('sections')
            assert(len(chapter) > 0), \
                ''

            assert(len(sections) > 0), \
                ''

        self.student.sleep(5)

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

    # Case C8294 - 008 - Student | Clicking on a chapter bar brings up to
    # five practice assessments for that chapter
    @pytest.mark.skipif(str(8294) not in TESTS, reason='Excluded')
    def test_student_clicking_chapter_brings_up_to_five_assessments_8294(self):
        """Clicking chapter bar brings up to 5 practice assessments.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"
        Scroll to the Individual Chapters section
        Click on a chapter bar

        Expected Result:
        The user is presented with up to five practice assessments for
        that chapter
        """
        self.ps.test_updates['name'] = 't1.50.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.008',
            '8294'
        ]
        self.ps.test_updates['passed'] = False
        # btn-block btn btn-default
        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the calendar dashboard'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'

        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.presence_of_element_located((
                By.XPATH,
                "//div[@class='chapter']/button"
            ))
        ).click()

        assert('practice' in self.student.current_url()), \
            'Not presented with practice problems'

        self.student.sleep(5)

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

    # Case C8295 - 009 - Student | Clicking on a section bar brings up to five
    # practice assessments for that section
    @pytest.mark.skipif(str(8295) not in TESTS, reason='Excluded')
    def test_student_clicking_section_brings_up_to_five_assessments_8295(self):
        """Clicking section bar brings up to 5 practice assessments.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"
        Scroll to the Individual Chapters section
        Click on a section bar

        Expected Result:
        The user is presented with up to five practice assessments for that
        section
        """
        self.ps.test_updates['name'] = 't1.50.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.009',
            '8295'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.find(
            By.XPATH,
            "//div[@class='chapter-panel']/div[@class='sections']" +
            "/div[@class='section']/button"
        ).click()

        assert('practice' in self.student.current_url()), \
            'Not presented with practice problems'

        self.student.sleep(5)

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

    # Case C8296 - 010 - Student | Bars without enough data show Practice More
    # To Get Forecast instead of a color bar
    @pytest.mark.skipif(str(8296) not in TESTS, reason='Excluded')
    def test_student_bars_without_data_show_practice_more_8296(self):
        """Bar without enough data show Practice More To Get Forecast.

        Steps:
        Click on the user menu in the upper right corner
        Click on "Performance Forecast"
        Scroll to the Individual Chapters section

        Expected Result:
        The user is presented with the "Practice More To Get Forecast"
        button under a section without enough data instead of a color bar
        """
        self.ps.test_updates['name'] = 't1.50.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            't1',
            't1.50',
            't1.50.010',
            '8296'
        ]
        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'

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.find(By.CLASS_NAME, 'no-data')

        self.ps.test_updates['passed'] = True
class TestImproveLoginRegistrationEnrollment(unittest.TestCase):
    """CC2.09 - Improve Login, Registration, Enrollment."""

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

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

    def get_enrollemnt_code(self, number=0):
        """
        Steps:
        Sign in as teacher
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"

        Return value: code, enrollemnt_url
            code - enrollment code
            enrollemnt_url - url of book for course
        """
        self.teacher.login()
        if number != 0:
            cc_courses = self.teacher.find_all(
                By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
            )
            cc_courses[number].click()
        else:
            self.teacher.find(
                By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
            ).click()
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Course Settings and Roster'
        ).click()
        self.teacher.find(
            By.XPATH, '//span[contains(text(),"Your student enrollment code")]'
        ).click()
        self.teacher.sleep(1)
        code = self.teacher.find(
            By.XPATH, '//p[@class="code"]'
        ).text
        enrollement_url = self.teacher.find(
            By.XPATH, '//textarea'
        ).text
        enrollement_url = enrollement_url.split('\n')[5]
        self.teacher.find(
            By.XPATH, '//button[@class="close"]'
        ).click()
        self.teacher.sleep(0.5)
        self.teacher.logout()
        return code, enrollement_url

    def create_user(self, start_num, end_num):
        """
        creates a new user and return the username
        """
        self.student.get("http://accounts-qa.openstax.org")
        num = str(randint(start_num, end_num))
        self.student.find(By.LINK_TEXT, 'Sign up').click()
        self.student.find(
            By.ID, 'identity-login-button').click()
        self.student.find(
            By.ID, 'signup_first_name').send_keys('first_name_001')
        self.student.find(
            By.ID, 'signup_last_name').send_keys('last_name_001')
        self.student.find(
            By.ID, 'signup_email_address').send_keys('*****@*****.**')
        self.student.find(
            By.ID, 'signup_username').send_keys('automated_09_'+num)
        self.student.find(
            By.ID, 'signup_password'
        ).send_keys(os.getenv('STUDENT_PASSWORD'))
        self.student.find(
            By.ID, 'signup_password_confirmation'
        ).send_keys(os.getenv('STUDENT_PASSWORD'))
        self.student.find(By.ID, 'signup_i_agree').click()
        self.student.find(
            By.ID, 'create_account_submit').click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Sign out')
            )
        ).click()
        print('automated_09_'+num)
        return 'automated_09_'+num

    '''
    # 14820 - 001 - Teacher | Register for teaching a CC course as new faculty
    @pytest.mark.skipif(str(14820) not in TESTS, reason='Excluded')
    def test_teacher_register_for_teaching_cc_course_as_new_facult_14820(self):
        """Register for teaching a CC course as new faculty.

        Steps:

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

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

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

    # 14819 - 002 - Teacher | Register for teaching a CC course as
    # returning faculty for the same book
    @pytest.mark.skipif(str(14819) not in TESTS, reason='Excluded')
    def test_teacher_register_for_teaching_cc_course_as_returning_14819(self):
        """Register for teaching a CC course as returning faculty.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click "Course Settings and Roster" from the user menu
        Click "Add Section"
        Create a name when prompted
        Click "Add"
        Click on the sections from previous semesters
        Click "Archive Section"

        Expected Result:
        A new section is added and the old sections are archived
        """
        self.ps.test_updates['name'] = 'cc2.09.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.002', '14819']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.driver.find_element(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.LINK_TEXT, 'Course Settings and Roster'
        ).click()
        # add a new section
        new_section_name = "new_section_" + str(randint(100, 999))
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"add-period")]//button')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="modal-content"]//input[@type="text"]')
            )
        ).send_keys(new_section_name)
        self.teacher.driver.find_element(
            By.XPATH,
            '//div[@class="modal-content"]//button/span[text()="Add"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//li//a[@role="tab" and text()="' + new_section_name + '"]')
            )
        )
        # revove old section
        old_section_name = self.teacher.find(By.XPATH, '//a[@role="tab"]').text
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//li//a[@role="tab" and text()="' + old_section_name + '"]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(@class,"archive-period")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@role="tooltip"]//button' +
                 '//span[contains(text(),"Archive")]')
            )
        ).click()
        self.teacher.sleep(2)
        archived = self.teacher.driver.find_elements(
            By.XPATH,
            '//li//a[@role="tab" and text()="' + old_section_name + '"]')
        assert(len(archived) == 0), ' not archived'

        # arhive new section and re-add old section as clean-up
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//li//a[@role="tab" and text()="' + new_section_name + '"]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(@class,"archive-period")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@role="tooltip"]//button' +
                 '//span[contains(text(),"Archive")]')
            )
        ).click()

        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[contains(@class,"view-archived-periods")]//button')
            )
        ).click()
        periods = self.teacher.driver.find_elements(
            By.XPATH, '//div[@class="modal-content"]//tbody//tr'
        )
        for period in periods:
            try:
                period.find_element(
                    By.XPATH, ".//td[text()='" + old_section_name + "']")
                period.find_element(
                    By.XPATH,
                    ".//td//span[contains(@class,'restore-period')]//button"
                ).click()
                break
            except NoSuchElementException:
                if period == periods[-1]:
                    raise Exception

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

    # 14759 - 003 - Student | Sign up and enroll in a CC course
    @pytest.mark.skipif(str(14759) not in TESTS, reason='Excluded')
    def test_teacher_sign_up_and_enroll_in_a_cc_course_14759(self):
        """Sign up and enroll in a CC course.

        Steps:
        Sign in as teacher
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"
        Copy and paste the URL into an incognito window
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"
        Click Sign Up
        Click Sign up with a password
        Fill in the required fields
        Click "Create Account"
        Enter the numerical enrollment code you get from the teacher
        Click "Enroll"
        Enter school issued ID, OR skip this step for now

        Expected Result:
        The user is presented with a message that confirms enrollment
        Is redirected to the CC assignment
        """
        self.ps.test_updates['name'] = 'cc2.09.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.003', '14759']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        code, enrollement_url = self.get_enrollemnt_code()
        rand_username = self.create_user(100, 999)
        self.student.get(enrollement_url)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH, '//div[text()="Sign in"]'
        ).click()
        self.student.sleep(0.5)
        login_window = self.student.driver.window_handles[1]
        cc_window = self.student.driver.window_handles[0]
        self.student.driver.switch_to_window(login_window)
        print(rand_username)
        self.student.find(
            By.ID, 'auth_key').send_keys(rand_username)
        print(self.student.password)
        self.student.find(
            By.ID, 'password').send_keys(self.student.password)
        self.student.find(
            By.XPATH, '//button[text()="Sign in"]').click()
        try:
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
        except NoSuchElementException:
            pass
        self.student.driver.switch_to_window(cc_window)
        self.student.sleep(1)
        self.student.find(
            By.XPATH, '//input[@placeholder="enrollment code"]'
        ).send_keys(code)
        self.student.find(
            By.XPATH, '//button/span[text()="Enroll"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[@class="skip"]')
            )
        ).click()
        # check for confirmation message
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//*[contains(text(),"You have successfully joined")]')
            )
        )

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

    # 14862 - 004 - Student | Sign in and enroll in a CC course
    @pytest.mark.skipif(str(14862) not in TESTS, reason='Excluded')
    def test_teacher_sign_in_and_enroll_in_a_cc_course_14862(self):
        """Sign in and enroll in a CC course.

        Steps:
        Sign in as teacher100
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"
        Copy and paste the URL into an incognito window
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"
        Click Sign In
        Sign in as student71
        Enter the numerical enrollment code you get from the teacher
        Click "Enroll"
        Enter school issued ID, OR skip this step for now

        Expected Result:
        The user is presented with a message that confirms enrollment
        Is redirected to the CC assignment
        """
        self.ps.test_updates['name'] = 'cc2.09.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.004', '14862']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        code, enrollement_url = self.get_enrollemnt_code()
        # use a new student so that when run a second time no issues
        # with student already being enrolled in course
        rand_username = self.create_user(100, 999)
        self.student.get(enrollement_url)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH, '//div[text()="Sign in"]'
        ).click()
        self.student.sleep(0.5)
        login_window = self.student.driver.window_handles[1]
        cc_window = self.student.driver.window_handles[0]
        self.student.driver.switch_to_window(login_window)
        self.student.find(
            By.ID, 'auth_key').send_keys(rand_username)
        self.student.find(
            By.ID, 'password').send_keys(self.student.password)
        self.student.find(
            By.XPATH, '//button[text()="Sign in"]').click()
        try:
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
            self.student.find(By.ID, "i_agree").click()
            self.student.find(By.ID, "agreement_submit").click()
        except NoSuchElementException:
            pass
        self.student.driver.switch_to_window(cc_window)
        self.student.sleep(1)
        self.student.find(
            By.XPATH, '//input[@placeholder="enrollment code"]'
        ).send_keys(code)
        self.student.find(
            By.XPATH, '//button/span[text()="Enroll"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[@class="skip"]')
            )
        ).click()
        # check for confirmation message
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//*[contains(text(),"You have successfully joined")]')
            )
        )

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

    # 14771 - 005 - User | View a message that says you need an enrollment code
    # before signing up
    @pytest.mark.skipif(str(14771) not in TESTS, reason='Excluded')
    def test_user_view_a_message_that_says_you_need_an_enrollment_14771(self):
        """View a message that says you need an enrollment code before signing up.

        Steps:
        Sign in as teacher100
        Click on a Concept Coach course
        Click on "Course Settings and Roster" from the user menu
        Click "Your Student Enrollment Code"
        Copy and paste the URL into an incognito window
        Click "Jump to Concept Coach"
        Click "Launch Concept Coach"

        Expected Result:
        The user is presented with a message that says "Sign up with your
        enrollment code. If you don't have an enrollment code, contact your
        instructor."
        """
        self.ps.test_updates['name'] = 'cc2.09.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.005', '14771']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        code, enrollement_url = self.get_enrollemnt_code()
        self.student.get(enrollement_url)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//p[@class="code-required"]')
            )
        )

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

    # 14821 - 006 - Student | Jump to CC from the top of the reading
    @pytest.mark.skipif(str(14821) not in TESTS, reason='Excluded')
    def test_student_jump_to_cc_from_the_top_of_the_reading_14821(self):
        """Jump to CC from the top of the reading.

        Steps:
        If the user has more than one course, click on a CC course name
        Click on a non-introductory section
        Click "Jump to Concept Coach"

        Expected Result:
        The screen jumps to the "Launch Concept Coach" button
        """
        self.ps.test_updates['name'] = 'cc2.09.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.006', '14821']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.find(
            By.XPATH, '//a[contains(@href,"cnx")]'      # possibly change
        ).click()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button//span[text()="Contents"]')
            )
        ).click()
        self.student.sleep(0.5)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]')
            )
        ).click()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        )

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

    # 14822 - 007 - Teacher | Jump to CC from the top of the reading
    @pytest.mark.skipif(str(14822) not in TESTS, reason='Excluded')
    def test_teacher_jump_to_cc_from_the_top_of_the_reading_14822(self):
        """Jump to CC from the top of the reading.

        Steps:
        If the user has more than one course, click on a CC course name
        Click "Online Book"
        Click on a non-introductory section
        Click "Jump to Concept Coach"

        Expected Result:
        The screen jumps to the "Launch Concept Coach" button
        """
        self.ps.test_updates['name'] = 'cc2.09.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc2', 'cc2.09', 'cc2.09.007', '14822']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//a[contains(@href,"/cc-dashboard")]'
        ).click()
        # open book
        self.teacher.driver.find_element(
            By.XPATH, '//a//span[contains(text(),"Online Book")]'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('cnx' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'
        # get to non-introductory section of book
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button//span[text()="Contents"]')
            )
        ).click()
        self.student.sleep(0.5)
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//span[@class="chapter-number" and text()="1.1"]')
            )
        ).click()
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.LINK_TEXT, 'Jump to Concept Coach')
            )
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[text()="Launch Concept Coach"]')
            )
        )
        self.ps.test_updates['passed'] = True

    # 107585 - 008 - Teacher | Register and enroll in a CC course without a
    # username
    @pytest.mark.skipif(str(107585) not in TESTS, reason='Excluded')
    def test_teacher_jump_to_cc_from_the_top_of_the_reading_107585(self):
        """Register and enroll in a CC course thout a username.

        Steps:
        [Get an enrollment link from a teacher in course settings and roster]
        Go to link
        Click orange "Jump to Concept Coach" button
        Click "Enroll in This Course"
        Click "sign Up and Enroll"

        [In the new window'
        Select 'Student' from the 'I am a' drop down menu
        Enter an email into the email text box
        Click 'Next'
        [an email with a pin is sent, log onto email and get pin]
        Enter Pin into text box
        Click 'Confirm'
        Enter password [staxly16] into password text box
        Re-Enter password in confirm password text box
        Click Submit
        Enter first name into the 'First Name' text box
        Enter last name into the 'Last Name' text box
        Enter school into 'School' text box
        Click the checkbox for 'I Agree' for the Terms of Use and the Privacy
        Policy
        Click 'Create Account'

        Click the checkbox and click 'I Agree' for the Terms of Use
        Click the checkbox and click 'I Agree' for the Privacy Policy

        Expected Result:
        Pop-up box for account creation is closed.
        New user is logged into Concept Coach.
        """
        self.ps.test_updates['name'] = 'cc2.09.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc2',
            'cc2.09',
            'cc2.09.008',
            '107585'
        ]
        self.ps.test_updates['passed'] = False

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

        self.ps.test_updates['passed'] = True
class TestDeliveringAssignments(unittest.TestCase):
    """CC1.12 - Delivering Assignments."""

    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
        )

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

    # Case C7738 - 001 - System | PDF is available for download for
    # CC derived copy
    @pytest.mark.skipif(str(7738) not in TESTS, reason='Excluded')
    def test_system_pdf_is_available_for_download_7738(self):
        """PDF is available for download for a Concept Coach derived copy.

        Steps:
        got to https://cnx.org/
        select a textbook
        Scroll to the bottom of the page
        Click on the 'Downloads' button
        Click on the 'PDF' link
        Click on 'Download for Free'

        Expected Result:
        The book is downloaded as a PDF.
        """
        self.ps.test_updates['name'] = 'cc1.12.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.001', '7738']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://cnx.org/')
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"book")]/a/img')

            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"media-header")]')
            )
        )
        self.student.driver.execute_script(
            "window.scrollTo(0, document.body.scrollHeight);")
        self.student.driver.find_element(
            By.XPATH, '//div[@class="media-footer"]//li[@id="downloads-tab"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//div[@class="downloads tab-content"]' +
                 '//td//a[contains(text(),".pdf")]')
            )
        ).click()
        self.student.page.wait_for_page_load()
        element = self.student.driver.find_element(
            By.XPATH,
            '//a[contains(text(),"Download for Free")]'
        )
        coursename = element.get_attribute('href')
        coursename = coursename.split('/')[-1]
        element.click()
        self.student.sleep(1)
        # check that it was downloaded
        home = os.getenv("HOME")
        print(home + '/Downloads' + coursename)
        os.path.isfile(home + '/Downloads' + coursename)

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

    # Case C7741 - 002 - System | Webview table of contents matches the PDF
    # numbering
    @pytest.mark.skipif(str(7741) not in TESTS, reason='Excluded')
    def test_system_webview_table_of_contents_matches_the_pdf_numbe_7741(self):
        """Webview table of contents matches the PDF numbering.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Online Book' button
        Return to initial tab/window with tutor
        Click on 'HW PDF' -- a pdf will be downloaded

        Expected Result:
        The table of content numberings match between the web view and PDF.
        """
        self.ps.test_updates['name'] = 'cc1.12.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.002', '7741']
        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 C7742 - 003 - Student | Find the CC book from an online search
    @pytest.mark.skipif(str(7742) not in TESTS, reason='Excluded')
    def test_student_find_the_cc_book_from_an_online_search_7742(self):
        """Find the Concept Coach book from an online search.

        Steps:
        Search the title of the book, with 'openstax' through a search engine

        Expected Result:
        The search returns a link to the book
        """
        self.ps.test_updates['name'] = 'cc1.12.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.003', '7742']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://www.google.com')
        self.student.page.wait_for_page_load()
        actions = ActionChains(self.student.driver)
        actions.send_keys('openstax concept coach biology')
        actions.send_keys(Keys.RETURN)
        actions.perform()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//a[contains(text(),"Biology with Concept Coach")]')
            )
        )
        self.student.driver.find_element(
            By.XPATH, '//cite[contains(text(),"https://cnx.org/")]')

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

    # Case C7743 - 004 - Student | Find the Concept Coach book from CNX
    @pytest.mark.skipif(str(7743) not in TESTS, reason='Excluded')
    def test_student_find_the_cc_book_from_cnx_7743(self):
        """Find the Concept Coach book from CNX.

        Steps:
        Go to CNX
        Click search
        Click Advance Search
        Search the name of the book in the title text box
        (include 'with Concept Coach' in the search)

        Expected Result:
        The book is displayed in the results
        """
        self.ps.test_updates['name'] = 'cc1.12.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.004', '7743']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://cnx.org/browse')
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH, '//a[contains(text(),"Search") and @href="/browse"]'
        ).click()
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH, '//a[contains(@class,"advanced-search btn")]'
        ).click()
        self.student.page.wait_for_page_load()
        self.student.driver.find_element(
            By.XPATH, '//input[@name="title"]'
        ).send_keys('Biology with Concept Coach')
        self.student.driver.find_element(
            By.XPATH, '//button[@type="submit"]'
        ).click()
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//td//a[contains(text(),"Biology with Concept Coach")]')
            )
        )

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

    # Case C7746 - 005 - User | View the chapter and section number before the
    # CNX page module title
    @pytest.mark.skipif(str(7746) not in TESTS, reason='Excluded')
    def test_user_view_the_chapter_and_section_number_before_cnx_7746(self):
        """View the chapter and section number before the CNX page module title.

        Steps:
        Go to a Concept Coach book
        If the contents is not already open, Click on contents
        Click on a chapter
        Click on a section

        Expected Result:
        The chapter and section appear before the name of the module.
        """
        self.ps.test_updates['name'] = 'cc1.12.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.005', '7746']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.driver.get('https://cnx.org/')
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"book")]/a/img')

            )
        ).click()
        self.student.page.wait_for_page_load()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"media-header")]')
            )
        )
        self.student.driver.find_element(
            By.XPATH,
            '//div[@class="media-toolbar"]' +
            '//button[contains(@class,"toggle")]' +
            '//span[contains(text(),"Contents")]'
        ).click()
        self.student.sleep(0.5)
        self.student.driver.find_element(
            By.XPATH, '//span[@class="chapter-number" and text()="1.1"]'
        ).click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[@class="title-chapter" and text()="1.1"]')
            )
        )

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

    # Case C7747 - 006 - System | Display correct PDF numbering when the print
    # style is CCAP
    @pytest.mark.skipif(str(7747) not in TESTS, reason='Excluded')
    def test_system_display_correct_pdf_numbering_when_the_print_7747(self):
        """Display correct PDF numbering when the print style is CCAP.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 'cc1.12.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.12', 'cc1.12.006', '7747']
        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
Exemple #39
0
class TestViewTheListDashboard(unittest.TestCase):
    """T1.45 - View the list dashboard."""
    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)
        else:
            self.student = Student(use_env_vars=True)
        self.student.login()

    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)
        try:
            self.student.delete()
        except:
            pass

    # Case C162190 - 001 - Student | View Various Aspects of Tutor
    @pytest.mark.skipif(str(162190) not in TESTS, reason='Excluded')
    def test_student_view_the_assignemnt_list_162190(self):
        """
        #STEPS
        Go to https://tutor-qa.openstax.org/
        Click on the 'Login' button
        Enter the student user account [ ] in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, select a Tutor course
        ***The user is presented with their list of assignments.*** 
        ***Assignments for the current week are displayed.*** 
        ***Upcoming assignments are displayed under the table titled 'Coming Up'***
        ***You can see the recent topics under the "Performance Forecast" on the dashboard***(

        Click "Get Help" from the user menu in the upper right corner of the screen
        ***The user is presented with the Tutor Help Center***

        Click the 'View All Topics'
        ***The user is presented with their performance forecast.*** 

        Open the drop down menu by clicking on the menu link with the user's name
        Click on 'Performance Forecast'
        ***The user is presented with their performance forecast.*** 

        Click the button that says "Return to Dashboard"
        Click the button that says 'All Past Work'
        ***The student's past work is displayed.***
        ***Late assignments have a red clock displayed next to their 'Progress' status.***

        Click the 'Browse The Book' button
        # EXPECTED RESULT 
        ***The user is taken to the book in a new tab.*** 

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

        # View Dashboard
        self.student.select_course(appearance='college_physics')
        self.student.page.wait_for_page_load()

        # View the Assignments for the current week
        self.student.wait.until(
            expect.visibility_of_element_located((By.LINK_TEXT, 'This Week')))

        # View the Upcoming Assignments
        try:
            self.student.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"-upcoming")]')))
        except TimeoutException:
            self.student.driver.find_element(
                By.XPATH, '//div[contains(text(),"No upcoming events")]')

        # View Recent Performance Forecast Topics
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//h3[contains(@class, "recent")]')))
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class, "guide-group")]')))

        # View Performance Forecast Using Dashboard Button
        performance = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button[contains(@class,"view-performance-forecast")]')))
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', performance)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        performance.click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

        # View Performance Forecast Using the Menu

        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'viewPerformanceGuide'))).click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'dashboard'))).click()

        # # View the Student's Past Work
        # self.student.wait.until(
        #     expect.visibility_of_element_located(
        #         (By.LINK_TEXT, 'All Past Work')
        #     )
        # ).click()
        # assert(past_work.get_attribute('aria-selected') == 'true'),\
        #     'not viewing past work'

        # # Late Assignments have a red clock displayed next to their "Progress" tab

        # late = self.student.wait.until(
        #     expect.visibility_of_element_located(
        #         (By.XPATH, '//i[contains(@class,"info late")]')
        #     )
        # )
        # self.student.driver.execute_script(
        #     'return arguments[0].scrollIntoView();', late)
        # self.student.driver.execute_script('window.scrollBy(0, -80);')
        # late.click()

        # Click Browse The Book button

        book = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(@class,"view-reference-guide")]' +
                 '//div[contains(text(),"Browse the Book")]')))
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', book)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        book.click()

        window_with_book = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_book)
        assert('book' in self.student.current_url()), \
            'Not viewing the textbook PDF'

        self.ps.test_updates['passed'] = True
class TestPractice(unittest.TestCase):
    """T1.55 - Practice."""

    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.student.login()
        self.student.select_course(appearance='physics')
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
        self.wait.until(
            expect.visibility_of_element_located((
                By.XPATH,
                '//button[contains(@class,"practice")]//span'
            ))
        ).click()

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

    # Case C8297 - 001 - Student | Click on a section performance forecast bar
    # to start practice session
    @pytest.mark.skipif(str(8297) not in TESTS, reason='Excluded')
    def test_student_click_on_a_section__bar_to_start_practice_8297(self):
        """Click on a section performance forecast bar to start a practice

        Steps:
        Click one of the section performance bars from the dashboard (in setup)

        Expected Result:
        The user is taken to a practice session for the section.
        """
        self.ps.test_updates['name'] = 't1.55.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.001', '8297']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assert('practice' in self.student.current_url()), \
            'Not in practice assignment'

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

    # Case C8298 - 002 - Student | Navigate between questions using breadcrumbs
    @pytest.mark.skipif(str(8298) not in TESTS, reason='Excluded')
    def test_student_navigate_between_questions_using_breadcrumbs_8298(self):
        """Navigate between questions using the breadcrumbs.

        Steps:
        Click a breadcrumb

        Expected Result:
        The student is taken to a different question in the practice session.
        """
        self.ps.test_updates['name'] = 't1.55.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.002', '8298']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        section = sections[-2]
        chapter = section.get_attribute("data-reactid")
        section.click()
        self.student.find(
            By.XPATH,
            '//div[contains(@data-question-number,"%s")]' %
            (int(chapter[-1]) + 1)
        )

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

    # Case C8299 - 003 - Student | Scrolling the window up reveals the header
    @pytest.mark.skipif(str(8299) not in TESTS, reason='Excluded')
    def test_student_scrolling_the_window_up_reveals_the_header_bar_8299(self):
        """Scrolling the window up reveals the header bar.

        Steps:
        Scroll down
        Scroll to the top of the page

        Expected Result:
        The header bar, containing the course name, OpenStax logo,
        and user menu link is visible.
        """
        self.ps.test_updates['name'] = 't1.55.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.003', '8299']
        self.ps.test_updates['passed'] = False

        # answer free response first
        # so that mc questions appear and there is enough text to scroll
        try:
            self.student.find(
                By.TAG_NAME, 'textarea').send_keys("hello")
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//button/span[contains(text(),"Answer")]')
                )
            ).click()
        except NoSuchElementException:
            pass
        # scroll page
        self.student.driver.execute_script("window.scrollTo(0, 100);")
        self.student.driver.execute_script("window.scrollTo(0, 0);")
        self.student.find(By.CLASS_NAME, 'ui-brand-logo')

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

    # Case C8300 - 004 - Student | Inputting a free response activates the
    # Answer button
    @pytest.mark.skipif(str(8300) not in TESTS, reason='Excluded')
    def test_student_inputting_a_free_response_activates_the_button_8300(self):
        """Inputting a free response into activates the Answer button.

        Steps:
        If there is a text box: input text
            OR
        Click on the next breadcrumb until a textbox is available

        Expected Result:
        The "Answer" button is click-able.
        """
        self.ps.test_updates['name'] = 't1.55.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.004', '8300']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        for x in range(len(sections)):
            try:
                element = self.student.find(
                    By.TAG_NAME, 'textarea')
                for i in 'hello':
                    element.send_keys(i)
                self.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH, '//button/span[contains(text(),"Answer")]')
                    )
                )
                break
            except NoSuchElementException:
                if x >= len(sections)-1:
                    print('no questions in this practice with free respnse')
                    raise Exception
                sections_new = self.student.find_all(
                    By.XPATH, '//span[contains(@class,"breadcrumbs")]')
                sections_new[x].click()

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

    # Case C8301 - 005 - Student | Answer a free reponse question
    @pytest.mark.skipif(str(8301) not in TESTS, reason='Excluded')
    def test_student_answer_a_free_response_question_8301(self):
        """Answer a free reponse question.

        Steps:
        If there is a text box, input text
        Click the "Answer" button

        Expected Result:
        The text box disappears and the multiple choice answer appear.
        """
        self.ps.test_updates['name'] = 't1.55.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.005', '8301']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        answer_text = "hello"
        for x in range(len(sections)):
            try:
                element = self.student.find(
                    By.TAG_NAME, 'textarea')
                for i in answer_text:
                    element.send_keys(i)
                self.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH, '//button/span[contains(text(),"Answer")]')
                    )
                ).click()
                break
            except NoSuchElementException:
                if x >= len(sections) - 1:
                    print('no questions in this homework with free respnse')
                    raise Exception
                sections_new = self.student.find_all(
                    By.XPATH, '//span[contains(@class,"breadcrumbs")]')
                sections_new[x].click()

        self.student.find(
            By.XPATH,
            '//div[@class="free-response" and contains(text(),"' +
            answer_text + '")]')
        self.student.find(
            By.XPATH, '//div[@class="answer-letter"]')

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

    # Case C8302 - 006 - Student | Selecting a multiple choice answer activates
    # the Submit button
    @pytest.mark.skipif(str(8302) not in TESTS, reason='Excluded')
    def test_student_selecting_a_mc_answer_activates_submit_button_8302(self):
        """Selecting a multiple choice answer activates the Submit button.

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer

        Expected Result:
        The "Submit" button can now be clicked
        """
        self.ps.test_updates['name'] = 't1.55.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.006', '8302']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(
                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 NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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.element_to_be_clickable(
                (By.XPATH, '//button/span[contains(text(),"Submit")]')
            )
        )

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

    # Case C8303 - 007 - Student | Submit the assessment
    @pytest.mark.skipif(str(8303) not in TESTS, reason='Excluded')
    def test_student_submit_the_assesment_8303(self):
        """Submit the assessment.

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer
        Click the "Submit" button

        Expected Result:
        The answer is submitted and the 'Next Question' button appears.
        """
        self.ps.test_updates['name'] = 't1.55.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.007', '8303']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(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 NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button/span[contains(text(),"Next Question")]')
            )
        )

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

    # Case C8304 - 008 - Student | Answer feedback is presented
    @pytest.mark.skipif(str(8304) not in TESTS, reason='Excluded')
    def test_student_answer_feedback_is_presented_8304(self):
        """Answer feedback is presented.

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer
        Click the "Submit" button

        Expected Result:
        The answer is submitted, the correct answer is displayed,
        and feedback on the answer is given.
        """
        self.ps.test_updates['name'] = 't1.55.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.008', '8304']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(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 NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//span[contains(@class,"breadcrumbs")]' +
                 '//i[contains(@class,"correct") or ' +
                 'contains(@class,"incorrect")]')
            )
        )

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

    # Case C8305 - 009 - Student | Correctness for a completed assesment is
    # displayed in the breadcrumbs
    @pytest.mark.skipif(str(8305) not in TESTS, reason='Excluded')
    def test_student_correctness_is_displayed_in_the_breadcrumbs_8305(self):
        """Correctness for a completed assessment is displayed in breadcrumbs

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer
        Click the "Submit" button

        Expected Result:
        The correctness for the completed question is visible in the breadcrumb
        """
        self.ps.test_updates['name'] = 't1.55.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.009', '8305']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(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 NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-feedback")]')
            )
        )

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

    # Case C8306 - 010 - Student | The assessment identification number and
    # version are visible
    @pytest.mark.skipif(str(8306) not in TESTS, reason='Excluded')
    def test_student_assesment_id_number_and_version_are_visible_8306(self):
        """The assessment id number and version are visible for each assessment

        Steps:
        Navigate through each question in the assessment

        Expected Result:
        Each question's identification number and version are visible.
        """
        self.ps.test_updates['name'] = 't1.55.0010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.010', '8306']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(text(),"ID#")]')
            )
        )
        self.student.find(
            By.XPATH, '//span[contains(text(),"@")]')

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

    # Case C8307 - 011 - Student | Clicking on Report an error renders the
    # Assessment Errata Form and prefills the assessment
    @pytest.mark.skipif(str(8307) not in TESTS, reason='Excluded')
    def test_student_clicking_on_report_an_error_renders_form_8307(self):
        """Clicking on Report an error renders the Assessment Errata Form

        Steps:
        Click the "Report an error" link

        Expected Result:
        The user is taken to the Assessment Errata Form and the ID is prefilled
        """
        self.ps.test_updates['name'] = 't1.55.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.011', '8307']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        id_num = self.student.find(
            By.XPATH,
            '//span[contains(@class,"exercise-identifier-link")]//span[2]'
        ).text
        self.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Report an error')
            )
        ).click()
        window_with_form = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_form)
        self.student.page.wait_for_page_load()
        self.student.find(
            By.XPATH, '//div[contains(text(),"Report Content Errors")]')
        text_box = self.student.find(
            By.XPATH, '//input[contains(@aria-label,"ID is required")]')
        assert(text_box.get_attribute('value') == id_num), \
            'form not prefilled correctly'

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

    # Case C8308 - 012 - Student | Submit the Assessment Errata Form
    @pytest.mark.skipif(str(8308) not in TESTS, reason='Excluded')
    def test_student_submit_the_assesment_errata_form_8308(self):
        """Submit the Assessment Errata Form.

        Steps:
        Click the "Report an error" link
        Fill out the fields
        Click the "Submit" button

        Expected Result:
        The form is submitted
        """
        self.ps.test_updates['name'] = 't1.55.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.011', '8307']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Report an error')
            )
        ).click()
        window_with_form = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_form)
        self.student.page.wait_for_page_load()
        # fill out form
        self.student.find(
            By.TAG_NAME, 'textarea').send_keys('qa test')
        self.student.find(
            By.XPATH, '//div[@data-value="Minor" and @role="radio"]').click()
        self.student.find(
            By.XPATH, '//div[@data-value="other" and @role="radio"]').click()
        self.student.find(
            By.XPATH,
            '//div[contains(@data-value,"Biology") and @role="radio"]'
        ).click()
        self.student.find(
            By.XPATH, '//div[@data-value="Safari" and @role="radio"]').click()
        self.student.find(
            By.XPATH, '//span[text()="Submit"]').click()
        # find submitted message
        self.student.find(
            By.XPATH,
            '//div[contains(text(),"Thank you")]')

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

    # Case C8309 - 013 - Student | End of practice shows the number of
    # assessments answered
    @pytest.mark.skipif(str(8309) not in TESTS, reason='Excluded')
    def test_student_end_of_practice_shows_the_number_answered_8309(self):
        """End of practice shows the number of assessments answered.

        Steps:
        Answer some of the assesments
        Click on the last breadcrumb

        Expected Result:
        End of practice shows the number of assessments answered
        """
        self.ps.test_updates['name'] = 't1.55.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.013', '8309']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        stop_point = len(sections)//2

        for _ in range(stop_point):
            try:
                # if the question is two part must answer free response first
                element = self.student.find(
                    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 NoSuchElementException:
                pass
            # answer the mc portion
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"question-stem")]')
                )
            )
            element = self.student.find(
                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.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//button/span[contains(text(),"Next Question")]')
                )
            ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(@class,"breadcrumb-end")]')
            )
        ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"completed-message")]')
            )
        ).click()
        self.student.find(
            By.XPATH,
            '//div[contains(@class,"completed-message")]' +
            '//span[contains(@data-reactid,"0.1") and contains(text(),"' +
            str(stop_point) + '")]')
        self.student.find(
            By.XPATH,
            '//div[contains(@class,"completed-message")]' +
            '//span[contains(@data-reactid,"0.3") and contains(text(),"' +
            str(len(sections) - 1) + '")]')

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

    # Case C8310 - 014 - Student | Back To Dashboard button returns the user
    # to the dashboard
    @pytest.mark.skipif(str(8310) not in TESTS, reason='Excluded')
    def test_student_back_to_dashboard_button_returns_to_dashboard_8310(self):
        """Clicking the Back To Dashboard button returns user to the dashboard.

        Steps:
        Answer all the assessments
        Click the "Back To Dashboard" button

        Expected Result:
        The user is returned to the dashboard
        """
        self.ps.test_updates['name'] = 't1.55.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.014', '8310']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        for _ in range(len(sections) - 1):
            try:
                # if the question is two part must answer free response first
                element = self.student.find(
                    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 NoSuchElementException:
                pass
            # answer the free response portion
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"question-stem")]')
                )
            )
            element = self.student.find(
                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.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//button/span[contains(text(),"Next Question")]')
                )
            ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(text(),"Back to Dashboard")]')
            )
        ).click()
        assert('list' in self.student.current_url()), \
            'Not returned to list dashboard'

        self.ps.test_updates['passed'] = True
class TestSimplifyAndImproveReadings(unittest.TestCase):
    """T2.13 - Simplify and Improve Readings."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities["name"] = self.id()
        self.teacher = Teacher(use_env_vars=True, pasta_user=self.ps, capabilities=self.desired_capabilities)
        # create a reading for the student to work
        self.teacher.login()
        self.assignment_name = "t1.18 reading-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = today.strftime("%m/%d/%Y")
        end = (today + datetime.timedelta(days=randint(1, 10))).strftime("%m/%d/%Y")
        self.teacher.add_assignment(
            assignment="reading",
            args={
                "title": self.assignment_name,
                "description": chomsky(),
                "periods": {"all": (begin, end)},
                "reading_list": ["1.1", "1.2"],
                "status": "publish",
            },
        )
        self.teacher.wait.until(
            expect.visibility_of_element_located((By.XPATH, '//div[contains(@class,"calendar-container")]'))
        )
        self.teacher.logout()
        # login as a student to work the reading
        self.student = Student(
            existing_driver=self.teacher.driver,
            use_env_vars=True,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
        )
        self.student.login()
        self.student.wait.until(expect.visibility_of_element_located((By.LINK_TEXT, "This Week")))
        reading = self.student.driver.find_element(By.XPATH, '//span[text()="%s"]' % self.assignment_name)
        self.teacher.driver.execute_script("return arguments[0].scrollIntoView();", reading)
        self.teacher.driver.execute_script("window.scrollBy(0, -80);")
        reading.click()

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

    # 14745 - 001 - Student | Relative size and progress are displayed while
    # working a reading assignment
    @pytest.mark.skipif(str(14745) not in TESTS, reason="Excluded")
    def test_student_relative_size_and_progress_are_displayed_whil_14745(self):
        """Size and progress are displayed while working a reading.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name
        Click on a reading assignment
        Click on the right arrow

        Expected Result:
        The progress bar at the top reflects how far along you are as you work
        through the reading assignment
        """
        self.ps.test_updates["name"] = "t2.13.001" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.13", "t2.13.001", "14745"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.driver.find_element(By.XPATH, '//div[contains(@class,"progress-bar progress-bar-success")]')

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

    # 14746 - 002 - Student | Access prior milestones in the reading assignment
    # with breadcrumbs
    @pytest.mark.skipif(str(14746) not in TESTS, reason="Excluded")
    def test_student_access_prior_milestones_in_the_reading_assign_14746(self):
        """Access prior milestones in the reading assignment with breadcrumbs.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on a reading assignment
        Click on the icon next to the calendar on the header

        Expected Result:
        The user is presented with prior milestones
        """
        self.ps.test_updates["name"] = "t2.13.002" + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates["tags"] = ["t2", "t2.13", "t2.13.002", "14746"]
        self.ps.test_updates["passed"] = False

        # Test steps and verification assertions
        self.student.find(By.CSS_SELECTOR, "a.paging-control.next").click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, "a.milestones-toggle").click()
        self.student.sleep(1)
        cards = self.student.find_all(By.CSS_SELECTOR, 'div[class="milestone"]')
        preview = ""
        if not isinstance(cards, list):
            preview = cards.find_element(By.XPATH, '/div[@class="milestone-preview"]').text
            cards.click()
        else:
            card = randint(0, len(cards) - 1)
            preview = cards[card].find_element(By.XPATH, '/div[@class="milestone-preview"]').text
            cards[card].click()
        # Issue: section titles are not in the content
        preview

        self.ps.test_updates["passed"] = True
class TestStudentsWorkAssignments(unittest.TestCase):
    """CC1.08 - Students Work Assignments."""
    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'

    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 C7691 - 001 - Student | Selects an exercise answer
    @pytest.mark.skipif(str(7691) not in TESTS, reason='Excluded')
    def test_student_select_an_exercise_answer_7691(self):
        """Select an exercise answer."""
        self.ps.test_updates['name'] = 'cc1.08.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.001', '7691']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.get(self.book_url)
        self.student.sleep(2)
        self.student.find_all(By.XPATH, '//a[@class="nav next"]')[0].click()
        self.student.page.wait_for_page_load()
        try:
            widget = self.student.find(By.ID, 'coach-wrapper')
        except:
            self.student.find_all(By.XPATH,
                                  '//a[@class="nav next"]')[0].click()
            self.student.page.wait_for_page_load()
            try:
                self.student.sleep(1)
                widget = self.student.find(By.ID, 'coach-wrapper')
            except:
                self.student.find_all(By.XPATH,
                                      '//a[@class="nav next"]')[0].click()
                self.student.page.wait_for_page_load()
                self.student.sleep(1)
                widget = self.student.find(By.ID, 'coach-wrapper')
        Assignment.scroll_to(self.student.driver, widget)
        self.student.find(
            By.XPATH,
            '//button[span[contains(text(),"Launch Concept Coach")]]').click()
        self.student.sleep(1.5)
        base_window = self.student.driver.window_handles[0]
        self.student.find(By.CSS_SELECTOR, 'div.sign-up').click()
        self.student.sleep(3)
        popup = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(popup)
        self.student.find(By.LINK_TEXT, 'Sign up').click()
        self.student.find(By.ID, 'identity-login-button').click()
        self.student.find(By.ID,
                          'signup_first_name').send_keys(self.first_name)
        self.student.find(By.ID, 'signup_last_name').send_keys(self.last_name)
        self.student.find(By.ID, 'signup_email_address').send_keys(self.email)
        self.student.find(By.ID, 'signup_username').send_keys(self.last_name)
        self.student.find(By.ID,
                          'signup_password').send_keys(self.student.password)
        self.student.find(By.ID, 'signup_password_confirmation').send_keys(
            self.student.password)
        self.student.find(By.ID, 'create_account_submit').click()
        self.student.find(By.ID, 'i_agree').click()
        self.student.find(By.ID, 'agreement_submit').click()
        self.student.find(By.ID, 'i_agree').click()
        self.student.find(By.ID, 'agreement_submit').click()
        self.student.driver.switch_to_window(base_window)
        self.student.find(
            By.XPATH,
            '//input[contains(@label,"Enter the enrollment code")]').send_keys(
                self.code)
        self.student.sleep(2)
        self.student.find(By.CSS_SELECTOR, 'button.enroll').click()
        self.student.sleep(2)
        self.student.find(By.CSS_SELECTOR,
                          'div.field input.form-control').send_keys(
                              self.last_name)
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()
        self.student.sleep(5)
        try:
            self.student.find(By.XPATH, '//button[text()="Continue"]').click()
        except:
            print('Two-step message not seen.')
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH,
                 '//div[@class="openstax-question"]//textarea'))).send_keys(
                     chomsky())
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="answer-letter"]')))
        answers = self.student.find_all(By.CSS_SELECTOR, 'div.answer-letter')
        answers[randint(0, len(answers) - 1)].click()
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()

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

    # Case C7692 - 002 - Student | After answering an exercise feedback
    # is presented
    @pytest.mark.skipif(str(7692) not in TESTS, reason='Excluded')  # NOQA
    def test_student_after_answering_an_exercise_feedback_7692(self):
        """View section completion report.

        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 the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click the 'Answer' button
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        The correct answer is displayed and feedback is given.
        """
        self.ps.test_updates['name'] = 'cc1.08.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.002', '7692']
        self.ps.test_updates['passed'] = False

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

        # //span[@class='title section']
        # get the 21 drop downs in toc

        #    By.PARTIAL_LINK_TEXT, "Macro Econ").click()
        self.student.select_course(appearance='macro_economics')
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)

        finished = False

        # Expand all the chapters in the table of contents
        chapters = self.student.driver.find_elements_by_xpath(
            "//span[@class='title section']")
        chapters.pop(0)
        for chapter in chapters:
            chapter.click()

        # Get all sections, excluding the preface
        sections = self.student.driver.find_elements_by_xpath(
            "//a/span[@class='title']")
        sections.pop(0)

        self.student.sleep(2)

        length = len(sections)

        for num in range(length):

            sections = self.student.driver.find_elements_by_xpath(
                "//a/span[@class='title']")
            sections.pop(0)
            sections[num].click()
            self.student.sleep(3)

            if 'Introduction-to' not in self.student.current_url():
                # Jump to the Concept Coach widget and open Concept Coach
                self.student.find(
                    By.XPATH,
                    "//div[@class='jump-to-cc']/a[@class='btn']").click()
                self.student.sleep(2)
                self.student.find(
                    By.XPATH,
                    "//button[@class='btn btn-lg btn-primary']").click()
                self.student.sleep(2)

                # If this section has been completed already,
                # leave and go to the next section
                breadcrumbs = self.student.driver.find_elements_by_xpath(
                    "//div[@class='task-breadcrumbs']/span")

                breadcrumbs[-1].click()
                self.student.sleep(3)

                if len(
                        self.student.driver.find_elements_by_xpath(
                            "//div[@class='card-body coach-coach-review-completed'][1]"
                        )) > 0:
                    self.student.find(
                        By.XPATH, "//a/button[@class='btn-plain " +
                        "-coach-close btn btn-default']").click()

                # Else, go through questions until a blank one is found
                # and answer the question
                else:
                    for question in breadcrumbs:
                        question.click()

                        if len(
                                self.student.driver.find_elements_by_xpath(
                                    "//div[@class='question-feedback bottom']")
                        ) > 0:
                            continue

                        else:
                            while len(
                                    self.student.driver.find_elements_by_xpath(
                                        "//div[@class='question-feedback bottom']"
                                    )) == 0:

                                if len(
                                        self.student.driver.
                                        find_elements_by_xpath(
                                            "//button[@class='btn btn-default']"
                                        )) > 0:
                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='btn btn-default']"
                                    ).click()
                                    continue

                                # Free response
                                if self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']"
                                ).text == 'Answer':
                                    self.student.find(
                                        By.XPATH, "//textarea").send_keys(
                                            'An answer for this textarea')
                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']").click()
                                    self.student.sleep(3)

                                # Multiple Choice
                                elif self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']"
                                ).text == 'Submit':
                                    answers = self.student.driver.find_elements(  # NOQA
                                        By.CLASS_NAME, 'answer-letter')
                                    self.student.sleep(0.8)
                                    rand = randint(0, len(answers) - 1)
                                    answer = chr(ord('a') + rand)
                                    Assignment.scroll_to(
                                        self.student.driver, answers[0])
                                    if answer == 'a':
                                        self.student.driver.execute_script(
                                            'window.scrollBy(0, -160);')
                                    elif answer == 'd':
                                        self.student.driver.execute_script(
                                            'window.scrollBy(0, 160);')
                                    answers[rand].click()

                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']").click()
                                    self.student.sleep(3)

                                    finished = True

                        break

            if finished:
                break

        self.student.sleep(5)
        self.student.find(By.XPATH, "//div[@class='question-feedback bottom']")

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

    # Case C7693 - 003 - System | Assessments are from the current module
    @pytest.mark.skipif(str(7693) not in TESTS, reason='Excluded')  # NOQA
    def test_system_assessments_are_from_the_current_module_7693(self):
        """Assessment is from the current module.

        Steps:


        Expected Result:
        """
        self.ps.test_updates['name'] = 'cc1.08.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.003', '7693']
        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 C7694 - 004 - System | Spaced practice assessments are from
    # previously worked modules
    @pytest.mark.skipif(str(7694) not in TESTS, reason='Excluded')  # NOQA
    def test_system_spaced_practice_assessments_are_from_previo_7694(self):
        """Spaced practice assessments are from previousy worked modules.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Select a non-introductory section
        Click Jump to Concept Coach
        Click Launch Concept Coach
        Go through the assessments until you get to the Spaced Practice

        Expected Result:
        The section number beneath the text box is from a previous section
        """
        self.ps.test_updates['name'] = 'cc1.08.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.004', '7694']
        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 C7695 - 005 - System | Modules without assessments do not display
    # the Concept Coach widget
    @pytest.mark.skipif(str(7695) not in TESTS, reason='Excluded')  # NOQA
    def test_system_modules_without_assessments_do_not_display_7695(self):
        """Module without assessments does not display the CC widget.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Click on an introductory section

        Expected Result:
        The Concept Coach widget does not appear.
        """
        self.ps.test_updates['name'] = 'cc1.08.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.005', '7695']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='macro_economics')
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)

        # Expand all the chapters in the table of contents
        chapters = self.student.driver.find_elements_by_xpath(
            "//span[@class='title section']")
        chapters.pop(0)
        for chapter in chapters:
            chapter.click()

        # Get all sections, excluding the preface
        sections = self.student.driver.find_elements_by_xpath(
            "//a/span[@class='title']")
        sections.pop(0)

        self.student.sleep(2)

        length = len(sections)

        for num in range(length):

            sections = self.student.driver.find_elements_by_xpath(
                "//a/span[@class='title']")
            sections.pop(0)
            sections[num].click()
            self.student.sleep(3)

            if 'Introduction-to' in self.student.current_url():
                # Jump to the Concept Coach widget and open Concept Coach
                count = self.student.driver.find_elements_by_xpath(
                    "//div[@class='jump-to-cc']/a[@class='btn']")
                self.student.sleep(2)

                assert (len(count) == 0), "Intro should not have CC widget"
                break

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

    # Case C7696 - 006 - Student | Assignment is assistive technology friendly
    @pytest.mark.skipif(str(7696) not in TESTS, reason='Excluded')  # NOQA
    def test_student_assignment_is_assistive_technology_friendly_7696(self):
        """Assignment is assistive technology friendly.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click the 'Answer' button
        Type a, b, c, or d

        Expected Result:
        A multiple choice answer matching the letter typed should be selected.
        """
        self.ps.test_updates['name'] = 'cc1.08.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.006', '7696']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='macro_economics')
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)

        finished = False

        # Expand all the chapters in the table of contents
        chapters = self.student.driver.find_elements_by_xpath(
            "//span[@class='title section']")
        chapters.pop(0)
        for chapter in chapters:
            chapter.click()

        # Get all sections, excluding the preface
        sections = self.student.driver.find_elements_by_xpath(
            "//a/span[@class='title']")
        sections.pop(0)

        self.student.sleep(2)

        length = len(sections)

        for num in range(length):

            sections = self.student.driver.find_elements_by_xpath(
                "//a/span[@class='title']")
            sections.pop(0)
            sections[num].click()
            self.student.sleep(3)

            if 'Introduction-to' not in self.student.current_url():
                # Jump to the Concept Coach widget and open Concept Coach
                self.student.find(
                    By.XPATH,
                    "//div[@class='jump-to-cc']/a[@class='btn']").click()
                self.student.sleep(2)
                self.student.find(
                    By.XPATH,
                    "//button[@class='btn btn-lg btn-primary']").click()
                self.student.sleep(2)

                # If this section has been completed already,
                # leave and go to the next section
                breadcrumbs = self.student.driver.find_elements_by_xpath(
                    "//div[@class='task-breadcrumbs']/span")

                breadcrumbs[-1].click()
                self.student.sleep(3)

                if len(
                        self.student.driver.find_elements_by_xpath(
                            "//div[@class='card-body coach-coach-review-completed'][1]"
                        )) > 0:
                    self.student.find(
                        By.XPATH, "//a/button[@class='btn-plain " +
                        "-coach-close btn btn-default']").click()

                # Else, go through questions until a blank one is found
                # and answer the question
                else:
                    for question in breadcrumbs:
                        question.click()

                        if len(
                                self.student.driver.find_elements_by_xpath(
                                    "//div[@class='question-feedback bottom']")
                        ) > 0:
                            continue

                        else:
                            while len(
                                    self.student.driver.find_elements_by_xpath(
                                        "//div[@class='question-feedback bottom']"
                                    )) == 0:

                                if len(
                                        self.student.driver.
                                        find_elements_by_xpath(
                                            "//button[@class='btn btn-default']"
                                        )) > 0:
                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='btn btn-default']"
                                    ).click()
                                    continue

                                # Free response
                                if self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']"
                                ).text == 'Answer':
                                    self.student.find(
                                        By.XPATH, "//textarea").send_keys(
                                            'An answer for this textarea')
                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']").click()
                                    self.student.sleep(3)

                                # Multiple Choice
                                elif self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']"
                                ).text == 'Submit':
                                    action = ActionChains(self.student.driver)
                                    action.send_keys('c')
                                    action.perform()

                                    self.student.find(
                                        By.XPATH,
                                        "//div[@class='answers-answer " +
                                        "answer-checked']")
                                    self.student.sleep(3)

                                    finished = True
                                    break

                        break

            if finished:
                break

        self.student.sleep(5)

        self.student.sleep(3)

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

    # Case C7697 - 007 - Student | Display the assignment summary
    # after completing the assignment
    @pytest.mark.skipif(str(7697) not in TESTS, reason='Excluded')  # NOQA
    def test_student_display_the_assignment_summary_after_completin_7697(self):
        """Display the assignment summary after completing the assignment.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button
        After answering the last question, click the 'Next Question' button

        Expected Result:
        The summary is displayed
        """
        self.ps.test_updates['name'] = 'cc1.08.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.007', '7697']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='macro_economics')
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)

        finished = False

        # Expand all the chapters in the table of contents
        chapters = self.student.driver.find_elements_by_xpath(
            "//span[@class='title section']")
        chapters.pop(0)
        for chapter in chapters:
            chapter.click()

        # Get all sections, excluding the preface
        sections = self.student.driver.find_elements_by_xpath(
            "//a/span[@class='title']")
        sections.pop(0)

        self.student.sleep(2)

        length = len(sections)

        for num in range(length):

            sections = self.student.driver.find_elements_by_xpath(
                "//a/span[@class='title']")
            sections.pop(0)
            sections[num].click()
            self.student.sleep(3)

            if 'Introduction-to' not in self.student.current_url():
                # Jump to the Concept Coach widget and open Concept Coach
                self.student.find(
                    By.XPATH,
                    "//div[@class='jump-to-cc']/a[@class='btn']").click()
                self.student.sleep(2)
                self.student.find(
                    By.XPATH,
                    "//button[@class='btn btn-lg btn-primary']").click()
                self.student.sleep(2)

                # If this section has been completed already,
                # leave and go to the next section
                breadcrumbs = self.student.driver.find_elements_by_xpath(
                    "//div[@class='task-breadcrumbs']/span")

                breadcrumbs[-1].click()
                self.student.sleep(3)

                if len(
                        self.student.driver.find_elements_by_xpath(
                            "//div[@class='card-body coach-coach-review-completed'][1]"
                        )) > 0:
                    self.student.find(
                        By.XPATH, "//a/button[@class='btn-plain " +
                        "-coach-close btn btn-default']").click()

                # Else, go through questions until a blank one is found
                # and answer the question
                else:
                    for question in breadcrumbs:
                        question.click()

                        if len(
                                self.student.driver.find_elements_by_xpath(
                                    "//div[@class='question-feedback bottom']")
                        ) > 0:
                            if len(
                                    self.student.driver.find_elements_by_xpath(
                                        "//div[@class='card-body coach-" +
                                        "coach-review-completed'][1]")) > 0:
                                finished = True
                            continue

                        else:
                            while len(
                                    self.student.driver.find_elements_by_xpath(
                                        "//div[@class='question-feedback bottom']"
                                    )) == 0:
                                # Free response

                                if len(
                                        self.student.driver.
                                        find_elements_by_xpath(
                                            "//button[@class='btn btn-default']"
                                        )) > 0:
                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='btn btn-default']"
                                    ).click()
                                    continue

                                if self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']"
                                ).text == 'Answer':
                                    self.student.find(
                                        By.XPATH, "//textarea").send_keys(
                                            'An answer for this textarea')
                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']").click()
                                    self.student.sleep(3)

                                # Multiple Choice
                                elif self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']"
                                ).text == 'Submit':
                                    answers = self.student.driver.find_elements(  # NOQA
                                        By.CLASS_NAME, 'answer-letter')
                                    self.student.sleep(0.8)
                                    rand = randint(0, len(answers) - 1)
                                    answer = chr(ord('a') + rand)
                                    Assignment.scroll_to(
                                        self.student.driver, answers[0])
                                    if answer == 'a':
                                        self.student.driver.execute_script(
                                            'window.scrollBy(0, -160);')
                                    elif answer == 'd':
                                        self.student.driver.execute_script(
                                            'window.scrollBy(0, 160);')
                                    answers[rand].click()

                                    self.student.find(
                                        By.XPATH,
                                        "//button[@class='async-button " +
                                        "continue btn btn-primary']").click()
                                    self.student.sleep(3)

            if finished:
                break

        self.student.sleep(5)

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

    # Case C7698 - 008 - Student | The exercise ID is visible within
    # the assessment pane
    @pytest.mark.skipif(str(7698) not in TESTS, reason='Excluded')  # NOQA
    def test_student_exercise_id_is_visible_within_the_assessment_7698(self):
        """The exercise ID is visible within the assessment pane.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student 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 the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page

        Expected Result:
        The exercise ID is visivle on the exercise.
        """
        self.ps.test_updates['name'] = 'cc1.08.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.008', '7698']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='macro_economics')
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)

        # Expand all the chapters in the table of contents
        chapters = self.student.driver.find_elements_by_xpath(
            "//span[@class='title section']")
        chapters.pop(0)
        for chapter in chapters:
            chapter.click()

        # Get all sections, excluding the preface
        sections = self.student.driver.find_elements_by_xpath(
            "//a/span[@class='title']")
        sections.pop(0)

        self.student.sleep(2)

        length = len(sections)

        for num in range(length):

            sections = self.student.driver.find_elements_by_xpath(
                "//a/span[@class='title']")
            sections.pop(0)
            sections[num].click()
            self.student.sleep(3)

            if 'Introduction-to' not in self.student.current_url():
                # Jump to the Concept Coach widget and open Concept Coach
                self.student.find(
                    By.XPATH,
                    "//div[@class='jump-to-cc']/a[@class='btn']").click()
                self.student.sleep(2)
                self.student.find(
                    By.XPATH,
                    "//button[@class='btn btn-lg btn-primary']").click()
                self.student.sleep(2)

                # View summary
                breadcrumbs = self.student.driver.find_elements_by_xpath(
                    "//div[@class='task-breadcrumbs']/span")

                breadcrumbs[-1].click()
                self.student.sleep(3)

                # Verify the first question has an exercise ID
                breadcrumbs[2].click()

                self.student.find(
                    By.XPATH,
                    "//span[@class='exercise-identifier-link']/span[2]")

                break

        self.student.sleep(5)

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

    # Case C7699 - 009 - Student | Able to refer an assessment to OpenStax
    # via Errata Form
    @pytest.mark.skipif(str(7699) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_refer_an_assessment_to_openstax_7699(self):
        """Able to refer to an assessment to OpenStax via Errata form.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Click the 'Report an error' link

        Expected Result:
        User is taken to the Errata form with the exercise ID prefilled
        """
        self.ps.test_updates['name'] = 'cc1.08.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.009', '7699']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='macro_economics')
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)

        # Expand all the chapters in the table of contents
        chapters = self.student.driver.find_elements_by_xpath(
            "//span[@class='title section']")
        chapters.pop(0)
        for chapter in chapters:
            chapter.click()

        # Get all sections, excluding the preface
        sections = self.student.driver.find_elements_by_xpath(
            "//a/span[@class='title']")
        sections.pop(0)

        self.student.sleep(2)

        length = len(sections)

        for num in range(length):

            sections = self.student.driver.find_elements_by_xpath(
                "//a/span[@class='title']")
            sections.pop(0)
            sections[num].click()
            self.student.sleep(3)

            if 'Introduction-to' not in self.student.current_url():
                # Jump to the Concept Coach widget and open Concept Coach
                self.student.find(
                    By.XPATH,
                    "//div[@class='jump-to-cc']/a[@class='btn']").click()
                self.student.sleep(2)
                self.student.find(
                    By.XPATH,
                    "//button[@class='btn btn-lg btn-primary']").click()
                self.student.sleep(2)

                # View summary
                breadcrumbs = self.student.driver.find_elements_by_xpath(
                    "//div[@class='task-breadcrumbs']/span")

                breadcrumbs[-1].click()
                self.student.sleep(3)

                # Verify the first question has an exercise ID
                breadcrumbs[2].click()

                self.student.find(
                    By.XPATH,
                    "//span[@class='exercise-identifier-link']/a").click()

                self.student.driver.switch_to.window(
                    self.student.driver.window_handles[-1])

                assert("google" in self.student.current_url()), \
                    'Not viewing the errata form'

                break

        self.student.sleep(5)

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

    # Case C7700 - 010 - Student | Able to work an assignment on an
    # Apple tablet device
    @pytest.mark.skipif(str(7700) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_work_an_assignment_on_an_apple_tablet_7700(self):
        """Able to work an assignment on an Apple tablet device.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        Answer is successfully submitted.
        """
        self.ps.test_updates['name'] = 'cc1.08.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.010', '7700']
        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 C7701 - 011 - Student | Able to work an assignment on an
    # Android tablet device
    @pytest.mark.skipif(str(7701) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_work_an_assignment_on_android_tablet_7701(self):
        """Able to work an assignment on an Android tablet device.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        Answer is successfully submitted.
        """
        self.ps.test_updates['name'] = 'cc1.08.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.011', '7701']
        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 C7702 - 012 - Student | Able to work an assignment on a
    # Windows tablet device
    @pytest.mark.skipif(str(7701) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_work_an_assignment_on_windows_tablet_7702(self):
        """Able to work an assignment on a WIndows tablet device.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        Answer is successfully submitted.
        """
        self.ps.test_updates['name'] = 'cc1.08.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['cc1', 'cc1.08', 'cc1.08.012', '7702']
        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 C7703 - 013 - Student | Sees product error modals
    @pytest.mark.skipif(str(7703) not in TESTS, reason='Excluded')  # NOQA
    def test_student_sees_product_error_modals_7703(self):
        """See product error modals.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 'cc1.08.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.013',
            '7703'
        ]
        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 C100131 - 014 - Student | Work a two-step assessment
    @pytest.mark.skipif(str(100131) not in TESTS, reason='Excluded')  # NOQA
    def test_student_work_a_two_step_assessment_100131(self):
        """Work a two-step assessment.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 'cc1.08.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1', 'cc1.08', 'cc1.08.014', '100131'
        ]
        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 C100132 - 015 - Student | Work a multiple-choice-only assessment
    @pytest.mark.skipif(str(100132) not in TESTS, reason='Excluded')  # NOQA
    def test_student_work_a_multiple_choice_only_assessment_100132(self):
        """Work a multiple-choice-only assessment.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 'cc1.08.015' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1', 'cc1.08', 'cc1.08.015', '100132'
        ]
        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 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
Exemple #44
0
 def setUp(self):
     """Pretest settings."""
     self.student = Student(use_env_vars=True)
     self.student.set_window_size(height=700, width=1200)
class TestWorkAHomework(unittest.TestCase):
    """"""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.student = Student(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
            self.teacher = Teacher(existing_driver=self.student.driver,
                                   use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
        else:
            self.student = Student(use_env_vars=True)
            self.teacher = Teacher(use_env_vars=True,
                                   existing_driver=self.student.driver)
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)

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

    @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded')
    def test_working_hw(self):
        '''
        Go to https://tutor-qa.openstax.org/
        Login with the account
        If the user has more than one course, select a Tutor course

        Click on a homework assignment on the list dashboard
        ***The user is presented with the first question of the homework
        assignment (t1.71.01)***

        Hover the cursor over the information icon in right corner of the
        footer
        ***The user is presented with the assignment description/instructions
        (t1.71.02)***

        [Navigate through the questions sequentially using the breadcrumbs
        until a free response question is found]
        Enter a free response into the free response text box
        ***The Answer button is activated
        (t1.71.04)***
        ***The user is presented with the next question when clicking the
        breadcrumb(t1.71.03)***

        Click on another breadcrumb to get to the next assessment
        Click back to the original assessment
        ***The free response on the original assessment is saved (t1.71.08)***

        Click 'Answer' (which should be activated)
        ***A free response answer is submitted and multiple choice is shown
        (t1.71.05)***

        Select a multiple choice answer
        ***The Submit button is activated
        (t1.71.06)***

        Click on the next breadcrumb to get to the next assessment
        Click back to the original assessment
        ***The multiple choice answer on the original assessment is saved
        (t1.71.09)***

        Click "Submit"
        ***A multiple choice answer is submitted (t1.71.07)***

        Click on the course name in the left corner of the header
        OR
        Click "Dashboard" in the user menu
        ***The user returns to dashboard and the assignment progress shows the
        number of questions answered (t1.71.10)***

        Click on the same homework assignment
        Change a multiple choice answer on an assessment
        ***The button in the lower left corner says "Saving" with a loading
        circle
        A multiple choice answer is changed on an assessment (t1.71.12)***

        Continue answering all assessments
        ***The user is presented with the completion report at the end of the
        assignment (t1.71.11,14)***
        ***A homework may have a Spaced Practice assessment toward the end
        (t1.71.16)***
        ***A homework may have a Personalized assessment toward the end
        (t1.71.17)***

        Click "Back To Dashboard"
        ***The user is returned to the dashboard (t1.71.13)***
        ***The user is returned to the dashboard and the completed homework
        shows X/X answered in the dashboard progress column (t1.71.15)***

        Expected Results:

        Corresponds to t1.71 01 --> 15
        :return:
        '''
        # t1.71.01 --> The user is presented with the first question of the
        # homework assignment
        self.teacher.login()

        target_course = self.teacher.find(
            By.XPATH,
            "//div[contains(@data-title,'College Physics with Courseware')"
            "and not(contains(@data-title,'Debshila'))]")
        # for reference later as student
        course_number = target_course.get_attribute('data-course-id')
        target_course.click()

        # IMPORTANT -- get the course number of the course that you're in -->
        # this will let you identify the course later (in case there's any
        # similarly-named courses)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=3)).strftime('%m/%d/%Y')
        # non-immediate feedback

        assignment_name = 'hw no.{0}: {1}'.format(str(randint(0, 100)),
                                                  str(today))
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"calendar-header")]')))
        self.teacher.add_assignment(
            assignment='homework',  # CHANGED THIS TOO
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {
                    'all': (begin, end)
                },
                'status': 'publish',
                'problems': {
                    '1.1': 5
                }
            })
        # check add_assignment() method for information on structuring of args
        # NOTE: exercises hard-coded to chapter 1.1 only --> might cause
        # problems
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//*[contains(@data-title,"%s")]' % assignment_name)))
        self.teacher.logout()
        assert('https://tutor-qa.openstax.org' in self.teacher.current_url()),\
            'NOT BACK AT TUTOR HOMEPAGE'

        self.student.login()

        self.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, "//div[contains(@data-course-id,%s)]" %
                 course_number))).click()

        assert(course_number in self.student.current_url()),\
            "Not at the desired course %s page!" % course_number

        homework = self.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[contains(text(),"%s")]' % assignment_name)))
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', homework)

        self.student.driver.execute_script('window.scrollBy(0, -80);')
        homework.click()
        self.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')))
        assert('task' in self.student.current_url()),\
            "Not currently working %s!" % assignment_name

        # t1.71.02 --> The user is presented with the assignment
        # description/instructions
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        icon = self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"homework")]' +
                 '//button[contains(@class,"task-details")]'
                 )))  # check that task-details icon is there

        ActionChains(self.student.driver).move_to_element(icon).perform()
        self.student.driver.find_element(
            By.XPATH, '//div[contains(@id,"task-details-popover")]')
        # when hovering over the icon, a popover should come up

        # t1.71.03 --> The user is presented with the next question when
        # clicking the breadcrumb
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]')))

        sections = self.student.driver.find_elements(
            By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]')
        count = 0  # by default it starts at the first exercises

        sections[count + 1].click()
        self.student.driver.find_element(
            By.XPATH, '//div[@data-question-number="%s"]' % str(count + 2))
        self.student.sleep(1)
        sections[count].click()

        # t1.71.04
        # sections is a list of all the breadcrumbs in the homework
        answer_text = 'hello'

        while (True):
            try:
                element = self.student.driver.find_element(
                    By.TAG_NAME, 'textarea')
                for i in answer_text:
                    element.send_keys(i)
                answer_btn = self.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH,
                         '//button[contains(@class,"btn-primary")]')))

                if answer_btn.get_attribute("disabled") is None:
                    # if the answer button is activated, then you can move on
                    break
            except:
                count += 1
                if count >= len(sections):
                    print('no questions in this homework with free response')
                    raise Exception
                sections[count].click()

        # t1.71.08 --> The free response on the original assessment is saved
        # currently this test might not always work
        if count == len(sections) - 1:
            increment = -1
        else:
            increment = 1

        # because of a bug that doesn't allow saving when navigating to review
        # questions
        ###
        print('count', count)
        sections[count + increment].click()
        self.student.sleep(1)
        sections[count].click()
        self.student.driver.find_element(
            By.XPATH, '//textarea[text()= "%s"]' % answer_text)

        # t1.71.05 --> A free response answer is submitted and multiple choice
        # is shown
        self.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH,
                 '//button[contains(@class,"btn-primary")]'))).click()
        # this should answer the free response question

        # print('about to get multiple choice')

        # WHAT DO WE DO IF WE DON'T GET TO A FREE CHOICE QUESTION UNTIL WE'RE
        # AT THE LAST QUESTION?
        mc_choices = self.wait.until(
            expect.presence_of_all_elements_located(
                (By.XPATH, '//div[contains(@class,"answers-answer")]')))

        # print('got list of all multiple choice')
        # gives list of all the possible multiple choice options
        answer_ind = 0  # we are by default picking the first option

        mc_choices[answer_ind].click()

        # gives list of all the possible multiple choice options
        print(mc_choices[answer_ind].get_attribute('class'))
        children = mc_choices[answer_ind].find_elements(By.XPATH, './/label')
        print(len(children))
        print(children[0].get_attribute('class'))

        # t1.71.09 --> The multiple choice answer on the original assessment is
        # saved check that multiple choice answer saved
        sections[count + increment].click()
        sections[count].click()
        mc_choices = self.wait.until(
            expect.presence_of_all_elements_located(
                (By.XPATH, '//div[contains(@class,"answers-answer")]')))
        # mc_choices reassigned to get rid of stale elements
        curr_choice_status = mc_choices[answer_ind].get_attribute('class')
        assert('answer-checked' in curr_choice_status),\
            'Selected answer was not saved upon navigating breadcrumbs'
        # checking that the answer that we selected is registered as checked

        # t1.71.06 --> The Submit button is activated
        print('got here')
        self.student.driver.execute_script('window.scrollBy(0, -150);')
        submit_btn = self.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"continue btn")]')))

        # t1.71.07 --> A multiple choice answer is submitted

        submit_btn.click()
        self.student.driver.find_element(
            By.XPATH, '//div[@data-question-number="%s"]' % str(count + 2))
        # next element will be two more than the offset index of the current
        # problem

        # t1.71.10 --> The user returns to dashboard and the assignment
        # progress shows the number of questions answered
        # WHERE IS THIS GONNA START? WILL IT START AFTER THE FIRST QUESTION?
        # VERIFY THAT ALL THE TESTS BEFORE THIS END ON THE FIRST QUESTION
        # DOES THIS TEST RUN ANY RISK OF OVERSHOOTING?
        # AS FOR T1.71.16, HOW DO YOU VERIFY THAT THE REVIEW QUESTIONS COMES

        stop_point = len(sections) // 2
        print('stop point', stop_point)
        sections[0].click()
        self.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')))

        for q in range(stop_point):
            try:
                # if the question is two part must answer free response to get
                # to mc
                element = self.student.driver.find_element(
                    By.TAG_NAME, 'textarea')
                answer_text = "hello"
                for i in answer_text:
                    element.send_keys(i)
                self.wait.until(
                    expect.visibility_of_element_located((
                        By.XPATH,
                        '//button[contains(@class,"continue btn")]'))).click()
            except:
                pass
            # answer the multiple choice portion
            self.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[contains(@class,"question-stem")]')))
            mc_answer = self.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[contains(@class,"answer-letter")]')))
            print('THis is the choice' + mc_answer.text)
            print('this section' + str(q))
            # self.student.driver.execute_script('window.scrollBy(0, 0);')
            # Assignment.scroll_to(self.student.driver, mc_answer)
            self.student.driver.execute_script(
                'return arguments[0].scrollIntoView();', mc_answer)

            mc_answer.click()
            # pass in the case that the answer is already selected

            self.wait.until(
                expect.element_to_be_clickable(
                    (By.XPATH, '//button[contains(@class,"continue btn")]'
                     ))).click()  # click to submit

        # curr_question_num = int(self.student.find(
        # By.XPATH,"//div[contains(@class,'openstax-question')]"
        # ).get_attribute("data-question-number")
        #                         )
        # assert(curr_question_num == stop_point),Not
        # NOT SURE IF WE NEED THIS ASSERT POINT HERE --> asserts that current
        # question number is at the stop point

        curr_question_num = self.wait.until(
            expect.presence_of_element_located(
                (By.CSS_SELECTOR,
                 '.openstax-question'))).get_attribute('data-question-number')
        assert(str(stop_point+1) in curr_question_num),\
            'Not on the question after the designated stop point'

        self.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//a[contains(@class,"course-name")]'))).click()
        # brings you back to the class page

        # T1.71.11 --> The user is presented with the completion report at the
        # end of the assignment
        # Verify the assignment progress changed.
        # - this is supposed to answer all the questions
        # test that partial completion report does show on the course home
        locator = '//div[contains(text(),"%s")]/..//span' % assignment_name
        print('locator,' + locator)
        partial_complete = self.wait.until(
            expect.presence_of_element_located((By.XPATH, locator)))
        assert("%s/%s" % (str(stop_point), str(len(sections) - 1)) in
               partial_complete.text), \
            "Partial completion report doesn't show"

        # NOTE: /.. designates the parent of an element
        homework = partial_complete.find_elements(By.XPATH, '/..')
        print(homework.get_attribute('class') + "HERE")
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', homework)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        homework.click()

        # click on the breadcrumb start from the beginning
        # this is so this test can be independent of the partial completion one
        sections = self.wait.until(
            expect.presence_of_all_elements_located(
                (By.XPATH, '//span[contains(@class,"openstax-breadcrumbs")]')))
        sections[0].click()

        for q in range(len(sections)):
            try:
                # if the question is two part must answer free response to get
                # to mc
                element = self.student.driver.find_element(
                    By.TAG_NAME, 'textarea')
                answer_text = "hello"
                for i in answer_text:
                    element.send_keys(i)
                self.wait.until(
                    expect.visibility_of_element_located(
                        (By.XPATH,
                         '//button/span[contains(text(),"Answer")]'))).click()
            except:
                pass
            if 'end' in \
                    sections[q] \
                    .find_element(By.XPATH, '//i') \
                    .get_attribute('class'):
                pass
            # answer the multiple choice  portion
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"question-stem")]')))
            element = self.student.driver.find_element(
                By.XPATH, '//div[@class="answer-letter"]')
            self.student.driver.execute_script(
                'return arguments[0].scrollIntoView();', element)
            self.student.driver.execute_script('window.scrollBy(0, -150);')
            element.click()
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//button/span[contains(text(),"Submit")]'))).click()

        self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"completed-message")]')
        self.student.driver.find_element(
            By.XPATH, '//h1[contains(text(),"You are done")]')

        # t1.71.12 --> The button in the lower left corner says "Saving" with a
        # loading circle and A multiple choice answer is changed on an
        # assessment (t1.71.12)***

        # this is expected to change a multiple choice question
        # that has already been answered
        self.student.driver.execute_script('window.scrollTo(0,0)')
        self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"course-name")]').click()
        homework = self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"homework") and ' +
            'not(contains(@class,"deleted"))]' +
            '//i[contains(@class,"icon-homework")]')
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', homework)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        homework.click()
        # reanswer mc portion
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')))
        element = self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"answers-answer") and ' +
            'not(contains(@class,"checked"))]')
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', element)

        self.student.driver.execute_script('window.scrollBy(0, -150);')
        element.click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button/span[contains(text(),"Submit")]'))).click()

        # t1.71.14 -->The user is presented with the completion report at the
        # end of the assignment (same as t1.71.11)

        # Completed homework shows "You are done" in the completion report
        self.student.find(By.XPATH, "//div[@class='completed-message']")

        # t1.71.17 -->A homework may have a Personalized assessment toward the
        # end

        # FOR PERSONALIZED LOOK UNDER PERFORMANCE FORECAST --> WEAKEST SUBJECTS

        # T1.71.16 --> A homework may have a Spaced Practice assessment toward
        # the end

        # ACCOUNTS NEED MORE HISTORY FOR THESE --> MAYBE WORK THROUGH A COUPLE
        # ASSIGNMNETS FOR THESE
        # HOW CAN YOU MAKE SURE THAT THIS STARTS WHERE YOU LEFT OFF FROM AND
        # ANSWERS FULLY THROUGH?
        # MAYBE USE A WHILE LOOP?
        # HOW DO YOU CHECK FOR REVIEW ASSIGNMENT?

        # t1.71.13 --> The user is returned to the dashboard

        self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"completed-message")]')
        self.student.driver.find_element(
            By.XPATH, "//a[contains(text(),'Back to Dashboard')]").click()
        self.student.find(By.XPATH, "//div[contains(text(),'This Week')]")

        # t1.71.15 --> The user is returned to the dashboard and the completed
        # homework
        # shows X/X answered in the dashboard progress column (t1.71.15)

        self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"homework") and ' +
            'not(contains(@class,"deleted"))]' +
            '//span[contains(text(),"%s/%s answered")]' %
            (len(sections) - 1, len(sections) - 1))
class TestViewTheListDashboard(unittest.TestCase):
    """T1.45 - View the list dashboard."""
    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)
        else:
            self.student = Student(use_env_vars=True)
        self.student.login()

    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)
        try:
            self.student.delete()
        except:
            pass

    # Case C162192 - 004 - Student | View more Performance Forecast functions
    @pytest.mark.skipif(str(162192) not in TESTS, reason='Excluded')
    def test_student_return_to_dashboard_button_162192(self):
        """
        #STEPS
        Go to https://tutor-qa.openstax.org/
        Click on the 'Login' button
        Enter the student user account [ | ] in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a Tutor course name

        Click on the user menu in the upper right corner 
        Click on "Performance Forecast"
        Click on "Return To Dashboard"
        ***The user is presented with the list dashboard.***

        Click on the user menu in the upper right corner 
        Click on "Performance Forecast"
        Scroll to the Individual Chapters section
        Click on a section bar.
        # EXPECTED RESULT 
        ***The user is presented with up to five practice assessments for that section.***


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

        # Test steps and verification assertions
        self.student.select_course(appearance='college_physics')
        self.student.page.wait_for_page_load()

        # The User is presented with the list dashboard
        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.sleep(5)
        self.student.open_user_menu()
        self.student.wait.until(
            expect.presence_of_element_located(
                (By.LINK_TEXT, 'Dashboard'))).click()

        self.student.sleep(5)

        self.student.find(By.CSS_SELECTOR, '.student-dashboard')

        # The User is presented with up to five practice assessments for that section

        self.student.open_user_menu()
        self.student.find(By.PARTIAL_LINK_TEXT, 'Performance Forecast').click()
        assert('guide' in self.student.current_url()), \
            'Not viewing performance forecast'
        self.student.find(
            By.XPATH, "//div[@class='chapter-panel']/div[@class='sections']" +
            "/div[@class='section']/button").click()

        assert('practice' in self.student.current_url()), \
            'Not presented with practice problems'

        self.student.sleep(5)
        breadcrumbs = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumb-exercise")]')
        assert(len(breadcrumbs) <= 5), \
            "more than 5 questions"

        self.ps.test_updates['passed'] = True
class TestStudentProgressViews(unittest.TestCase):
    """CC1.09 - Student Progress Views."""

    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.student.username = os.getenv('STUDENT_USER_CC')
        self.student.login()
        self.student.sleep(5)  # for CNX redirect

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

    # Case C7732 - 001 - Student | View section completion report
    @pytest.mark.skipif(str(7732) not in TESTS, reason='Excluded')
    def test_student_view_section_completion_report_7732(self):
        """View section completion report.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click on "Contents"
        Select a section
        Scroll to bottom of the section
        Click "Launch Concept Coach"
        Enter a response into the free response text box
        Click "Answer"
        Select a multiple choice answer
        Click "Submit"
        Click "Next question"
        Continue answering questions

        Expected Result:
        The user is presented with section completion report
        that shows "You're done"
        """
        self.ps.test_updates['name'] = 'cc1.09.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.09',
            'cc1.09.001',
            '7732'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.sleep(5)
        self.student.find(By.XPATH, "//button[@class='toggle btn']").click()
        self.student.sleep(3)
        self.student.find(
            By.XPATH,
            "//div/ul/li[2]/ul/li[2]/div/span[@class='name-wrapper']" +
            "/a/span[@class='title']").click()
        self.student.sleep(1)
        self.student.find(
            By.XPATH, "//div[@class='jump-to-cc']/a[@class='btn']").click()
        self.student.sleep(1)
        self.student.find(
            By.XPATH, "//button[@class='btn btn-lg btn-primary']").click()

        self.student.sleep(5)
        page = self.student.driver.page_source

        # Work through Concept Coach
        while 'or review your work below.' not in page:
            # Free response
            try:
                self.student.find(By.TAG, 'textarea').send_keys(chomsky())
                self.student.find(By.CSS_SELECTOR, 'button.continue').click()
                self.student.sleep(0.3)
            except:
                pass
            # Multiple choice
            try:
                answers = self.student.find_all(By.CSS_SELECTOR,
                                                'div.answer-letter')
                if not isinstance(answers, list):
                    Assignment.scroll_to(self.student.driver, answers)
                    answers.click()
                else:
                    Assignment.scroll_to(self.student.driver, answers[0])
                    answers[randint(0, len(answers) - 1)].click()
                self.student.sleep(0.2)
                self.student.find(By.CSS_SELECTOR, 'button.continue').click()
                self.student.sleep(0.3)
                self.student.find(By.CSS_SELECTOR, 'button.continue').click()
                self.student.sleep(0.3)
            except:
                pass
            self.student.sleep(2)
            page = self.student.driver.page_source

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

    # Case C7733 - 002 - Student | Completion report shows the section status
    # of started and completed modules
    @pytest.mark.skipif(str(7733) not in TESTS, reason='Excluded')
    def test_student_completion_report_shows_the_section_status_of_7733(self):
        """Completion report shows the section status.

        Steps:
        Click on "Contents"
        Select a section
        Scroll to bottom of the section
        Click "Launch Concept Coach"
        Enter a response into the free response text box
        Click "Answer"
        Select a multiple choice answer
        Click "Submit"
        Click "Next question"
        Continue answering questions

        Expected Result:
        The user is presented with the completion report, which shows the
        section status of completed modules
        """
        self.ps.test_updates['name'] = 'cc1.09.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.09',
            'cc1.09.002',
            '7733'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.find(By.CSS_SELECTOR, 'div.media-nav button').click()
        self.student.sleep(1)
        self.student.find(By.XPATH, '//a[span[text()="1.2"]]').click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, 'div.jump-to-cc a').click()
        self.student.sleep(0.5)
        self.student.find(
            By.CSS_SELECTOR,
            'div.concept-coach-launcher button'
        ).click()
        try:
            self.student.find(By.XPATH, '//button[text()="Continue"]').click()
        except:
            print('Two-step message not seen.')

        # Work through Concept Coach
        page = self.student.driver.page_source
        while 'or review your work below.' not in page:
            # Free response
            try:
                self.student.find(By.TAG, 'textarea').send_keys(chomsky())
                self.student.find(By.CSS_SELECTOR, 'button.continue').click()
                self.student.sleep(0.3)
            except:
                pass
            # Multiple choice
            try:
                answers = self.student.find_all(By.CSS_SELECTOR,
                                                'div.answer-letter')
                if not isinstance(answers, list):
                    Assignment.scroll_to(self.student.driver, answers)
                    answers.click()
                else:
                    Assignment.scroll_to(self.student.driver, answers[0])
                    answers[randint(0, len(answers) - 1)].click()
                self.student.sleep(0.2)
                self.student.find(By.CSS_SELECTOR, 'button.continue').click()
                self.student.sleep(0.3)
                self.student.find(By.CSS_SELECTOR, 'button.continue').click()
                self.student.sleep(0.3)
            except:
                pass
            self.student.sleep(2)
            page = self.student.driver.page_source
        self.student.sleep(5)

        section_id = self.student.find(
            By.CSS_SELECTOR,
            'h3.chapter-section-prefix'
        ).get_attribute('data-section')
        problem_id = self.student.find(
            By.XPATH,
            '//span[contains(@data-reactid,"help-links.1")]'
        ).text

        assert(section_id == problem_id), \
            'Section ID does not match the problem ID'

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

    # Case C7735 - 003 - Student | Access the progress views at any point
    @pytest.mark.skipif(str(7735) not in TESTS, reason='Excluded')
    def test_student_access_the_progress_views_at_any_point_7735(self):
        """Able to access the progress views at any point.

        Steps:
        Click on "Contents"
        Select a section
        Scroll to bottom of the section
        Click "Launch Concept Coach"
        Click "My Progress" in the header

        Expected Result:
        The user is presented with the progress view
        """
        self.ps.test_updates['name'] = 'cc1.09.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.09',
            'cc1.09.003',
            '7735'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.find(By.CSS_SELECTOR, 'div.media-nav button').click()
        self.student.sleep(1)
        self.student.find(By.XPATH, '//a[span[text()="1.2"]]').click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, 'div.jump-to-cc a').click()
        self.student.sleep(0.5)
        self.student.find(
            By.CSS_SELECTOR,
            'div.concept-coach-launcher button'
        ).click()
        self.student.sleep(2)
        try:
            self.student.find(By.XPATH, '//button[text()="Continue"]').click()
        except:
            print('Two-step message not seen.')
        self.student.find(By.LINK_TEXT, 'My Progress').click()

        assert('progress' in self.student.current_url()), \
            'Not viewing the My Progress page'

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

    # Case C7736 - 004 - Student | Return to current position in an assignment
    '''@pytest.mark.skipif(str(7736) not in TESTS, reason='Excluded')
    def test_student_return_to_current_position_in_an_assignment_7736(self):
        """Return to current position in an assignment.

        Steps:
        Click on "Contents"
        Select a section
        Scroll to bottom of the section
        Click "Launch Concept Coach"
        Enter a response into the free response text box
        Click "Answer"
        Select a multiple choice answer
        Click "Submit"
        Click "Next question"
        Click "Close" in the right corner of the header
        Click "Launch Concept Coach"

        Expected Result:
        The user is presented with their current position in the assignment
        """
        self.ps.test_updates['name'] = 'cc1.09.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.09',
            'cc1.09.004',
            '7736'
        ]
        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 C7737 - 005 - Student | Able to review previous modules
    @pytest.mark.skipif(str(7737) not in TESTS, reason='Excluded')
    def test_student_able_to_review_previous_modules_7737(self):
        """Able to review previous modules.

        Steps:
        Click on "Contents"
        Select a section
        Scroll to bottom of the section
        Click "Launch Concept Coach"
        Click "My Progress" in the header
        Click on the desired module under the "Previous" section

        Expected Result:
        The user is presented with a previous module
        """
        self.ps.test_updates['name'] = 'cc1.09.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.09',
            'cc1.09.005',
            '7737'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.find(By.CSS_SELECTOR, 'div.media-nav button').click()
        self.student.sleep(1)
        self.student.find(By.XPATH, '//a[span[text()="1.2"]]').click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, 'div.jump-to-cc a').click()
        self.student.sleep(0.5)
        self.student.find(
            By.CSS_SELECTOR,
            'div.concept-coach-launcher button'
        ).click()
        self.student.sleep(2)
        try:
            self.student.find(By.XPATH, '//button[text()="Continue"]').click()
        except:
            print('Two-step message not seen.')
        first = self.student.find(
            By.CSS_SELECTOR,
            'h3.chapter-section-prefix'
        ).text
        self.student.find(By.LINK_TEXT, 'My Progress').click()

        assert('progress' in self.student.current_url()), \
            'Not viewing the My Progress page'

        self.student.sleep(3)
        self.student.find(By.XPATH, '//div[@data-section="1.1"]').click()
        self.student.sleep(0.5)
        second = self.student.find(
            By.XPATH, "//h3[@class='chapter-section-prefix']").text

        assert(first != second), 'Not at new section'

        self.ps.test_updates['passed'] = True
class TestStudentsWorkAssignments(unittest.TestCase):
    """CC1.08 - Students Work Assignments."""

    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 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 C7691 - 001 - Student | Selects an exercise answer
    @pytest.mark.skipif(str(7691) not in TESTS, reason='Excluded')
    def test_student_select_an_exercise_answer_7691(self):
        """Select an exercise answer."""
        self.ps.test_updates['name'] = 'cc1.08.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.001',
            '7691'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.get(self.book_url)
        self.student.sleep(2)
        self.student.find_all(By.XPATH, '//a[@class="nav next"]')[0].click()
        self.student.page.wait_for_page_load()
        try:
            widget = self.student.find(By.ID, 'coach-wrapper')
        except:
            self.student.find_all(By.XPATH,
                                  '//a[@class="nav next"]')[0].click()
            self.student.page.wait_for_page_load()
            try:
                self.student.sleep(1)
                widget = self.student.find(By.ID, 'coach-wrapper')
            except:
                self.student.find_all(By.XPATH,
                                      '//a[@class="nav next"]')[0].click()
                self.student.page.wait_for_page_load()
                self.student.sleep(1)
                widget = self.student.find(By.ID, 'coach-wrapper')
        Assignment.scroll_to(self.student.driver, widget)
        self.student.find(
            By.XPATH,
            '//button[span[contains(text(),"Launch Concept Coach")]]'
        ).click()
        self.student.sleep(1.5)
        base_window = self.student.driver.window_handles[0]
        self.student.find(By.CSS_SELECTOR, 'div.sign-up').click()
        self.student.sleep(3)
        popup = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(popup)
        self.student.find(By.LINK_TEXT, 'Sign up').click()
        self.student.find(By.ID, 'identity-login-button').click()
        self.student.find(
            By.ID,
            'signup_first_name'
        ).send_keys(self.first_name)
        self.student.find(By.ID, 'signup_last_name').send_keys(self.last_name)
        self.student.find(By.ID, 'signup_email_address').send_keys(self.email)
        self.student.find(By.ID, 'signup_username').send_keys(self.last_name)
        self.student.find(
            By.ID,
            'signup_password'
        ).send_keys(self.student.password)
        self.student.find(
            By.ID,
            'signup_password_confirmation'
        ).send_keys(self.student.password)
        self.student.find(By.ID, 'create_account_submit').click()
        self.student.find(By.ID, 'i_agree').click()
        self.student.find(By.ID, 'agreement_submit').click()
        self.student.find(By.ID, 'i_agree').click()
        self.student.find(By.ID, 'agreement_submit').click()
        self.student.driver.switch_to_window(base_window)
        self.student.find(
            By.XPATH,
            '//input[contains(@label,"Enter the enrollment code")]'
        ).send_keys(self.code)
        self.student.sleep(2)
        self.student.find(By.CSS_SELECTOR, 'button.enroll').click()
        self.student.sleep(2)
        self.student.find(
            By.CSS_SELECTOR,
            'div.field input.form-control'
        ).send_keys(self.last_name)
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()
        self.student.sleep(5)
        try:
            self.student.find(By.XPATH, '//button[text()="Continue"]').click()
        except:
            print('Two-step message not seen.')
        self.student.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH,
                 '//div[@class="openstax-question"]//textarea')
            )
        ).send_keys(chomsky())
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[@class="answer-letter"]')
            )
        )
        answers = self.student.find_all(By.CSS_SELECTOR, 'div.answer-letter')
        answers[randint(0, len(answers) - 1)].click()
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()
        self.student.find(By.CSS_SELECTOR, 'button.async-button').click()

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

    # Case C7692 - 002 - Student | After answering an exercise feedback
    # is presented
    @pytest.mark.skipif(str(7692) not in TESTS, reason='Excluded')  # NOQA
    def test_student_after_answering_an_exercise_feedback_7692(self):
        """View section completion report.

        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 the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click the 'Answer' button
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        The correct answer is displayed and feedback is given.
        """
        self.ps.test_updates['name'] = 'cc1.08.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.002',
            '7692'
        ]
        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 C7693 - 003 - System | Assessments are from the current module
    @pytest.mark.skipif(str(7693) not in TESTS, reason='Excluded')  # NOQA
    def test_system_assessments_are_from_the_current_module_7693(self):
        """Assessment is from the current module.

        Steps:


        Expected Result:
        """
        self.ps.test_updates['name'] = 'cc1.08.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.003',
            '7693'
        ]
        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 C7694 - 004 - System | Spaced practice assessments are from
    # previously worked modules
    @pytest.mark.skipif(str(7694) not in TESTS, reason='Excluded')  # NOQA
    def test_system_spaced_practice_assessments_are_from_previo_7694(self):
        """Spaced practice assessments are from previousy worked modules.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Select a non-introductory section
        Click Jump to Concept Coach
        Click Launch Concept Coach
        Go through the assessments until you get to the Spaced Practice

        Expected Result:
        The section number beneath the text box is from a previous section
        """
        self.ps.test_updates['name'] = 'cc1.08.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.004',
            '7694'
        ]
        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 C7695 - 005 - System | Modules without assessments do not display
    # the Concept Coach widget
    @pytest.mark.skipif(str(7695) not in TESTS, reason='Excluded')  # NOQA
    def test_system_modules_without_assessments_do_not_display_7695(self):
        """Module without assessments does not display the CC widget.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Click on an introductory section

        Expected Result:
        The Concept Coach widget does not appear.
        """
        self.ps.test_updates['name'] = 'cc1.08.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.005',
            '7695'
        ]
        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 C7696 - 006 - Student | Assignment is assistive technology friendly
    @pytest.mark.skipif(str(7696) not in TESTS, reason='Excluded')  # NOQA
    def test_student_assignment_is_assistive_technology_friendly_7696(self):
        """Assignment is assistive technology friendly.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click the 'Answer' button
        Type a, b, c, or d

        Expected Result:
        A multiple choice answer matching the letter typed should be selected.
        """
        self.ps.test_updates['name'] = 'cc1.08.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.006',
            '7696'
        ]
        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 C7697 - 007 - Student | Display the assignment summary
    # after completing the assignment
    @pytest.mark.skipif(str(7697) not in TESTS, reason='Excluded')  # NOQA
    def test_student_display_the_assignment_summary_after_completin_7697(self):
        """Display the assignment summary after completing the assignment.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button
        After answering the last question, click the 'Next Question' button

        Expected Result:
        The summary is displayed
        """
        self.ps.test_updates['name'] = 'cc1.08.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.007',
            '7697'
        ]
        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 C7698 - 008 - Student | The exercise ID is visible within
    # the assessment pane
    @pytest.mark.skipif(str(7698) not in TESTS, reason='Excluded')  # NOQA
    def test_student_exercise_id_is_visible_within_the_assessment_7698(self):
        """The exercise ID is visible within the assessment pane.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the student 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 the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page

        Expected Result:
        The exercise ID is visivle on the exercise.
        """
        self.ps.test_updates['name'] = 'cc1.08.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.008',
            '7698'
        ]
        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 C7699 - 009 - Student | Able to refer an assessment to OpenStax
    # via Errata Form
    @pytest.mark.skipif(str(7699) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_refer_an_assessment_to_openstax_7699(self):
        """Able to refer to an assessment to OpenStax via Errata form.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Click the 'Report an error' link

        Expected Result:
        User is taken to the Errata form with the exercise ID prefilled
        """
        self.ps.test_updates['name'] = 'cc1.08.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.009',
            '7699'
        ]
        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 C7700 - 010 - Student | Able to work an assignment on an
    # Apple tablet device
    @pytest.mark.skipif(str(7700) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_work_an_assignment_on_an_apple_tablet_7700(self):
        """Able to work an assignment on an Apple tablet device.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        Answer is successfully submitted.
        """
        self.ps.test_updates['name'] = 'cc1.08.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.010',
            '7700'
        ]
        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 C7701 - 011 - Student | Able to work an assignment on an
    # Android tablet device
    @pytest.mark.skipif(str(7701) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_work_an_assignment_on_android_tablet_7701(self):
        """Able to work an assignment on an Android tablet device.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        Answer is successfully submitted.
        """
        self.ps.test_updates['name'] = 'cc1.08.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.011',
            '7701'
        ]
        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 C7702 - 012 - Student | Able to work an assignment on a
    # Windows tablet device
    @pytest.mark.skipif(str(7701) not in TESTS, reason='Excluded')  # NOQA
    def test_student_able_to_work_an_assignment_on_windows_tablet_7702(self):
        """Able to work an assignment on a WIndows tablet device.

        Steps:
        Click the 'Contents' button to open the table of contents
        Click on a chapter
        Click on a non-introductory section
        Click the 'Launch Concept Coach' button at the bottom of the page
        Type text into the 'Enter your response' text box
        Click a multiple choice answer
        Click the 'Submit' button

        Expected Result:
        Answer is successfully submitted.
        """
        self.ps.test_updates['name'] = 'cc1.08.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.012',
            '7702'
        ]
        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 C7703 - 013 - Student | Sees product error modals
    @pytest.mark.skipif(str(7703) not in TESTS, reason='Excluded')  # NOQA
    def test_student_sees_product_error_modals_7703(self):
        """See product error modals.

        Steps:


        Expected Result:

        """
        self.ps.test_updates['name'] = 'cc1.08.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.08',
            'cc1.08.013',
            '7703'
        ]
        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
Exemple #49
0
class TestPractice(unittest.TestCase):
    """T1.55 - Practice."""

    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
            )
        else:
            self.student = Student(
                use_env_vars=True
            )
        self.student.login()
        self.student.select_course(title='College Physics with Courseware')
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
        self.wait.until(
            expect.visibility_of_element_located((
                By.XPATH,
                '//button[contains(@class,"practice")]'
            ))
        ).click()

    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
            )
        try:
            self.student.delete()
        except:
            pass

    # Case C8297 - 001 - Student | Click on a section performance forecast bar
    # to start practice session
    @pytest.mark.skipif(str(8297) not in TESTS, reason='Excluded')
    def test_student_click_on_a_section__bar_to_start_practice_8297(self):
        """Click on a section performance forecast bar to start a practice

        Steps:
        Click one of the section performance bars from the dashboard (in setup)

        Expected Result:
        The user is taken to a practice session for the section.
        """
        self.ps.test_updates['name'] = 't1.55.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.001', '8297']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assert('practice' in self.student.current_url()), \
            'Not in practice assignment'

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

    # Case C8298 - 002 - Student | Navigate between questions using breadcrumbs
    @pytest.mark.skipif(str(8298) not in TESTS, reason='Excluded')
    def test_student_navigate_between_questions_using_breadcrumbs_8298(self):
        """Navigate between questions using the breadcrumbs.

        Steps:
        Click a breadcrumb

        Expected Result:
        The student is taken to a different question in the practice session.
        """
        self.ps.test_updates['name'] = 't1.55.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.002', '8298']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        section = sections[-2]
        section.click()
        self.student.find(
            By.XPATH,
            '//div[contains(@data-question-number,"%s")]' %
            (len(sections) - 1)
        )
        self.ps.test_updates['passed'] = True

    # Case C8299 - 003 - Student | Scrolling the window up reveals the header
    @pytest.mark.skipif(str(8299) not in TESTS, reason='Excluded')
    def test_student_scrolling_the_window_up_reveals_the_header_bar_8299(self):
        """Scrolling the window up reveals the header bar.

        Steps:
        Scroll down
        Scroll to the top of the page

        Expected Result:
        The header bar, containing the course name, OpenStax logo,
        and user menu link is visible.
        """
        self.ps.test_updates['name'] = 't1.55.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.003', '8299']
        self.ps.test_updates['passed'] = False

        # answer free response first
        # so that mc questions appear and there is enough text to scroll
        try:
            self.student.find(
                By.TAG_NAME, 'textarea').send_keys("hello")
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//button[contains(text(),"Answer")]')
                )
            ).click()
        except NoSuchElementException:
            pass
        # scroll page
        self.student.driver.execute_script("window.scrollTo(0, 100);")
        self.student.driver.execute_script("window.scrollTo(0, 0);")
        self.student.find(By.CLASS_NAME, 'ui-brand-logo')

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

    # Case C8300 - 004 - Student | Inputting a free response activates the
    # Answer button
    @pytest.mark.skipif(str(8300) not in TESTS, reason='Excluded')
    def test_student_inputting_a_free_response_activates_the_button_8300(self):
        """Inputting a free response into activates the Answer button.

        Steps:
        If there is a text box: input text
            OR
        Click on the next breadcrumb until a textbox is available

        Expected Result:
        The "Answer" button is click-able.
        """
        self.ps.test_updates['name'] = 't1.55.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.004', '8300']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        for x in range(len(sections)):
            try:
                element = self.student.find(
                    By.TAG_NAME, 'textarea')
                for i in 'hello':
                    element.send_keys(i)
                self.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH, '//button[contains(text(),"Answer")]')
                    )
                )
                break
            except NoSuchElementException:
                if x >= len(sections)-1:
                    print('no questions in this practice with free respnse')
                    raise Exception
                sections_new = self.student.find_all(
                    By.XPATH, '//span[contains(@class,"breadcrumbs")]')
                sections_new[x].click()

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

    # Case C8301 - 005 - Student | Answer a free reponse question
    @pytest.mark.skipif(str(8301) not in TESTS, reason='Excluded')
    def test_student_answer_a_free_response_question_8301(self):
        """Answer a free reponse question.

        Steps:
        If there is a text box, input text
        Click the "Answer" button

        Expected Result:
        The text box disappears and the multiple choice answer appear.
        """
        self.ps.test_updates['name'] = 't1.55.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.005', '8301']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        answer_text = "hello"
        for x in range(len(sections)):
            try:
                element = self.student.find(
                    By.TAG_NAME, 'textarea')
                for i in answer_text:
                    element.send_keys(i)
                self.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH, '//button[contains(text(),"Answer")]')
                    )
                ).click()
                break
            except NoSuchElementException:
                if x >= len(sections) - 1:
                    print('no questions in this homework with free respnse')
                    raise Exception
                sections_new = self.student.find_all(
                    By.XPATH, '//span[contains(@class,"breadcrumbs")]')
                sections_new[x].click()

        self.student.find(
            By.XPATH,
            '//div[@class="free-response" and contains(text(),"' +
            answer_text + '")]')
        self.student.find(
            By.XPATH, '//div[@class="answer-letter"]')

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

    # Case C8302 - 006 - Student | Selecting a multiple choice answer activates
    # the Submit button
    @pytest.mark.skipif(str(8302) not in TESTS, reason='Excluded')
    def test_student_selecting_a_mc_answer_activates_submit_button_8302(self):
        """Selecting a multiple choice answer activates the Submit button.

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer

        Expected Result:
        The "Submit" button can now be clicked
        """
        self.ps.test_updates['name'] = 't1.55.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.006', '8302']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(
                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(text(),"Answer")]')
                )
            ).click()
        except NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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.element_to_be_clickable(
                (By.XPATH, '//button[contains(text(),"Submit")]')
            )
        )

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

    # Case C8303 - 007 - Student | Submit the assessment
    @pytest.mark.skipif(str(8303) not in TESTS, reason='Excluded')
    def test_student_submit_the_assesment_8303(self):
        """Submit the assessment.

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer
        Click the "Submit" button

        Expected Result:
        The answer is submitted and the 'Next Question' button appears.
        """
        self.ps.test_updates['name'] = 't1.55.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.007', '8303']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(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(text(),"Answer")]')
                )
            ).click()
        except NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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[contains(text(),"Submit")]')
            )
        ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(text(),"Next Question")]')
            )
        )

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

    # Case C8304 - 008 - Student | Answer feedback is presented
    @pytest.mark.skipif(str(8304) not in TESTS, reason='Excluded')
    def test_student_answer_feedback_is_presented_8304(self):
        """Answer feedback is presented.

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer
        Click the "Submit" button

        Expected Result:
        The answer is submitted, the correct answer is displayed,
        and feedback on the answer is given.
        """
        self.ps.test_updates['name'] = 't1.55.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.008', '8304']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(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(text(),"Answer")]')
                )
            ).click()
        except NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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[contains(text(),"Submit")]')
            )
        ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//span[contains(@class,"breadcrumbs")]' +
                 '//i[contains(@class,"correct") or ' +
                 'contains(@class,"incorrect")]')
            )
        )

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

    # Case C8305 - 009 - Student | Correctness for a completed assesment is
    # displayed in the breadcrumbs
    @pytest.mark.skipif(str(8305) not in TESTS, reason='Excluded')
    def test_student_correctness_is_displayed_in_the_breadcrumbs_8305(self):
        """Correctness for a completed assessment is displayed in breadcrumbs

        Steps:
        If there is a text box, input text
        Click the "Answer" button
        Select a multiple choice answer
        Click the "Submit" button

        Expected Result:
        The correctness for the completed question is visible in the breadcrumb
        """
        self.ps.test_updates['name'] = 't1.55.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.009', '8305']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        try:
            # if the question is two part must answer free response first
            element = self.student.find(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(text(),"Answer")]')
                )
            ).click()
        except NoSuchElementException:
            pass
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )
        element = self.student.find(
            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[contains(text(),"Submit")]')
            )
        ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-feedback")]')
            )
        )

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

    # Case C8306 - 010 - Student | The assessment identification number and
    # version are visible
    @pytest.mark.skipif(str(8306) not in TESTS, reason='Excluded')
    def test_student_assesment_id_number_and_version_are_visible_8306(self):
        """The assessment id number and version are visible for each assessment

        Steps:
        Navigate through each question in the assessment

        Expected Result:
        Each question's identification number and version are visible.
        """
        self.ps.test_updates['name'] = 't1.55.0010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.010', '8306']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        text = self.student.find(
            By.XPATH,
            '//span[@class="exercise-identifier-link"]').text
        assert("ID#" in text), "ID# not displayed"
        assert("@" in text), "version not displayed"
        self.ps.test_updates['passed'] = True

    # Case C8307 - 011 - Student | Clicking on Report an error renders the
    # Assessment Errata Form and prefills the assessment
    @pytest.mark.skipif(str(8307) not in TESTS, reason='Excluded')
    def test_student_clicking_on_report_an_error_renders_form_8307(self):
        """Clicking on Report an error renders the Assessment Errata Form

        Steps:
        Click the "Report an error" link

        Expected Result:
        The user is taken to the Assessment Errata Form and the ID is prefilled
        """
        self.ps.test_updates['name'] = 't1.55.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.011', '8307']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        id_num = self.student.find(
            By.XPATH,
            '//span[@class="exercise-identifier-link"]'
        ).text.split(" |")[0]
        self.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Report an error')
            )
        ).click()
        window_with_form = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_form)
        self.student.page.wait_for_page_load()
        assert("errata" in self.student.current_url()), \
            'not taken to assesmant errat form'
        text_box = self.student.find(
            By.XPATH, '//input[@name="location"]')
        assert(id_num[4:] in text_box.get_attribute('value')), \
            'form not prefilled correctly'

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

    # Case C8308 - 012 - Student | Submit the Assessment Errata Form
    @pytest.mark.skipif(str(8308) not in TESTS, reason='Excluded')
    def test_student_submit_the_assesment_errata_form_8308(self):
        """Submit the Assessment Errata Form.

        Steps:
        Click the "Report an error" link
        Fill out the fields
        Click the "Submit" button

        Expected Result:
        The form is submitted
        """
        self.ps.test_updates['name'] = 't1.55.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.011', '8307']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'Report an error')
            )
        ).click()
        window_with_form = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_form)
        self.student.page.wait_for_page_load()
        # fill out form
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//h1[contains(text(),"Suggest a Correction")]')
            )
        )
        self.student.find(
            By.XPATH, '//input[@type="radio" and @value="Typo"]').click()
        self.student.find(
            By.XPATH,
            '//textarea[@name="detail"]'
        ).send_keys('automated qa test')
        self.student.find(
            By.XPATH, '//input[@type="submit"]').click()
        # find submitted message
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//h1[contains(text(),"Thanks for your help!")]')
            )
        )

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

    # Case C8309 - 013 - Student | End of practice shows the number of
    # assessments answered
    @pytest.mark.skipif(str(8309) not in TESTS, reason='Excluded')
    def test_student_end_of_practice_shows_the_number_answered_8309(self):
        """End of practice shows the number of assessments answered.

        Steps:
        Answer some of the assesments
        Click on the last breadcrumb

        Expected Result:
        End of practice shows the number of assessments answered
        """
        self.ps.test_updates['name'] = 't1.55.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.013', '8309']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        stop_point = len(sections)//2

        for _ in range(stop_point):
            try:
                # if the question is two part must answer free response first
                element = self.student.find(
                    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(text(),"Answer")]')
                    )
                ).click()
            except NoSuchElementException:
                pass
            # answer the mc portion
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"question-stem")]')
                )
            )
            element = self.student.find(
                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[contains(text(),"Submit")]')
                )
            ).click()
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//button[contains(text(),"Next Question")]')
                )
            ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//span[contains(@class,"breadcrumb-end")]')
            )
        ).click()
        text = self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"completed-message")]/h3')
            )
        ).text
        print(text)
        q_answered = text.lstrip("You have answered ").\
            rstrip(" questions.").split(" of ")
        assert(str(stop_point) in q_answered[0]), "error"
        assert(str(len(sections)-1) in q_answered[1]), "error"

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

    # Case C8310 - 014 - Student | Back To Dashboard button returns the user
    # to the dashboard
    @pytest.mark.skipif(str(8310) not in TESTS, reason='Excluded')
    def test_student_back_to_dashboard_button_returns_to_dashboard_8310(self):
        """Clicking the Back To Dashboard button returns user to the dashboard.

        Steps:
        Answer all the assessments
        Click the "Back To Dashboard" button

        Expected Result:
        The user is returned to the dashboard
        """
        self.ps.test_updates['name'] = 't1.55.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.55', 't1.55.014', '8310']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        sections = self.student.find_all(
            By.XPATH, '//span[contains(@class,"breadcrumbs")]')
        for _ in range(len(sections) - 1):
            try:
                # if the question is two part must answer free response first
                element = self.student.find(
                    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(text(),"Answer")]')
                    )
                ).click()
            except NoSuchElementException:
                pass
            # answer the free response portion
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"question-stem")]')
                )
            )
            element = self.student.find(
                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[contains(text(),"Submit")]')
                )
            ).click()
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//button[contains(text(),"Next Question")]')
                )
            ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(text(),"Back to Dashboard")]')
            )
        ).click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'student-dashboard ')
            )
        ).click()

        self.ps.test_updates['passed'] = True
Exemple #50
0
class TestViewTheListDashboard(unittest.TestCase):
    """T1.45 - View the list dashboard."""
    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.student.login()

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

    # Case C8268 - 001 - Student | View the assignment list
    @pytest.mark.skipif(str(8268) not in TESTS, reason='Excluded')
    def test_student_view_the_assignemnt_list_8268(self):
        """View the assignment list.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        The User is presented with their assignment list
        """
        self.ps.test_updates['name'] = 't1.45.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.001', '8268']
        self.ps.test_updates['passed'] = False

        self.student.select_course(appearance='physics')
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard'

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

    # Case C8269 - 002 - Student | View the performance forecast using the
    # dashboard button
    @pytest.mark.skipif(str(8269) not in TESTS, reason='Excluded')
    def test_student_performance_forecast_using_dashboard_button_8269(self):
        """View the performance forecast using the dashboard button.

        Steps:
        If the user has more than one course, select a Tutor course
        Click the View All Topics button

        Expected Result:
        The User is presented with their performance forecast
        """
        self.ps.test_updates['name'] = 't1.45.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.002', '8269']
        self.ps.test_updates['passed'] = False

        self.student.select_course(appearance='physics')
        performance = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button[contains(@class,"view-performance-forecast")]')))
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', performance)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        performance.click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C8270 - 003 - Student | View the performance forecast using the menu
    @pytest.mark.skipif(str(8270) not in TESTS, reason='Excluded')
    def test_student_view_performance_forecast_using_the_menu_link_8270(self):
        """View the performance forecast using the menu link.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the user menu
        Click on the Performance Forecast option

        Expected Result:
        The User is presented with their performance forecast
        """
        self.ps.test_updates['name'] = 't1.45.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.003', '8270']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'viewPerformanceForecast'))).click()
        assert('guide' in self.student.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C8271 - 004 - Student | View the assignments for the current week
    @pytest.mark.skipif(str(8271) not in TESTS, reason='Excluded')
    def test_student_view_the_assignemnts_for_the_current_week_8271(self):
        """View the assignments for the current week.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        The Assignemnts for the current week are displayed
        """
        self.ps.test_updates['name'] = 't1.45.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.004', '8271']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located((By.LINK_TEXT, 'This Week')))

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

    # Case C8272 - 005 - Student | View the upcoming assignments
    @pytest.mark.skipif(str(8272) not in TESTS, reason='Excluded')
    def test_student_view_the_upcoming_assignemnts_8272(self):
        """View the upcoming assignments.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        The Upcoming Assignemnts are displayed
        """
        self.ps.test_updates['name'] = 't1.45.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.005', '8272']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        try:
            self.student.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//div[contains(@class,"-upcoming")]')))
        except TimeoutException:
            self.student.driver.find_element(
                By.XPATH, '//div[contains(text(),"No upcoming events")]')

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

    # Case C8273 - 006 - Student | View past work
    @pytest.mark.skipif(str(8273) not in TESTS, reason='Excluded')
    def test_student_view_past_work_8273(self):
        """View past work.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the All Past Work tab

        Expected Result:
        The Past work is displayed
        """
        self.ps.test_updates['name'] = 't1.45.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.006', '8273']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        past_work = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'All Past Work')))
        past_work.click()
        assert(past_work.get_attribute('aria-selected') == 'true'),\
            'not viewing past work'

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

    # Case C8274 - 007 - Student | Check which assignments were late
    @pytest.mark.skipif(str(8274) not in TESTS, reason='Excluded')
    def test_student_check_which_assignments_were_late_8274(self):
        """Check which assignments were late.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the All Past Work tab

        Expected Result:
        Late Assignemnts have a red clock icon next to their progress status
        """
        self.ps.test_updates['name'] = 't1.45.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.007', '8274']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.LINK_TEXT, 'All Past Work'))).click()
        late = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//i[contains(@class,"info late")]')))
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', late)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        late.click()

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

    # Case C8275 - 008 - Student | View recent performance forecast topics
    @pytest.mark.skipif(str(8275) not in TESTS, reason='Excluded')
    def test_student_view_recent_performance_topics_8275(self):
        """View recent performance forecast topics.

        Steps:
        If the user has more than one course, select a Tutor course

        Expected Result:
        Recent topics are displayed on the dashboard under performance forecast
        """
        self.ps.test_updates['name'] = 't1.45.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.008', '8275']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//h2[contains(@class, "recent")]')))
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class, "guide-group")]')))

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

    # Case C8276 - 009 - Student | Open the refrence book using the dashboard
    # button
    @pytest.mark.skipif(str(8276) not in TESTS, reason='Excluded')
    def test_student_open_the_refrence_book_using_dashboard_button_8276(self):
        """Open the refrence book using the dashboard button.

        Steps:
        If the user has more than one course, select a Tutor course
        Click the Browse The Book button

        Expected Result:
        The refrence book is opened in a new tab or window
        """
        self.ps.test_updates['name'] = 't1.45.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.009', '8276']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        book = self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(@class,"view-reference-guide")]' +
                 '//div[contains(text(),"Browse the Book")]')))
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', book)
        self.student.driver.execute_script('window.scrollBy(0, -80);')
        book.click()
        window_with_book = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_book)
        assert('book' in self.student.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C8277 - 010 - Student | Open the refrence book using the menu link
    @pytest.mark.skipif(str(8277) not in TESTS, reason='Excluded')
    def test_student_open_the_refrence_book_using_the_menu_link_8277(self):
        """Open the refrence book using the menu link.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the user menu
        Click the Browse The Book option

        Expected Result:
        The refrence book is opened in a new tab or window
        """
        self.ps.test_updates['name'] = 't1.45.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.010', '8277']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.open_user_menu()
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.CLASS_NAME, 'view-reference-guide'))).click()
        window_with_book = self.student.driver.window_handles[1]
        self.student.driver.switch_to_window(window_with_book)
        assert('book' in self.student.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C8278 - 011 - Student | Click on the course name to return to the
    # dasboard
    @pytest.mark.skipif(str(8278) not in TESTS, reason='Excluded')
    def test_student_click_on_course_name_to_return_to_dashboard_8278(self):
        """Click on the course name to return to the dashboard.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the View All Topics button
        Click on the course name

        Expected Result:
        The user is returned to their dashboard
        """
        self.ps.test_updates['name'] = 't1.45.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.011', '8278']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH,
                 '//button[contains(@class,"view-performance-forecast")]'
                 ))).click()
        self.student.driver.find_element(
            By.XPATH,
            '//a[contains(@aria-describedby,"course-name-tooltip")]').click()
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard 011'

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

    # Case C8279 - 012 - Student | Click on the OpneStax logo to return to the
    # course picker
    @pytest.mark.skipif(str(8279) not in TESTS, reason='Excluded')
    def test_student_click_on_openstax_logo_return_to_course_picker_8279(self):
        """Click on the OpenStax logo to return to the course picker.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the OpenStax logo

        Expected Result:
        The user is returned to the course picker
        """
        self.ps.test_updates['name'] = 't1.45.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.012', '8279']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.select_course(appearance='physics')
        self.student.driver.find_element(
            By.XPATH, '//i[contains(@class,"ui-brand-logo")]').click()
        assert('dashboard' in self.student.current_url()), \
            'Not viewing the course picker 012'

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

    # Case C8280 - 013 - Student | Click on the course OpenStax logo to return
    # to the dasboard
    @pytest.mark.skipif(str(8280) not in TESTS, reason='Excluded')
    def test_student_click_on_openstax_logo_to_return_to_dashboard_8280(self):
        """Click on the OpenStax logo to return to the dashboard.

        Steps:
        If the user has more than one course, select a Tutor course
        Click on the View All Topics button
        Click on the OpenStax logo

        Expected Result:
        The user is returned to their dashboard
        """
        self.ps.test_updates['name'] = 't1.45.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.45', 't1.45.013', '8280']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.logout()
        student2 = Student(username=os.getenv('STUDENT_USER_ONE_COURSE'),
                           password=os.getenv('STUDENT_PASSWORD'),
                           existing_driver=self.student.driver,
                           pasta_user=self.ps,
                           capabilities=self.desired_capabilities)
        student2.login()
        student2.page.wait_for_page_load()
        student2.open_user_menu()
        student2.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[contains(text(),"Performance Forecast") ' +
                 'and @role="menuitem"]'))).click()
        self.student.driver.find_element(
            By.XPATH, '//i[contains(@class,"ui-brand-logo")]').click()
        assert('list' in self.student.current_url()), \
            'Not viewing the list dashboard 011'

        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 TestTrainingAndSupportingTeachersAndStudents(unittest.TestCase):
    """CC1.14 - Training and Supporting Teachers and Students."""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        Steps:

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

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

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

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

        Steps:

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

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

        self.ps.test_updates['passed'] = True
    def test_student_view_active_notification_112521(self):
        """View an active system notification.

        Steps:

        Expected Result: //div[@class='notification system']/span

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

        # Test steps and verification assertions

        # Create notification
        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,
                        "//input[@id='message']").send_keys('automated test')

        self.admin.driver.find_elements_by_xpath(
            "//input[@class='btn btn-default']")[0].click()

        self.admin.sleep(5)

        # View notification as student
        student = Student(use_env_vars=True)
        student.login()
        student.select_course(appearance='physics')
        student.sleep(10)
        notifs = student.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

        student.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 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