def test_admin_distribute_access_codes_for_the_course_7773(self):
        """Distribute access codes for the teacher's course.

        Steps:
        CC approves a faculty.
        Login as admin
        Click on user menu
        Click on Admin
        Click on Salesforce tab
        Click on import [Do not check the box]
        This will automatically create a course for the teacher created.
        Email is sent to the email id used when signing up with
            the unique course URL.

        Expected Result:
        Instructors are emailed the unique course url to the address provided
        when they signed up.
        """
        self.ps.test_updates['name'] = 'cc1.01.023' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.01',
            'cc1.01.023',
            '7773'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        raise NotImplementedError(inspect.currentframe().f_code.co_name)
        admin = Admin(
            use_env_vars=True,
            existing_driver=self.teacher.driver,
            # pasta_user=self.ps,
            # capabilities=self.desired_capabilities
        )
        admin.login()
        admin.open_user_menu()
        admin.find(By.LINK_TEXT, 'Admin').click()
        admin.page.wait_for_page_load()
        admin.find(By.LINK_TEXT, 'Salesforce').click()
        admin.page.wait_for_page_load()
        admin.find(
            By.XPATH, '//input[@vale="Import Courses"]'
        ).click()

        self.ps.test_updates['passed'] = True
    def test_teacher_remove_the_last_instructor_from_the_course_8260(self):
        """Remove the last instructor from the course.

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

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

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

        self.ps.test_updates['passed'] = True
class TestCourseMaintenance(unittest.TestCase):
    """T1.57 - Course Maintenance."""

    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.admin.login()
        self.admin.goto_admin_control()
        self.admin.sleep(5)

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

    # Case C8311 - 001 - Admin | Import courses from Salesforece
    @pytest.mark.skipif(str(8311) not in TESTS, reason='Excluded')
    def test_admin_import_courses_from_salesforce_8311(self):
        """Import courses from Salesforce.

        Steps:
        Click on the user menu
        Click on the Admin option
        Click on Salesforce on the header
        Click on the Import Courses button

        Expected Result:

        """
        self.ps.test_updates['name'] = 't1.57.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.57', 't1.57.001', '8311']
        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 C8312 - 002 - Admin | Update Salesforce Staistics
    @pytest.mark.skipif(str(8312) not in TESTS, reason='Excluded')
    def test_admin_update_salesforce_statistice_8312(self):
        """Update Salesforce statistics.

        Steps:
        Click on the user menu
        Click on the Admin option
        Click on Salesforce on the header
        Click on Update Salesforce

        Expected Result:

        """
        self.ps.test_updates['name'] = 't1.57.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.57', 't1.57.002', '8312']
        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 C8313 - 003 - Admin | Exclude assesments from all courses
    @pytest.mark.skipif(str(8313) not in TESTS, reason='Excluded')
    def test_admin_exclude_assesments_from_all_courses_8313(self):
        """Exclude assesments from all courses.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 't1.57.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.57', 't1.57.003', '8313']
        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 C8314 - 004 - Admin | Add a system notification
    @pytest.mark.skipif(str(8314) not in TESTS, reason='Excluded')
    def test_admin_add_a_system_notification_8314(self):
        """Add a system notification.

        Steps:
        Click on the user menu
        Click on the Admin option
        Click on System Setting on the header
        Click on the Notifications option
        Enter a notification into the New Notification text box
        Click on the Add button

        Expected Result:
        A system notification is added
        """
        self.ps.test_updates['name'] = 't1.57.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.57', 't1.57.004', '8314']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'System Setting')
            )
        ).click()
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Notifications')
            )
        ).click()
        self.admin.sleep(5)

        self.admin.find(By.XPATH, "//input[@id='new_message']").send_keys(
            'automated test')

        self.admin.find(By.XPATH, "//input[@class='btn btn-default']").click()

        self.admin.sleep(5)

        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

    # Case C8315 - 005 - Admin | Delete a system notification
    @pytest.mark.skipif(str(8315) not in TESTS, reason='Excluded')
    def test_admin_delete_a_system_notification_8315(self):
        """Delete a system notification.

        Steps:
        Click on the user menu
        Click on the Admin option
        Click on System Setting on the header
        Click on the Notifications option
        Click on the Remove button next to a notification
        Click OK on the dialouge box

        Expected Result:
        A system notification is deleted
        """
        self.ps.test_updates['name'] = 't1.57.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.57', 't1.57.005', '8315']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'System Setting')
            )
        ).click()
        self.admin.wait.until(
            expect.visibility_of_element_located(
                (By.PARTIAL_LINK_TEXT, 'Notifications')
            )
        ).click()
        self.admin.sleep(5)

        self.admin.find(By.XPATH, "//input[@id='new_message']").send_keys(
            'automated test')

        self.admin.find(By.XPATH, "//input[@class='btn btn-default']").click()

        self.admin.sleep(5)

        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()
                break

        deleted = True

        notif = self.admin.driver.find_elements_by_xpath(
            "//div[@class='col-xs-12']")

        for n in notif:
            if n.text.find('automated test') >= 0:
                deleted = False
                break

        if deleted:
            self.ps.test_updates['passed'] = True
class TestOpenStaxMetrics(unittest.TestCase):
    """CC1.15 - OpenStax Metrics."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.admin = Admin(
                use_env_vars=True,
                pasta_user=self.ps,
                capabilities=self.desired_capabilities
            )
        else:
            self.admin = Admin(
                use_env_vars=True,
            )

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

    # Case C7608 - 001 - Admin | View a report of enrolled students by course
    @pytest.mark.skipif(str(7608) not in TESTS, reason='Excluded')
    def test_admin_view_a_report_of_enrolled_students_by_course_7608(self):
        """View a report of enrolled students by course.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the admin user account in the username and password text boxes
        Click on the 'Sign in' button
        Click on the 'Admin' button from the user menu
        Open the drop down menu by clicking 'Course Organization'
        Click the 'Courses' option
        Click the 'List Students' button for the chosen course

        Expected Result:
        List of students for chosen course is displayed
        """
        self.ps.test_updates['name'] = 'cc1.15.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.15',
            'cc1.15.001',
            '7608'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.admin.login()
        self.admin.open_user_menu()
        self.admin.find(
            By.LINK_TEXT, 'Admin'
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.LINK_TEXT, 'Course Organization'
        ).click()
        self.admin.find(
            By.LINK_TEXT, 'Courses'
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.LINK_TEXT, 'List Students'
        ).click()
        # assert thaken to correct page
        self.admin.find(
            By.XPATH, '//h1[contains(text(),"Students for course")]'
        )
        assert('student' in self.admin.current_url())
        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 TestUserLogin(unittest.TestCase):
    """T1.36 - User login."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            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)
        else:
            self.admin = Admin(use_env_vars=True, )
            self.content = ContentQA(
                existing_driver=self.admin.driver,
                use_env_vars=True,
            )
            self.student = Student(
                existing_driver=self.admin.driver,
                use_env_vars=True,
            )
            self.teacher = Teacher(
                existing_driver=self.admin.driver,
                use_env_vars=True,
            )

    def tearDown(self):
        """Test destructor."""
        if not LOCAL_RUN:
            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 'Log in' 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, 'Log in'))).click()
        self.admin.page.wait_for_page_load()

        self.admin.find(By.ID, 'login_username_or_email') \
            .send_keys(self.admin.username)
        self.admin.find(By.XPATH, "//input[@value='Next']").click()
        self.admin.find(By.ID, 'login_password') \
            .send_keys(self.admin.password)

        # click on the sign in button
        self.admin.find(By.XPATH, "//input[@value='Log 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 'Log in' 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.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 'Log in' 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 'Log in' 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, 'Log in'))).click()
        self.content.page.wait_for_page_load()

        self.content.find(By.ID, 'login_username_or_email') \
            .send_keys(self.content.username)
        self.content.find(By.XPATH, "//input[@value='Next']").click()
        self.content.find(By.ID, 'login_password') \
            .send_keys(self.content.password)

        # click on the sign in button
        self.content.find(By.XPATH, "//input[@value='Log 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 'Log in' 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, '//div[contains(text(),"QA Content")]'))).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 'Log in' 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,
                 '//div[contains(text(),"Content Analyst")]'))).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 'Log in' 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 'Log in' 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, 'Log in'))).click()
        self.student.page.wait_for_page_load()

        self.student.find(By.ID, 'login_username_or_email') \
            .send_keys(self.student.username)
        self.student.find(By.XPATH, "//input[@value='Next']") \
            .click()
        self.student.find(By.ID, 'login_password') \
            .send_keys(self.student.password)

        # click on the sign in button
        self.student.find(By.XPATH, "//input[@value='Log 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 'Log in' 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, 'Log in'))).click()
        self.teacher.page.wait_for_page_load()

        self.teacher.find(By.ID, 'login_username_or_email') \
            .send_keys(self.teacher.username)
        self.teacher.find(By.XPATH, "//input[@value='Next']").click()
        self.teacher.find(By.ID, 'login_password') \
            .send_keys(self.teacher.password)

        # click on the sign in button
        self.teacher.find(By.XPATH, "//input[@value='Log 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 'Log in' 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 'Log in' 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

    # Case C96962 - 012 - Content Reviewer | Log into Exercises
    @pytest.mark.skipif(str(96962) not in TESTS, reason='Excluded')
    def test_content_reviewer_log_into_exercises_96962(self):
        """Log into Exercises.

        Steps:
        Go to https://exercises-qa.openstax.org/
        Click "SIGN IN"
        Enter the Content username into "Email or username" text box
        Click "Next"
        Enter the Content password into "password" text box
        Click "Login"

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

        # Test steps and verification assertions
        self.content.driver.get("https://exercises-qa.openstax.org/")
        self.content.sleep(3)

        self.content.find(By.LINK_TEXT, "SIGN IN").click()
        self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \
            .send_keys(os.getenv('CONTENT_USER'))
        self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \
            .send_keys(Keys.RETURN)
        self.content.sleep(2)

        self.content.find(By.XPATH, "//input[@id='login_password']") \
            .send_keys(os.getenv('CONTENT_PASSWORD'))
        self.content.find(By.XPATH, "//input[@id='login_password']") \
            .send_keys(Keys.RETURN)
        self.content.sleep(3)

        self.content.find(By.LINK_TEXT, "SIGN OUT")

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

    # Case C96963 - 013 - Content Reviewer | Access Reviewer Display
    @pytest.mark.skipif(str(96963) not in TESTS, reason='Excluded')
    def test_content_reviewer_access_reviewer_display_96963(self):
        """Access Reviewer Display.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 't1.36.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.013', '96963']
        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 C96964 - 014 - Content Reviewer | Log out
    @pytest.mark.skipif(str(96964) not in TESTS, reason='Excluded')
    def test_content_reviewer_log_out_96964(self):
        """Log out.

        Steps:
        go to https://exercises-qa.openstax.org/
        Click "SIGN IN"
        Enter [content] into "Email or username" text box
        Click "Next"
        Enter [staxly16] into "password" text box
        Click "Login"
        Click "SIGN OUT"

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

        # Test steps and verification assertions
        self.content.driver.get("https://exercises-qa.openstax.org/")
        self.content.sleep(3)

        self.content.find(By.LINK_TEXT, "SIGN IN").click()
        self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \
            .send_keys(os.getenv('CONTENT_USER'))
        self.content.find(By.XPATH, "//input[@id='login_username_or_email']") \
            .send_keys(Keys.RETURN)
        self.content.sleep(2)

        self.content.find(By.XPATH, "//input[@id='login_password']") \
            .send_keys(os.getenv('CONTENT_PASSWORD'))
        self.content.find(By.XPATH, "//input[@id='login_password']") \
            .send_keys(Keys.RETURN)
        self.content.sleep(3)

        self.content.find(By.LINK_TEXT, "SIGN OUT").click()
        self.content.sleep(2)

        self.content.find(By.LINK_TEXT, "SIGN IN")

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

    # Case C96965 - 015 - Content Editor | Log into Exercises
    @pytest.mark.skipif(str(96965) not in TESTS, reason='Excluded')
    def test_content_editor_log_into_exercises_96965(self):
        """Log into Exercises.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 't1.36.015' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.015', '96965']
        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 C96962 - 016 - Content Editor | Access the Exercise Editor
    @pytest.mark.skipif(str(96966) not in TESTS, reason='Excluded')
    def test_content_editor_access_the_exercise_editor_96966(self):
        """Access the Exercise Editor.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 't1.36.016' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.016', '96966']
        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 C96967 - 017 - Content Editor | Log out
    @pytest.mark.skipif(str(96967) not in TESTS, reason='Excluded')
    def test_content_editor_log_out_96967(self):
        """Log out.

        Steps:

        Expected Result:
        """
        self.ps.test_updates['name'] = 't1.36.017' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.36', 't1.36.017', '96967']
        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 TestManageDistricsSchoolsAndCourses(unittest.TestCase):
    """T1.59 - Manage districts, schools, and courses."""
    def setUp(self):
        """Pretest settings."""
        # login as admin, go to user menu, click admin option
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.admin = Admin(use_env_vars=True,
                               pasta_user=self.ps,
                               capabilities=self.desired_capabilities)
        else:
            self.admin = Admin(use_env_vars=True, )
        self.wait = WebDriverWait(self.admin.driver, Assignment.WAIT_TIME)
        self.admin.login()
        self.admin.goto_admin_control()

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

    def test_set_course_details_admin(self):
        """
        Pre-req: "Course-Navigate"

        Log into Admin
        Click on user name for drop down
        Click on 'Admin' option in menu
        Click on 'Course Organization' for dropdown menu
        Click on 'Courses'
        Click on 'Edit'

        Type new course scholastic year into 'Year' text-book
        ***(t1.59.21)***

        Type new number into number of sections
        ***(t1.59.22)***

        Set the course start date and time under the 'Starts at' text box
        ***(t1.59.23)***

        Set the course end date and time under the 'Ends at' textbox
        ***(t1.59.24)***

        Set the course offering under the 'Catalog Offering' dropdown
        ***(t1.59.25)***

        Set the course offering appearance code under the 'Appearance Code'
        dropdown
        ***(t1.59.26)***

        Click 'Course duration'
        ***End and start dates should be displayed (t2.07.11)***

        Corresponds to...
        t1.59 21 --> 26
        :return:
        """
        # t1.59.21 --> Type new course scholastic year into 'Year' text-book

        # Setup() leaves you at the admin control
        self.admin.goto_course_list()

        # Create the course
        create_new_course = self.admin.find(By.XPATH,
                                            "//a[text()='Add Course']")

        self.admin.driver.execute_script(
            'return arguments[0].scrollIntoView();', create_new_course)

        create_new_course.click()

        self.admin.find(
            By.ID, "course_year").send_keys((Keys.DELETE * 4) +
                                            str(datetime.date.today().year))

        # t1.59.22 --> Type new number into number of sections

        self.admin.find(By.ID, "course_num_sections").send_keys((Keys.DELETE) +
                                                                str(1))

        # t1.59.23 -->Set the course start date and time under the 'Starts at'
        # text box

        self.admin.find(By.ID, "course_starts_at").click()
        self.admin.sleep(1)
        next_calendar_arrows = self.admin.find_all(
            By.XPATH, '//div[contains(@class,"datepicker")]' +
            '//button[contains(@class,"_next")]')
        # next_calendar_arrows[0].click() # have to find all because the two
        # right arrows for the
        # start and end date have identical xpath's --> doing this allows us to
        # pick the first or second

        # get the date
        right_now = datetime.datetime.now()
        hour_plus_one = str(right_now.replace(hour=right_now.hour + 1).hour)
        month_now = str(right_now.replace(month=right_now.month - 1).month)
        # months are 1 minus their actual number
        month_plus_one = str(right_now.month)
        print(right_now)
        print(month_now)
        print(hour_plus_one)
        print(month_plus_one)

        self.admin.find(
            By.XPATH, '//div[contains(@class,"calendar")]' +
            '//td[@data-date="1" and @data-month="{0}"]'.format(month_now)
        ).click()

        # Choose start date
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"timepicker")]' +
                 '//div[@data-hour="{0}"]'.format(hour_plus_one)))).click()

        # t1.59.24 --> Set the course end date and time under the 'Ends at'
        # textbox
        # Choose end date

        self.admin.find(By.ID, "course_ends_at").click()
        self.admin.sleep(1)
        next_calendar_arrows[-1].click()
        self.admin.find_all(
            By.XPATH, '//div[contains(@class,"calendar")]' +
            '//td[@data-date="1" and @data-month="{0}"]'.format(month_plus_one)
        )[-1].click()

        self.admin.sleep(5)
        # choose end time
        self.admin.find_all(
            By.XPATH, '//div[contains(@class,"timepicker")]' +
            '//div[@data-hour="{0}"]'.format(hour_plus_one))[-1].click()

        # t1.59.25 --> Set the course offering under the 'Catalog Offering'
        # dropdown

        self.admin.find(By.ID, "course_catalog_offering_id").click()
        self.admin.find(
            By.XPATH,
            '//select[@id="course_catalog_offering_id"]/option[2]').click()

        # t1.59.26 -->Set the course offering appearance code under the
        # 'Appearance Code' dropdown

        self.admin.find(By.ID, "course_appearance_code").click()
        self.admin.find(
            By.XPATH,
            '//select[@id="course_appearance_code"]/option[2]').click()
Ejemplo n.º 8
0
class TestTutorAdmin(unittest.TestCase):
    """Tutor | Teacher"""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.admin = Admin(
                use_env_vars=True,
                pasta_user=self.ps,
                capabilities=self.desired_capabilities
            )
        else:
            self.admin = Admin(
                use_env_vars=True
            )

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


    @pytest.mark.skipif(str(162255) not in TESTS, reason='Excluded')
    def test_admin_change_course_start_end_dates_162255(self):
        """
        Log in as an Admin
        Go to the course management page
        Edit a course
        Change the term and course year
        Click Save
        ***Start and end dates should reflect the new term's timeframe***

        Edit a course
        Change the Starts at date and Ends at date
        Click Save 

        Expected Result:

        ***Start and end dates are changed***

        https://trello.com/c/YuvX7DN0/25-admin-change-course-start-end-dates
        """
        
        self.ps.test_updates['name'] = 'tutor_course_settings_admin_162255' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'course_settings', 'admin', '162255']
        self.ps.test_updates['passed'] = False

        # go to courses admin page directly and log in
        URL = str(os.getenv('SERVER_URL')) + '/admin/courses'
        self.admin.login(url=URL)
        # search 'preview' in the search bar
        self.admin.find(By.CSS_SELECTOR, "#search-courses").send_keys('preview\n')
        self.admin.page.wait_for_page_load()
        pages = self.admin.find_all(By.CSS_SELECTOR, ".pagination>a")
        # go to very last page
        self.admin.scroll_to(pages[-2])
        self.admin.sleep(1)
        pages[-2].click()

        # click on Edit button for very last course
        edit = self.admin.find_all(By.XPATH, ".//*[contains(text(),'Edit')]")
        self.admin.scroll_to(edit[-1])
        edit[-1].click()
        # change year field by adding 1 
        yearfield = self.admin.find(By.CSS_SELECTOR, "#course_year")
        year = yearfield.get_attribute('value')
        newyear = str(int(year) + 1)
        yearfield.send_keys(len(year) * Keys.DELETE)
        yearfield.send_keys(newyear)

        # change start date and end date
        oldstartdatefield = self.admin.find(By.CSS_SELECTOR, "#course_starts_at")
        oldenddatefield = self.admin.find(By.CSS_SELECTOR, "#course_ends_at")  
        # get start date and end date values
        oldstartdate = oldstartdatefield.get_attribute('value')
        oldenddate = oldenddatefield.get_attribute('value')
        change = datetime.timedelta(days=400)
        # converts start date and end date values into datetime objects and adds the change
        newstartdate = datetime.datetime.strptime(
            oldstartdate,
            '%Y-%m-%d %X %Z') + change
        # converts into a string format accepted by the form
        oldstartdatefield.send_keys(
            datetime.datetime.strftime(
                newstartdate, '%Y/%m/%d %X'
                )[:-3]
            )
        # converts start date and end date values into datetime objects and adds change ( 400 days)
        newenddate = datetime.datetime.strptime(
            oldenddate, 
            '%Y-%m-%d %X %Z') + change
        # converts into a string format accepted by teh form
        # newenddate = datetime.datetime.strftime(newenddate1, '%Y/%m/%d %X')[:-3]
        oldenddatefield.send_keys(
            datetime.datetime.strftime(
                newenddate, '%Y/%m/%d %X')[:-3]
        )
        
        # saves changes
        self.admin.sleep(1)
        self.admin.find(By.CSS_SELECTOR, "#edit-save").click()
        self.admin.sleep(1)
        # updated start date and end date fields, get their values
        updatedstartdate = self.admin.find(
            By.CSS_SELECTOR, "#course_starts_at").get_attribute('value')
        updatedstartdatetime = datetime.datetime.strptime(
            updatedstartdate,
            '%Y-%m-%d %X %Z'
        )
        updatedenddate = self.admin.find(
            By.CSS_SELECTOR, 
            "#course_ends_at").get_attribute('value')
        updatedenddatetime = datetime.datetime.strptime(
            updatedenddate, 
            '%Y-%m-%d %X %Z'
        )
        
        # assert that the datetime objects I put into it are the ones in the updated field
        assert(newstartdate.isocalendar() == updatedstartdatetime.isocalendar())
        assert(newenddate.isocalendar() == updatedenddatetime.isocalendar())
        
        # change start date and end date to what it was
        yearfield = self.admin.find(By.CSS_SELECTOR, "#course_year")
        yearfield.send_keys(len(year) * Keys.DELETE)
        yearfield.send_keys(year)
        startdatefield = self.admin.find(By.CSS_SELECTOR, "#course_starts_at")
        startdatefield.send_keys(datetime.datetime.strftime(
            datetime.datetime.strptime(oldstartdate, '%Y-%m-%d %X %Z'),
            '%Y/%m/%d %X')[:-3]
        )
        enddatefield = self.admin.find(By.CSS_SELECTOR, "#course_ends_at")
        enddatefield.send_keys(datetime.datetime.strftime(
            datetime.datetime.strptime(oldenddate, '%Y-%m-%d %X %Z'),
            '%Y/%m/%d %X')[:-3]
        )
        self.admin.find(By.CSS_SELECTOR, "#edit-save").click()
        
        self.ps.test_updates['passed'] = True
    

    @pytest.mark.skipif(str(162256) not in TESTS, reason='Excluded')
    def test_notification_and_faulty_url_162256(self):
        """
        Go to tutor qa
        Log in as admin
        Click "Admin" from the user menu
        Click "System Setting" 
        Click "Notifications"
        Enter a new notification into the text box
        Click "Add"

        Log out of admin account
        Log in as a teacher
        ***An orange header with the notification pops up when you sign in***

        Go to a fake url page to test if styled error page is displayed

        Expected result:

        ***a styled error page is displayed***

        Corresponding test case: T2.18 001, 030
        """

        self.ps.test_updates['name'] = 'tutor_system_settings_admin_162256' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'system_settings', 'admin', '162256']
        self.ps.test_updates['passed'] = False

        # go to admin instance
        self.admin.login(url=os.getenv('SERVER_URL') + '/admin')
        # go to system settings, then notifications, then set a notification
        self.admin.find(By.XPATH,".//*[contains(text(),'System Setting')]").click()
        self.admin.find(By.CSS_SELECTOR,"a[href*='notification']").click()
        self.admin.find(By.CSS_SELECTOR, "#message").send_keys('test_notification')
        self.admin.find(By.CSS_SELECTOR, ".btn.btn-default").click()
        
        # logout of admin
        self.admin.find(By.XPATH,".//*[contains(text(),'admin')]").click()
        self.admin.find(By.CSS_SELECTOR, 'a[href*="logout"]').click()
        # log into teacher account
        self.admin.login(username=os.getenv('TEACHER_USER'),
            password=os.getenv('TEACHER_PASSWORD'))
        self.admin.find(By.CSS_SELECTOR, '.my-courses-item-title>a').click()
        # if popup asking how you will be using Tutor shows up
        try:
            self.admin.find(By.XPATH,
                './/*[contains(text(),"I don’t know yet")]')
        except:
            pass
        # checks if notification is there
        self.admin.wait.until(
            expect.visibility_of_element_located((
                By.XPATH,
                '//div[contains(@class,"notifications-bar")]' +
                '//span[text()="test_notification"]'
            ))
        )
        self.admin.find(
            By.XPATH,
            '//div[contains(@class,"notifications-bar")]' +
            '//span[text()="test_notification"]'
        )
        
        # log out of teacher
        self.admin.logout()
        
        # log into admin
        self.admin.login(url=os.getenv('SERVER_URL') + '/admin')
        self.admin.find(By.XPATH, '//a[text()="System Setting"]').click()
        self.admin.find(By.XPATH, '//a[text()="Notifications"]').click()
        # remove general notification
        self.admin.find(By.XPATH, '//a[text()="Remove"]').click()
        self.admin.driver.switch_to_alert().accept()
        # go to invalid website
        self.admin.get(os.getenv('SERVER_URL') + '/not_a_Real_page')
        # confirm styling of webpage
        self.admin.find(By.CSS_SELECTOR, '.invalid-page')

        self.ps.test_updates['passed'] = True
Ejemplo n.º 9
0
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 TestOpenStaxMetrics(unittest.TestCase):
    """CC1.15 - OpenStax Metrics."""

    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
        )

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

    # Case C7608 - 001 - Admin | View a report of enrolled students by course
    @pytest.mark.skipif(str(7608) not in TESTS, reason='Excluded')
    def test_admin_view_a_report_of_enrolled_students_by_course_7608(self):
        """View a report of enrolled students by course.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the admin user account in the username and password text boxes
        Click on the 'Sign in' button
        Click on the 'Admin' button from the user menu
        Open the drop down menu by clicking 'Course Organization'
        Click the 'Courses' option
        Click the 'List Students' button for the chosen course

        Expected Result:
        List of students for chosen course is displayed
        """
        self.ps.test_updates['name'] = 'cc1.15.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = [
            'cc1',
            'cc1.15',
            'cc1.15.001',
            '7608'
        ]
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.admin.login()
        self.admin.open_user_menu()
        self.admin.find(
            By.LINK_TEXT, 'Admin'
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.LINK_TEXT, 'Course Organization'
        ).click()
        self.admin.find(
            By.LINK_TEXT, 'Courses'
        ).click()
        self.admin.page.wait_for_page_load()
        self.admin.find(
            By.LINK_TEXT, 'List Students'
        ).click()
        # assert thaken to correct page
        self.admin.find(
            By.XPATH, '//h1[contains(text(),"Students for course")]'
        )
        assert('student' in self.admin.current_url())
        self.ps.test_updates['passed'] = True