Пример #1
0
class TestStaxingTutorTeacher(unittest.TestCase):
    """Staxing case tests."""

    def setUp(self):
        """Pretest settings."""
        self.teacher = Teacher(use_env_vars=True)
        self.teacher.username = os.getenv('TEACHER_USER_MULTI',
                                          self.teacher.username)
        self.teacher.set_window_size(height=700, width=1200)
        self.teacher.login()
        self.teacher.select_course(title='High School Physics')

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

    @pytest.mark.skipif(str(301) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_individual_publish(self):
        """Build reading assignments."""
        # Reading, individual periods, publish
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left = randint(5, 20)
        right = left + randint(1, 10)
        start_date_1 = self.teacher.date_string(day_delta=left)
        end_date_1 = self.teacher.date_string(day_delta=left + right)
        start_date_2 = self.teacher.date_string(day_delta=left + 1)
        end_date_2 = self.teacher.date_string(day_delta=left + right + 1)
        start_time_2 = '6:30 am'
        end_time_2 = '11:59 pm'
        start_date_3 = self.teacher.date_string(day_delta=left + 2)
        end_date_3 = self.teacher.date_string(day_delta=left + right + 2)
        reading_options = self.teacher.get_book_sections()
        reading_start = randint(0, (len(reading_options) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = reading_options[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - individual periods - ' +
                               'publish',
                'periods': {
                    'First': (start_date_1, end_date_1),
                    'Second': ((start_date_2, start_time_2),
                               (end_date_2, end_time_2)),
                    'Third': (start_date_3, end_date_3),
                },
                'reading_list': reading_list,
                'status': 'publish',
                'break_point': None,
            }
        )
        assert('courses' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(
            By.XPATH,
            '//label[text()="%s"]' % assignment_title
        )
        time.sleep(5.0)
        assert(reading), '%s not publishing on %s' % (assignment_title,
                                                      end_date_3)

    @pytest.mark.skipif(str(302) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_all_publish(self):
        """Build reading assignments."""
        # Reading, all periods, publish
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left = randint(5, 20)
        right = left + randint(1, 10)
        start_date_1 = self.teacher.date_string(day_delta=left)
        end_date_1 = self.teacher.date_string(day_delta=left + right)
        start_date_2 = self.teacher.date_string(day_delta=left + 1)
        end_date_2 = self.teacher.date_string(day_delta=left + right + 1)
        reading_options = self.teacher.get_book_sections()
        reading_start = randint(0, (len(reading_options) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = reading_options[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - all periods - publish',
                'periods': {
                    'First': (start_date_1, end_date_1),
                    'all': (start_date_2, end_date_2),
                },
                'reading_list': reading_list,
                'status': 'publish',
                'break_point': None,
            }
        )
        assert('courses' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(
            By.XPATH,
            '//label[text()="%s"]' % assignment_title
        )
        time.sleep(5.0)
        assert(reading), '%s not publishing on %s' % (assignment_title,
                                                      end_date_2)

    @pytest.mark.skipif(str(303) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_individual_draft(self):
        """Build reading assignments."""
        # Reading, individual periods, draft
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left = randint(5, 20)
        right = left + randint(1, 10)
        start_date_1 = self.teacher.date_string(day_delta=left)
        end_date_1 = self.teacher.date_string(day_delta=left + right)
        start_date_2 = self.teacher.date_string(day_delta=left + 1)
        end_date_2 = self.teacher.date_string(day_delta=left + right + 1)
        start_date_3 = self.teacher.date_string(day_delta=left + 2)
        end_date_3 = self.teacher.date_string(day_delta=left + right + 2)
        reading_options = self.teacher.get_book_sections()
        reading_start = randint(0, (len(reading_options) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = reading_options[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - individual periods ' +
                               '- draft',
                'periods': {
                    'First': (start_date_1, end_date_1),
                    'Second': (start_date_2, end_date_2),
                    'Third': (start_date_3, end_date_3),
                },
                'reading_list': reading_list,
                'status': 'draft',
                'break_point': None,
            }
        )
        assert('courses' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(
            By.XPATH,
            '//label[text()="%s"]' % assignment_title
        )
        time.sleep(5.0)
        assert(reading), '%s not publishing on %s' % (assignment_title,
                                                      end_date_3)

    @pytest.mark.skipif(str(304) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_all_draft(self):
        """Build reading assignments."""
        # Reading, all periods, draft
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left = randint(5, 20)
        right = left + randint(1, 10)
        start_date_1 = self.teacher.date_string(day_delta=left)
        end_date_1 = self.teacher.date_string(day_delta=left + right)
        reading_options = self.teacher.get_book_sections()
        reading_start = randint(0, (len(reading_options) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = reading_options[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - all periods - draft',
                'periods': {
                    'all': (start_date_1, end_date_1),
                },
                'reading_list': reading_list,
                'status': 'draft',
                'break_point': None,
            }
        )
        assert('courses' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(
            By.XPATH,
            '//label[text()="%s"]' % assignment_title
        )
        time.sleep(5.0)
        assert(reading), '%s not publishing on %s' % (assignment_title,
                                                      end_date_1)

    @pytest.mark.skipif(str(305) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_one_cancel(self):
        """Build reading assignments."""
        # Reading, one period, cancel
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left = randint(5, 20)
        right = left + randint(1, 10)
        start_date_1 = self.teacher.date_string(day_delta=left)
        end_date_1 = self.teacher.date_string(day_delta=left + right)
        reading_options = self.teacher.get_book_sections()
        reading_start = randint(0, (len(reading_options) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = reading_options[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - cancel',
                'periods': {
                    'First': (start_date_1, end_date_1),
                },
                'reading_list': reading_list,
                'status': 'cancel',
                'break_point': None,
            }
        )
        assert('courses' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        time.sleep(5.0)
        with pytest.raises(NoSuchElementException):
            self.teacher.find(
                By.XPATH,
                '//label[text()="%s"]' % assignment_title
            )

    @pytest.mark.skipif(str(306) not in TESTS, reason='Excluded')
    def test_change_assignment(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(307) not in TESTS, reason='Excluded')
    def test_delete_assignment(self):
        """No test placeholder."""
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        start_date = self.teacher.date_string(day_delta=1)
        end_date = self.teacher.date_string(day_delta=3)
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'periods': {
                    'all': (start_date, end_date),
                },
                'reading_list': ['1', '1.1'],
                'status': 'draft',
                'break_point': None,
            }
        )
        assert('courses' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date)
        reading = self.teacher.find(
            By.XPATH,
            '//label[text()="%s"]' % assignment_title
        )
        time.sleep(5.0)
        assert(reading), \
            '%s not publishing on %s' % (assignment_title, end_date)
        new_date = start_date.split('/')
        new_date = '%s/%s' % (int(new_date[0]), int(new_date[1]))
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//label[@data-title="%s" and @data-opens-at="%s"]' %
                 (assignment_title, new_date))
            )
        )
        self.teacher.delete_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'periods': {
                    'all': (start_date, end_date),
                },
            }
        )
        self.teacher.rotate_calendar(end_date)
        time.sleep(5.0)
        with pytest.raises(NoSuchElementException):
            self.teacher.find(
                By.XPATH,
                '//label[text()="%s"]' % assignment_title
            )

    @pytest.mark.skipif(str(308) not in TESTS, reason='Excluded')
    def test_goto_menu_item(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(309) not in TESTS, reason='Excluded')
    def test_goto_calendar(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(310) not in TESTS, reason='Excluded')
    def test_goto_performance_forecast(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(311) not in TESTS, reason='Excluded')
    def test_goto_student_scores(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(312) not in TESTS, reason='Excluded')
    def test_goto_course_roster(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(313) not in TESTS, reason='Excluded')
    def test_goto_course_settings(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(314) not in TESTS, reason='Excluded')
    def test_add_course_section(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(315) not in TESTS, reason='Excluded')
    def test_get_enrollment_code(self):
        """No test placeholder."""
        pass
class TestCreateNewQuestionAndAssignmentTypes(unittest.TestCase):
    """T2.12 - Create New Question and Assignment Types."""
    def setUp(self):
        """Pretest settings."""

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

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

    # 14739 - 001 - Teacher | Vocabulary question is a question type
    @pytest.mark.skipif(str(14739) not in TESTS, reason='Excluded')
    def test_teacher_vocabulary_question_is_a_question_type_14739(self):
        """Vocabulary question is a question type.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher account in the username and password text boxes
        Click on the 'Sign in' button
        Click "Write a new exercise"
        Click "New Vocabulary Term"

        Expected Result:
        The user is presented with a page where a new vocabulary question can
        be created
        """
        self.ps.test_updates['name'] = 't2.12.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.001', '14739']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.get("https://exercises-qa.openstax.org/")
        # login
        self.teacher.find(
            By.XPATH,
            '//div[@id="account-bar-content"]//a[text()="Sign in"]').click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(By.ID, 'auth_key').send_keys(self.teacher.username)
        self.teacher.find(By.ID, 'password').send_keys(self.teacher.password)
        self.teacher.find(By.XPATH, '//button[text()="Sign in"]').click()
        # create new vocab
        self.teacher.page.wait_for_page_load()
        self.teacher.find(By.XPATH, '//a[@href="/exercises/new"]').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[text()="New Vocabulary Term"]'))).click()
        assert('/vocabulary/new' in self.teacher.current_url()), \
            'not at new vocab page'

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

    # 14741 - 002 - Teacher | True/False is a question type
    @pytest.mark.skipif(str(14741) not in TESTS, reason='Excluded')
    def test_teacher_truefalse_is_a_question_type_14741(self):
        """True/False is a question type.

        Steps:
        Click "Write a new exercise"
        Click on the "True/False" radio button

        Expected Result:
        The user is presented with a page where a True/False question can be
        created
        """
        self.ps.test_updates['name'] = 't2.12.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.002', '14741']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.get("https://exercises-qa.openstax.org/")
        # login
        self.teacher.find(
            By.XPATH,
            '//div[@id="account-bar-content"]//a[text()="Sign in"]').click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(By.ID, 'auth_key').send_keys(self.teacher.username)
        self.teacher.find(By.ID, 'password').send_keys(self.teacher.password)
        self.teacher.find(By.XPATH, '//button[text()="Sign in"]').click()
        # create new vocab
        self.teacher.page.wait_for_page_load()
        self.teacher.find(By.XPATH, '//a[@href="/exercises/new"]').click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//input[@label="True/False"]'))).click()
        self.teacher.find(By.XPATH, '//span[text()="True/False"]')
        self.ps.test_updates['passed'] = True

    # possibly changed implementation on site
    # no info icon found
    # 14742 - 003 - System | Display embedded videos with attribution and link
    # back to author
    @pytest.mark.skipif(str(14742) not in TESTS, reason='Excluded')
    def test_system_display_embedded_videos_with_attribution_14742(self):
        """Display embedded videos with attribution and a link back to author.

        Steps:
        Go to Tutor
        Click Login
        Sign in as student01
        Click "HS AP Physics LG"
        Click on a homework assignment
        Click through it until you get to a video
        Click on the info icon on the video

        Expected Result:
        Attribution and links are displayed
        """
        self.ps.test_updates['name'] = 't2.12.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.003', '14742']
        self.ps.test_updates['passed'] = False

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

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

    # NOT DONE
    # create hw helper still not working
    # but works for manually created assignemnt, add assignemnt commented out
    # 14743 - 004 - Teacher | Each part of a multi-part question counts as a
    # seperate problem when scored
    @pytest.mark.skipif(str(14743) not in TESTS, reason='Excluded')
    def test_teacher_each_part_of_a_multipart_question_counts_as_14743(self):
        """Multi-part questions count as seperate problems when scored.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Log in as teacher03
        Click "College Introduction to Sociology"
        Go to "Student Scores"
        Pick a homework that has multipart question
        Click "Review"

        Expected Result:
        There is a breadcrumb for each part of a multipart question
        """
        self.ps.test_updates['name'] = 't2.12.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.004', '14743']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        # create a hw with a multi part question, and gice it a randomized name
        # ID: 12061@6 is multi part
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//div[@data-appearance="intro_sociology"]' +
            '//a[not(contains(@href,"/cc-dashboard"))]').click()
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='homework',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'problems': {
                                            '1.1': ['12024@10'],
                                        },
                                        'status': 'publish',
                                    })
        self.teacher.open_user_menu()
        self.teacher.find(By.LINK_TEXT, 'Student Scores').click()
        self.teacher.page.wait_for_page_load()
        # can just click the first review because assignemnt just created
        # and should be the most recent one
        self.teacher.find(By.LINK_TEXT, 'Review').click()
        cards = self.teacher.find_all(By.XPATH,
                                      '//div[contains(@class,"card-body")]')
        questions = self.teacher.find_all(
            By.XPATH, '//div[contains(@class,"openstax-question")]')
        breadcrumbs = self.teacher.find_all(
            By.XPATH, '//span[contains(@class,"openstax-breadcrumb")]')
        assert(len(questions) == len(breadcrumbs)), \
            'breadcrumbs and questions not equal'
        assert(len(cards) < len(breadcrumbs)), \
            'multipart question card has multiple questions,' + \
            'not matching up with  breadcrumbs'

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

    # NOT DONE
    # same issue as above w/ add_homework helper
    # but works for manually created assignemnt
    # (add assignemnt gets commented out, manual assignemnt name added)
    # 14744 - 005 - Student | Each part of a multi-part question counts as a
    # seperate problem when scored
    @pytest.mark.skipif(str(14744) not in TESTS, reason='Excluded')
    def test_student_each_part_of_a_multipart_question_counts_as_14744(self):
        """Multi-part questions count as seperate problems when scored.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Log in as abarnes
        Click "College Introduction to Sociology"
        Click on a homework assignment
        Go through the questions

        Expected Result:
        There is a breadcrumb for each part in the multipart question and the
        progress/score is out of the total number of questions, rather than
        counting the multipart question as one question
        """
        self.ps.test_updates['name'] = 't2.12.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.005', '14744']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        # create a hw with a multi part question, and give it a randomized name
        # ID: 12252@5 is multi part
        self.teacher.login()
        self.teacher.find(
            By.XPATH, '//div[@data-appearance="intro_sociology"]' +
            '//a[not(contains(@href,"/cc-dashboard"))]').click()
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='homework',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'problems': {
                                            '1.1': ['12024@10'],
                                        },
                                        'status': 'publish',
                                    })
        self.teacher.logout()
        # assignemnt name put here for manual testing
        # assignment_name = 'hw w/ video and multi part question'
        # login as student and go to same class
        self.student.login()
        self.teacher.find(
            By.XPATH, '//div[@data-appearance="intro_sociology"]' +
            '//a[not(contains(@href,"/cc-dashboard"))]').click()
        self.student.page.wait_for_page_load()
        # go to assignment (find my assignemnt_name)
        self.student.find(
            By.XPATH, '//a[contains(@class,"homework workable")]' +
            '//span[text()="' + assignment_name + '"]').click()
        # go through all questions
        breadcrumbs = self.teacher.find_all(
            By.XPATH, '//span[contains(@class,"openstax-breadcrumb")' +
            ' and not(contains(@class,"intro"))' +
            ' and not(contains(@class,"personalized"))'
            ' and not(contains(@class,"end"))]')
        total_questions = 0
        found_multipart = False
        i = 0
        while i < len(breadcrumbs):
            breadcrumbs[i].click()
            try:
                self.student.find(By.XPATH,
                                  '//span[text()="Multi-part question"]')
                found_multipart = True
                questions = self.teacher.find_all(
                    By.XPATH, '//div[contains(@class,"openstax-question")]')
                total_questions += len(questions)
                i += len(questions)
            except NoSuchElementException:
                i += 1
                questions = self.teacher.find_all(
                    By.XPATH, '//div[contains(@class,"openstax-question")]')
                total_questions += len(questions)
        # check that everything worked out
        assert (found_multipart), 'no multipart question found'
        assert(total_questions == len(breadcrumbs)), \
            'breadcrumbs and questions not equal'

        self.ps.test_updates['passed'] = True
class TestWorkAHomework(unittest.TestCase):
    """"""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.student = Student(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
            self.teacher = Teacher(existing_driver=self.student.driver,
                                   use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
        else:
            self.student = Student(use_env_vars=True)
            self.teacher = Teacher(use_env_vars=True,
                                   existing_driver=self.student.driver)
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        Expected Results:

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

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

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

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

        self.student.login()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # print('about to get multiple choice')

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

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

        mc_choices[answer_ind].click()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.student.driver.find_element(
            By.XPATH, '//div[contains(@class,"homework") and ' +
            'not(contains(@class,"deleted"))]' +
            '//span[contains(text(),"%s/%s answered")]' %
            (len(sections) - 1, len(sections) - 1))
Пример #4
0
class TestViewTheCalendarDashboard(unittest.TestCase):
    """T1.13 - View the calendar."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(
                use_env_vars=True,
                pasta_user=self.ps,
                capabilities=self.desired_capabilities
            )
        else:
            self.teacher = Teacher(
                use_env_vars=True
            )
        self.teacher.login()
        self.teacher.select_course(appearance='college_physics')

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

    # Case C7978 - 001 - Teacher | View the calendar dashboard
    @pytest.mark.skipif(str(7978) not in TESTS, reason='Excluded')
    def test_teacher_view_the_calendar_dashboard_7978(self):
        """View the calendar dashboard.

        Steps:
        If the user has more than one course, click on a Tutor course name

        Expected Result:
        The teacher is presented their calendar dashboard.
        """
        self.ps.test_updates['name'] = 't1.13.001' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.001', '7978']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

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

    # Case C7979 - 002 - Teacher | View student scores using dashboard button
    @pytest.mark.skipif(str(7979) not in TESTS, reason='Excluded')
    def test_teacher_view_student_scores_using_the_dashboard_button_7979(self):
        """View student scores using the dashboard button.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Student Scores' button

        Expected Result:
        The teacher is presented with the student scores
        """
        self.ps.test_updates['name'] = 't1.13.002' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.002', '7979']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.find(By.LINK_TEXT, 'Student Scores').click()
        assert('scores' in self.teacher.current_url()), \
            'Not viewing student scores'

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

    # Case C7980 - 003 - Teacher | View student scores using the user menu link
    @pytest.mark.skipif(str(7980) not in TESTS, reason='Excluded')
    def test_teacher_view_student_scores_using_the_user_menu_link_7980(self):
        """View student scores using the user menu link.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the user menu
        Click on the 'Student Scores' link

        Expected Result:
        The teacher is presented with the student scores
        """
        self.ps.test_updates['name'] = 't1.13.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.003', '7980']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.open_user_menu()
        self.teacher.find(By.CLASS_NAME, 'viewScores'). \
            find_element_by_tag_name('a'). \
            click()
        assert('scores' in self.teacher.current_url()), \
            'Not viewing the student scores'

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

    # Case C7981 - 004 - Teacher | View performance forecast using the
    # dashboard button
    @pytest.mark.skipif(str(7981) not in TESTS, reason='Excluded')
    def test_teacher_view_performance_forecast_using_dash_button_7981(self):
        """View performance forecast using the dashboard button.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Performance Forecast' button on the dashboard

        Expected Result:
        The teacher is presented with the performance forecast
        """
        self.ps.test_updates['name'] = 't1.13.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.004', '7981']
        self.ps.test_updates['passed'] = False

        self.teacher.find(By.LINK_TEXT, 'Performance Forecast').click()
        self.teacher.page.wait_for_page_load()
        assert('guide' in self.teacher.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C7982 - 005 - Teacher | View performace forecast using
    # the user menu link
    @pytest.mark.skipif(str(7982) not in TESTS, reason='Excluded')
    def test_teacher_view_performance_forecast_using_user_menu_link_7982(self):
        """View performance forecast using the user menu link.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the user menu
        Click on the 'Performance Forecast' link

        Expected Result:
        The teacher is presented with the performance forecast
        """
        self.ps.test_updates['name'] = 't1.13.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.005', '7982']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.XPATH, '//a[@data-name="viewPerformanceGuide"]'
        ).click()
        self.teacher.page.wait_for_page_load()
        assert('guide' in self.teacher.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C7983 - 006 - Teacher | View a reading assignment summary
    @pytest.mark.skipif(str(7983) not in TESTS, reason='Excluded')
    def test_teacher_view_a_reading_assignment_summary_7983(self):
        """View a reading assignment summary.

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

        Expected Result:
        The teacher is presented with the reading assignment summary
        """
        self.ps.test_updates['name'] = 't1.13.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.006', '7983']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        # create an assignment
        assignment_name = 'reading-%s' % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'reading_list': ['1.1'],
                'status': 'publish',
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )

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

    # Case C7984 - 007 - Teacher | View a homework assignment summary
    @pytest.mark.skipif(str(7984) not in TESTS, reason='Excluded')
    def test_teacher_view_a_homework_assignment_summary_7984(self):
        """View a homework assignment summary.

        Steps:
        create a homework assignment
        If the user has more than one course, click on a Tutor course name
        Click on a homework assignment on the calendar

        Expected Result:
        The teacher is presented with the homework assignment summary
        """
        self.ps.test_updates['name'] = 't1.13.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.007', '7984']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        # create an assignment
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='homework',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'problems': {'1.1': (2, 3), },
                'status': 'publish',
                'feedback': 'immediate'
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )
        self.ps.test_updates['passed'] = True

    # NOT DONE
    # Case C7985 - 008 - Teacher | View an external assignment summary
    @pytest.mark.skipif(str(7985) not in TESTS, reason='Excluded')
    def test_teacher_view_an_external_assignment_summary_7985(self):
        """View an external assignment summary.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on an external assignment on the calendar

        Expected Result:
        The teacher is presented with the external assignment summary
        """
        self.ps.test_updates['name'] = 't1.13.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.008', '7985']
        self.ps.test_updates['passed'] = False

        # create an assignment
        assignment_name = 'external-%s' % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='external',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'url': 'google.com',
                'status': 'publish'
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )

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

    # Case C7986 - 009 - Teacher | View an event summary
    @pytest.mark.skipif(str(7986) not in TESTS, reason='Excluded')
    def test_teacher_view_an_event_summary_7986(self):
        """View an event summary.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on an event on the calendar

        Expected Result:
        The teacher is presented with the event summary
        """
        self.ps.test_updates['name'] = 't1.13.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.009', '7986']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        # create an assignment
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'publish'
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )

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

    # Case C7987 - 010 - Teacher | Open the refrenece book using the dashboard
    # button
    @pytest.mark.skipif(str(7987) not in TESTS, reason='Excluded')
    def test_teacher_open_the_reference_book_using_dashboard_button_7987(self):
        """Open the refrenece book using the dashboard button.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Browse The Book'button

        Expected Result:
        The teacher is preseneted with the book in a new tab
        """
        self.ps.test_updates['name'] = 't1.13.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.010', '7987']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.driver.find_element(
            By.CSS_SELECTOR,
            '.calendar-header .view-reference-guide'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('book' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C7988 - 011 - Teacher | Open the refrenece book using user menu link
    @pytest.mark.skipif(str(7988) not in TESTS, reason='Excluded')
    def test_teacher_open_the_reference_book_using_user_menu_link_7988(self):
        """Open the refrenece book using the user menu link.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the user menu
        Click on the 'Browse the Book' link

        Expected Result:
        The teacher is presented with the book in a new tab
        """
        self.ps.test_updates['name'] = 't1.13.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.011', '7988']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.open_user_menu()
        self.teacher.find(
            By.CSS_SELECTOR,
            '.calendar-header .view-reference-guide'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('book' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C7989 - 012 - Teacher | Click on the course name to return to
    # the dashboard
    @pytest.mark.skipif(str(7989) not in TESTS, reason='Excluded')
    def test_teacher_click_course_name_to_return_to_the_dashboard_7989(self):
        """Click on the course name to return to the dashboard.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Performance Forecast' button
        Click on the course name in the header

        Expected Result:
        The teacher is presented with their calendar dashboard
        """
        self.ps.test_updates['name'] = 't1.13.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.012', '7989']
        self.ps.test_updates['passed'] = False

        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT,
            'Performance Forecast'
        ).click()
        self.teacher.find(
            By.CLASS_NAME,
            'course-name'
        ).click()
        assert('course' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

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

    # Case C7990 - 013 - Teacher | Cick on the OpenStax logo to return to
    # the course picker
    @pytest.mark.skipif(str(7990) not in TESTS, reason='Excluded')
    def test_teacher_click_openstax_logo_to_return_to_course_picker_7990(self):
        """Cick on the OpenStax logo to return to the course picker.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click in the OpenStax logo in the header

        Expected Result:
        The teacher is presented with the course picker
        """
        self.ps.test_updates['name'] = 't1.13.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.013', '7990']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        self.teacher.find(
            By.CLASS_NAME,
            'ui-brand-logo'
        ).click()
        assert('dashboard' in self.teacher.current_url()), \
            'Not viewing the course picker'

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

    '''
class TestCreateNewQuestionAndAssignmentTypes(unittest.TestCase):
    """T2.12 - Create New Question and Assignment Types."""

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

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

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

    # 14739 - 001 - Teacher | Vocabulary question is a question type
    @pytest.mark.skipif(str(14739) not in TESTS, reason='Excluded')
    def test_teacher_vocabulary_question_is_a_question_type_14739(self):
        """Vocabulary question is a question type.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher account in the username and password text boxes
        Click on the 'Sign in' button
        Click "Write a new exercise"
        Click "New Vocabulary Term"

        Expected Result:
        The user is presented with a page where a new vocabulary question can
        be created
        """
        self.ps.test_updates['name'] = 't2.12.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.001', '14739']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.get("https://exercises-qa.openstax.org/")
        # login
        self.teacher.find(
            By.XPATH, '//div[@id="account-bar-content"]//a[text()="Sign in"]'
        ).click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.ID, 'auth_key'
        ).send_keys(self.teacher.username)
        self.teacher.find(
            By.ID, 'password'
        ).send_keys(self.teacher.password)
        self.teacher.find(
            By.XPATH, '//button[text()="Sign in"]'
        ).click()
        # create new vocab
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.XPATH, '//a[@href="/exercises/new"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//a[text()="New Vocabulary Term"]')
            )
        ).click()
        assert('/vocabulary/new' in self.teacher.current_url()), \
            'not at new vocab page'

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

    # 14741 - 002 - Teacher | True/False is a question type
    @pytest.mark.skipif(str(14741) not in TESTS, reason='Excluded')
    def test_teacher_truefalse_is_a_question_type_14741(self):
        """True/False is a question type.

        Steps:
        Click "Write a new exercise"
        Click on the "True/False" radio button

        Expected Result:
        The user is presented with a page where a True/False question can be
        created
        """
        self.ps.test_updates['name'] = 't2.12.002' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.002', '14741']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.get("https://exercises-qa.openstax.org/")
        # login
        self.teacher.find(
            By.XPATH, '//div[@id="account-bar-content"]//a[text()="Sign in"]'
        ).click()
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.ID, 'auth_key'
        ).send_keys(self.teacher.username)
        self.teacher.find(
            By.ID, 'password'
        ).send_keys(self.teacher.password)
        self.teacher.find(
            By.XPATH, '//button[text()="Sign in"]'
        ).click()
        # create new vocab
        self.teacher.page.wait_for_page_load()
        self.teacher.find(
            By.XPATH, '//a[@href="/exercises/new"]'
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//input[@label="True/False"]')
            )
        ).click()
        self.teacher.find(
            By.XPATH, '//span[text()="True/False"]'
        )
        self.ps.test_updates['passed'] = True

    # possibly changed implementation on site
    # no info icon found
    # 14742 - 003 - System | Display embedded videos with attribution and link
    # back to author
    @pytest.mark.skipif(str(14742) not in TESTS, reason='Excluded')
    def test_system_display_embedded_videos_with_attribution_14742(self):
        """Display embedded videos with attribution and a link back to author.

        Steps:
        Go to Tutor
        Click Login
        Sign in as student01
        Click "HS AP Physics LG"
        Click on a homework assignment
        Click through it until you get to a video
        Click on the info icon on the video

        Expected Result:
        Attribution and links are displayed
        """
        self.ps.test_updates['name'] = 't2.12.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.003', '14742']
        self.ps.test_updates['passed'] = False

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

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

    # NOT DONE
    # create hw helper still not working
    # but works for manually created assignemnt, add assignemnt commented out
    # 14743 - 004 - Teacher | Each part of a multi-part question counts as a
    # seperate problem when scored
    @pytest.mark.skipif(str(14743) not in TESTS, reason='Excluded')
    def test_teacher_each_part_of_a_multipart_question_counts_as_14743(self):
        """Multi-part questions count as seperate problems when scored.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Log in as teacher03
        Click "College Introduction to Sociology"
        Go to "Student Scores"
        Pick a homework that has multipart question
        Click "Review"

        Expected Result:
        There is a breadcrumb for each part of a multipart question
        """
        self.ps.test_updates['name'] = 't2.12.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.004', '14743']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        # create a hw with a multi part question, and gice it a randomized name
        # ID: 12061@6 is multi part
        self.teacher.login()
        self.teacher.find(
            By.XPATH,
            '//div[@data-appearance="intro_sociology"]' +
            '//a[not(contains(@href,"/cc-dashboard"))]'
        ).click()
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='homework',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'problems': {'1.1': ['12024@10'], },
                'status': 'publish',
            }
        )
        self.teacher.open_user_menu()
        self.teacher.find(
            By.LINK_TEXT, 'Student Scores'
        ).click()
        self.teacher.page.wait_for_page_load()
        # can just click the first review because assignemnt just created
        # and should be the most recent one
        self.teacher.find(
            By.LINK_TEXT, 'Review'
        ).click()
        cards = self.teacher.find_all(
            By.XPATH, '//div[contains(@class,"card-body")]')
        questions = self.teacher.find_all(
            By.XPATH, '//div[contains(@class,"openstax-question")]')
        breadcrumbs = self.teacher.find_all(
            By.XPATH, '//span[contains(@class,"openstax-breadcrumb")]')
        assert(len(questions) == len(breadcrumbs)), \
            'breadcrumbs and questions not equal'
        assert(len(cards) < len(breadcrumbs)), \
            'multipart question card has multiple questions,' + \
            'not matching up with  breadcrumbs'

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

    # NOT DONE
    # same issue as above w/ add_homework helper
    # but works for manually created assignemnt
    # (add assignemnt gets commented out, manual assignemnt name added)
    # 14744 - 005 - Student | Each part of a multi-part question counts as a
    # seperate problem when scored
    @pytest.mark.skipif(str(14744) not in TESTS, reason='Excluded')
    def test_student_each_part_of_a_multipart_question_counts_as_14744(self):
        """Multi-part questions count as seperate problems when scored.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Log in as abarnes
        Click "College Introduction to Sociology"
        Click on a homework assignment
        Go through the questions

        Expected Result:
        There is a breadcrumb for each part in the multipart question and the
        progress/score is out of the total number of questions, rather than
        counting the multipart question as one question
        """
        self.ps.test_updates['name'] = 't2.12.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.12', 't2.12.005', '14744']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        # create a hw with a multi part question, and give it a randomized name
        # ID: 12252@5 is multi part
        self.teacher.login()
        self.teacher.find(
            By.XPATH,
            '//div[@data-appearance="intro_sociology"]' +
            '//a[not(contains(@href,"/cc-dashboard"))]'
        ).click()
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=100)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='homework',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'problems': {'1.1': ['12024@10'], },
                'status': 'publish',
            }
        )
        self.teacher.logout()
        # assignemnt name put here for manual testing
        # assignment_name = 'hw w/ video and multi part question'
        # login as student and go to same class
        self.student.login()
        self.teacher.find(
            By.XPATH,
            '//div[@data-appearance="intro_sociology"]' +
            '//a[not(contains(@href,"/cc-dashboard"))]'
        ).click()
        self.student.page.wait_for_page_load()
        # go to assignment (find my assignemnt_name)
        self.student.find(
            By.XPATH,
            '//a[contains(@class,"homework workable")]' +
            '//span[text()="' + assignment_name + '"]'
        ).click()
        # go through all questions
        breadcrumbs = self.teacher.find_all(
            By.XPATH,
            '//span[contains(@class,"openstax-breadcrumb")' +
            ' and not(contains(@class,"intro"))' +
            ' and not(contains(@class,"personalized"))'
            ' and not(contains(@class,"end"))]')
        total_questions = 0
        found_multipart = False
        i = 0
        while i < len(breadcrumbs):
            breadcrumbs[i].click()
            try:
                self.student.find(
                    By.XPATH, '//span[text()="Multi-part question"]')
                found_multipart = True
                questions = self.teacher.find_all(
                    By.XPATH, '//div[contains(@class,"openstax-question")]')
                total_questions += len(questions)
                i += len(questions)
            except NoSuchElementException:
                i += 1
                questions = self.teacher.find_all(
                    By.XPATH, '//div[contains(@class,"openstax-question")]')
                total_questions += len(questions)
        # check that everything worked out
        assert(found_multipart), 'no multipart question found'
        assert(total_questions == len(breadcrumbs)), \
            'breadcrumbs and questions not equal'

        self.ps.test_updates['passed'] = True
class TestWorkAHomework(unittest.TestCase):
    def setUp(self):
        """Pretest settings."""
        if not LOCAL_RUN:
            self.ps = PastaSauce()
            self.desired_capabilities['name'] = self.id()
            self.student = Student(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
            self.teacher = Teacher(existing_driver=self.student.driver,
                                   use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
        else:
            self.teacher = Teacher(use_env_vars=True)
            self.student = Student(
                use_env_vars=True,
                existing_driver=self.teacher.driver,
            )
        self.wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)

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

    def teacher_make_late_assignment(self,
                                     assignment_type="homework",
                                     course_title=None,
                                     course_no="394",
                                     assignment_name=None):
        """
        Expects that you're starting from the teacher dashboard

        Uses: datetime, time.strftime

        Makes a late assignment --> usually due within a very short
        period of time from when it was made

        :param hw_name: (str) --> name that we're gonna give the assignment
        :param assignment_type: (str) --> type of assignment we want to make
            (options: homework, reading, external, event)
        :param course_title: (str) --> identifier for the course
        :param
        :return:
        """
        # Navigate to course

        if course_title is None:  # if no specific course has been specified
            open_course_xpath = "//div[contains(@data-course-id,%s)]" % \
                course_no

        else:
            current_term = current_tutor_term()
            course_title = course_title.lower()
            open_course_xpath = '//div[contains(@data-appearance,"{0}") and ' \
                'contains(@data-term,"{1}")]//a'.format(
                    course_title,
                    current_term
                )

        # we do the above in order to ensure that the course is open right now
        target_course = self.teacher.find(By.XPATH, open_course_xpath)

        # for reference later as student
        course_number = target_course.get_attribute('data-course-id')
        print(course_number)
        target_course.click()

        #
        today_date = date.today()
        begin = (today_date + timedelta(days=0)).strftime('%m/%d/%Y')
        # begin and end dates will be the same

        if assignment_type.lower() == 'reading':
            heading = 'Read'

        if assignment_type.lower() == 'homework':
            heading = 'HW'

        if assignment_type.lower() == 'external':
            heading = 'Ext'

        if assignment_type.lower() == 'event':
            heading = 'Event'

        if assignment_name is None:
            assignment_name = '{0} no.{1}: {2}'.format(heading,
                                                       str(randint(0, 100)),
                                                       str(today_date))

        # create assignment
        new_due_time = get_new_set_time(60)

        begin_tuple = (begin, "1201am")
        end_tuple = (begin, new_due_time)
        # PROBLEM --> for some reason, the begin tuples are correct and give
        # today's date
        # but during the add assignment page, the begin date is set as tomorrow

        self.teacher.add_assignment(assignment=assignment_type,
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin_tuple, end_tuple)
                                        },
                                        'status': 'publish',
                                        'problems': {
                                            'ch1': 5
                                        },
                                        'feedback': 'non-immediate'
                                    })

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

        Click on the "All Past Work" tab on the dashboard
        Click on a homework assignment
        Expected Result
        ***The user starts a late homework assignment (t1.71.18)***

        Enter a free response into the free response text box
        Click "Answer"
        Select a multiple choice answer
        Click "Submit"
        *** A multiple choice answer is submitted (t1.71.19)***
        *** answer feedback is presented (t1.71.20) ***
        *** Correctness for a completed assessment is displayed in the
        breadcrumbs (t1.71.21)***

        Corresponds to...
        t1.71.18 --> 21
        """
        self.teacher.login()

        course_number = str(160)
        self.teacher_make_late_assignment(assignment_type='homework',
                                          course_no=course_number)

        self.teacher.logout()

        # THE STUDENT PART -->
        self.student.login()

        # t1.71.18 --> The user starts a late homework assignment

        try:
            late_icon = self.student.find(By.XPATH,
                                          "//i[contains(@class,'info late')]")
            late_icon.click()  # should direct you to homework

        except:
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//a[contains(text(),"All Past Work")]'))).click()
            homework = self.student.driver.find_element(
                By.XPATH, '//div[contains(@aria-hidden,"false")]' +
                '//div[contains(@class,"homework") and ' +
                'not(contains(@class,"deleted"))]' +
                '//span[contains(text(),"0/")]')

            self.student.driver.execute_script(
                'return arguments[0].scrollIntoView();', homework)

            homework.click()

        # t1.71.20 --> A multiple choice answer is submitted and answer
        # feedback is presented
        try:
            # if the question is two part must answer free response to get mc
            text_box = self.student.find(By.TAG_NAME, 'textarea')
            self.teacher.driver.execute_script(
                "arguments[0].scrollIntoView(true);", text_box)

            answer_text = "hello"
            for i in answer_text:
                text_box.send_keys(i)
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//button[contains(@class,"continue")]'))).click()
        except:
            pass

        mc_choice = self.student.find(By.XPATH,
                                      '//div[@class="answer-letter"]')

        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();', mc_choice)

        self.student.driver.execute_script('window.scrollBy(0, -150);')
        mc_choice.click()

        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class,"continue")]'))).click()

        try:
            # this is looking for question feedback -- though not all questions
            # might have
            self.student.find(
                By.XPATH,
                '//div[contains(@class,"question-feedback-content")]')

        except:
            correct_answer = self.student.find(
                By.XPATH, "//div[contains(@class,'disabled answer-correct')]")
            print(correct_answer)

        # t1.71.21 --> Correctness for a completed assessment is displayed in
        # the breadcrumbs
        self.student.driver.find_element(
            By.XPATH, '//span[contains(@class,"breadcrumb")]' +
            '//i[contains(@class,"correct") or contains(@class,"incorrect")]')

        # t1.71.19 --> A multiple choice answer is submitted
        self.student.driver.find_element(
            By.XPATH, '//button/span[contains(text(),"Next Question")]')
class TestCreateAReading(unittest.TestCase):
    """T1.14 - Create a Reading."""

    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(
                use_env_vars=True,
                pasta_user=self.ps,
                capabilities=self.desired_capabilities
            )
        else:
            self.teacher = Teacher(
                use_env_vars=True
            )
        self.teacher.login()
        self.teacher.select_course(appearance='college_physics')

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

    # Case C162172 001 Teacher | Add a new open event for all periods
    @pytest.mark.skipif(str(162172) not in TESTS, reason="Excluded")
    def test_teacher_add_a_new_open_event_all_periods_162172(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162172']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_001_%d' % (randint(100, 999))
        assignment = Assignment()

        # Open Add Reading page
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add event screen'

        # Find and fill in title
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'reading-title')
            )
        ).send_keys(assignment_name)

        # Fill in description
        self.teacher.find(
            By.XPATH, '//textarea[contains(@class, "form-control")]'
        ).send_keys('description')

        # Set date
        today = datetime.date.today()
        end = randint(1, 5)
        opens_on = today.strftime(
            '%m/%d/%Y')  # make the start date today so it will be open
        closes_on = (today + datetime.timedelta(days=end)) \
            .strftime('%m/%d/%Y')
        assignment.assign_periods(
            self.teacher.driver, {'all': (opens_on, closes_on)})

        # publish
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class,"-publish")]')
            )
        ).click()
        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )

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


    # Case C162173 002 Teacher | Save a draft for individual periods
    @pytest.mark.skipif(str(162173) not in TESTS, reason="Excluded")
    def test_teacher_save_a_draft_event_for_individual_periods_162173(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162173']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_002_%d' % (randint(100, 999))
        assignment = Assignment()

        # Open Add Reading page
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add readings screen'

        # Find and fill in title
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'reading-title')
            )
        ).send_keys(assignment_name)

        # Set date
        today = datetime.date.today()
        start = randint(0, 6)
        end = start + randint(1, 5)
        opens_on = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        closes_on = (today + datetime.timedelta(days=end)) \
            .strftime('%m/%d/%Y')

        # Find all individual periods
        self.teacher.find(By.ID, 'show-periods-radio').click()
        period_boxes = self.teacher.driver.find_elements(
            By.XPATH, '//input[contains(@id, "period-toggle-period")]'
        )
        period_assignment = {}
        for period in period_boxes:
            period_assignment[
                self.teacher.driver.find_element(
                    By.XPATH,
                    '//label[contains(@for, "%s")]' % period.get_attribute(
                        'id')).text
            ] = (opens_on, closes_on)

        assignment.assign_periods(self.teacher.driver, period_assignment)

        # Save as draft
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'builder-draft-button')
            )
        ).click()

        # Check if the draft is on the dashboard
        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )

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


    # Case C162174 003 Teacher | Create and publish a new unopened assignment from calendar
    @pytest.mark.skipif(str(162174) not in TESTS, reason="Excluded")
    def test_teacher_create_and_publish_new_unopened_event_from_calendar_162174(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162174']
        self.ps.test_updates['passed'] = False
        # Test steps and verification assertions
        calendar_date = self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//div[contains(@class,"Day--upcoming")]')
            )
        )
        self.teacher.driver.execute_script(
            'return arguments[0].scrollIntoView();',
            calendar_date
        )
        self.teacher.sleep(1)
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(calendar_date)
        actions.move_by_offset(0, -35)
        actions.click()
        actions.move_by_offset(30, 105)
        actions.click()
        actions.perform()

        assert ('event/new' in self.teacher.current_url()), \
            'not at Add Event page'

        assignment_name = 'event_003_%d' % (randint(100, 999))
        assignment = Assignment()

        # Find and fill in title
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'reading-title')
            )
        ).send_keys(assignment_name)

        # Fill in description
        self.teacher.find(
            By.XPATH,
            '//div[contains(@class,"assignment-description")]' +
            '//textarea[contains(@class,"form-control")]'
        ).send_keys('description')
        # or change it to span .assignment-description > .form-control

        # Set date
        today = datetime.date.today()
        start = randint(1, 5)
        end = start + randint(1, 5)

        # the open date should be in the future for the assignment to be unopened
        opens_on = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        closes_on = (today + datetime.timedelta(days=end)) \
            .strftime('%m/%d/%Y')
        assignment.assign_periods(
            self.teacher.driver, {'all': (opens_on, closes_on)})

        # Publish
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class, "-publish")]')
            )
        ).click()
        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name))

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


    # Case C162175 004 Teacher | Publish a draft event
    @pytest.mark.skipif(str(162175) not in TESTS, reason="Excluded")
    def test_teacher_publish_a_draft_event_162175(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162175']

        self.ps.test_updates['passed'] = False
        # Test steps and verification assertions
        assignment_name = 'event_004_%s' % randint(100, 999)
        today = datetime.date.today()
        start = randint(0, 6)
        finish = start + randint(1, 5)
        begin = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()

        # Publish the draft assignment
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class,"-publish")]')
            )
        ).click()

        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(assignment_name)
            )

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


    # Case C162176 005 Teacher | Cancel a new event before making changes
    @pytest.mark.skipif(str(162176) not in TESTS, reason="Excluded")
    def test_teacher_cancel_a_new_event_before_changes_162176(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162176']
        self.ps.test_updates['passed'] = False

        # Open "Add Event" page
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add event screen'

        # Cancel a reading with "Cancel" button
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'builder-cancel-button')
            )
        ).click()
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling event'

        # Open "Add Event" page
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add event screen'

        # Cancel an event with "X" button
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"openstax-close-x")]')
            )
        ).click()
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling event'

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


    # Case C162177 006 Teacher | Cancel a new event after making changes
    @pytest.mark.skipif(str(162177) not in TESTS, reason="Excluded")
    def test_teacher_cancel_a_new_event_after_changes_162177(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162177']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_006_%d' % (randint(100, 999))

        # Open "Add Event" page
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add Event screen'

        # Add title
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'reading-title')
            )
        ).send_keys(assignment_name)
        sleep(1)

        # Cancel with "Cancel" button
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'builder-cancel-button')
            )
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"ok")]')
            )
        ).click()

        # Check if back at user dashboard
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling Event'

        # Open "Add Event" page
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add Event screen'

        # Add title
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'reading-title')
            )
        ).send_keys(assignment_name)

        # Cancel with "X" button
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"openstax-close-x")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class,"ok")]')
            )
        ).click()
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling Event'

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


    # Case C162178 007 Teacher | Cancel a draft event before making changes
    @pytest.mark.skipif(str(162178) not in TESTS, reason="Excluded")
    def test_teacher_cancel_a_draft_event_before_changes_162178(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162178']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name_1 = 'event_007_%s' % randint(100, 500)
        assignment_name_2 = 'event_007_%s' % randint(500, 999)

        today = datetime.date.today()
        finish = randint(1, 5)
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create a draft assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name_1,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name_1)
        ).click()
        sleep(1)

        # Cancel with "Cancel" button
        cancel_button = self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'builder-cancel-button')
            )
        )
        self.teacher.scroll_to(cancel_button)
        cancel_button.click()

        # Check if teacher is taken to user dashboard
        self.teacher.page.wait_for_page_load()
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling Event'

        # Add a draft Event
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name_2,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name_2)
        ).click()
        sleep(1)

        # Cancel with "X" button
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"openstax-close-x")]')
            )
        ).click()

        # Check if the teacher is back to user dashboard
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling Event'

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


    # Case C162179 008 Teacher | Cancel a draft event after making changes
    @pytest.mark.skipif(str(162179) not in TESTS, reason="Excluded")
    def test_teacher_cancel_a_draft_event_after_changes_162179(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162179']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name_1 = 'event_008_%s' % randint(100, 500)
        assignment_name_2 = 'event_008_%s' % randint(500, 999)

        today = datetime.date.today()
        finish = randint(1, 5)
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create a draft assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name_1,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name_1)
        ).click()
        sleep(1)

        # Edit the assignment
        self.teacher.find(
            By.ID, "reading-title"
        ).send_keys('changed')

        # Cancel with "Cancel" button
        cancel_button = self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'builder-cancel-button')
            )
        )
        self.teacher.scroll_to(cancel_button)
        cancel_button.click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"ok")]')
            )
        ).click()

        # Check if teacher is taken to user dashboard
        self.teacher.page.wait_for_page_load()
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling Event'

        # Create a draft assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name_2,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name_2)
        ).click()
        sleep(1)

        # Edit the assignment
        self.teacher.find(
            By.ID, "reading-title"
        ).send_keys('changed')

        # Cancel with "X" button
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"openstax-close-x")]')
            )
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"ok")]')
            )
        ).click()

        # Check if the teacher is back to user dashboard
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling Event'

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


    # Case C162180 009 Teacher | Attempt to save or publish an event with blank required fields
    @pytest.mark.skipif(str(162180) not in TESTS, reason="Excluded")
    def test_teacher_attempt_to_save_or_publish_events_with_blank_required_fields_162180(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162180']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add Event screen'

        # Publish without filling in any fields
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class,"-publish")]')
            )
        ).click()

        # Required field reminder
        self.teacher.find(
            By.XPATH, '//div[contains(text(),"Required field")]')
        assert ('event' in self.teacher.current_url()), \
            'went back to calendar even though required fields were left blank'

        # Refresh the page
        self.teacher.driver.refresh()
        sleep(3)

        # Save without filling in any fields
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//button[contains(@class, "save")]')
            )
        ).click()

        # Required field reminder
        self.teacher.find(
            By.XPATH, '//div[contains(text(),"Required field")]')
        assert ('event' in self.teacher.current_url()), \
            'went back to calendar even though required fields were left blank'

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


    # Case C162181 010 Teacher | Delete a draft event
    @pytest.mark.skipif(str(162181) not in TESTS, reason="Excluded")
    def test_teacher_delete_a_draft_event_162181(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162181']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_010_%s' % randint(100, 500)

        today = datetime.date.today()
        finish = randint(1, 5)
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create a draft assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()
        sleep(1)

        # Delete the draft assignment
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class,"delete-link")]')
            )
        ).click()
        self.teacher.find(
            By.XPATH, '//button[contains(text(),"Yes")]'
        ).click()
        sleep(3)

        assert ('month' in self.teacher.current_url()), \
            'not returned to calendar after deleting an assignment'

        # have to refresh to remove the assignment tab from calendar
        self.teacher.driver.refresh()
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        deleted_event = self.teacher.find_all(
            By.XPATH, '//label[@data-title="{0}"]'.format(assignment_name)
        )
        assert (len(deleted_event) == 0), 'Event not deleted'

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


    # Case C162182 011 Teacher | Delete an unopened event
    @pytest.mark.skipif(str(162182) not in TESTS, reason="Excluded")
    def test_teacher_delete_an_unopened_event_162182(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162182']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_011_%s' % randint(100, 500)

        today = datetime.date.today()
        start = randint(2, 3)
        finish = start + randint(1, 5)
        begin = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create an unopened assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'publish',
            }
        )

        # Find the unopened Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'edit-assignment-button')
            )
        ).click()

        # Delete the assignment
        delete_button = self.teacher.find(
            By.XPATH, '//button[contains(@class,"delete-link")]'
        )
        self.teacher.scroll_to(delete_button)
        delete_button.click()
        sleep(3)
        confirm_button = self.teacher.find(
            By.XPATH, '//button[contains(text(),"Yes")]'
        )
        self.teacher.scroll_to(confirm_button)
        confirm_button.click()
        sleep(3)

        assert ('month' in self.teacher.current_url()), \
            'not returned to calendar after deleting an assignment'

        # Have to refresh the browser to remove assignment tab from calendar
        self.teacher.driver.refresh()
        deleted_unopened = self.teacher.find_all(
            By.XPATH, '//label[@data-title="{0}"]'.format(assignment_name)
        )
        assert len(deleted_unopened) == 0, 'unopened reading not deleted'

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


    # Case C162183 012 Teacher | Delete an open event
    @pytest.mark.skipif(str(162183) not in TESTS, reason="Excluded")
    def test_teacher_delete_an_open_event_162183(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162183']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_012_%s' % randint(100, 500)

        today = datetime.date.today()
        finish = randint(1, 5)
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create an unopened assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'publish',
            }
        )

        # Find the open Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'edit-assignment-button')
            )
        ).click()

        # Delete the assignment
        delete_button = self.teacher.find(
            By.XPATH, '//button[contains(@class,"delete-link")]'
        )
        self.teacher.scroll_to(delete_button)
        delete_button.click()
        sleep(3)
        confirm_button = self.teacher.find(
            By.XPATH, '//button[contains(text(),"Yes")]'
        )
        self.teacher.scroll_to(confirm_button)
        confirm_button.click()
        sleep(3)

        assert ('month' in self.teacher.current_url()), \
            'not returned to calendar after deleting an assignment'

        # Have to refresh the browser to remove assignment tab from calendar
        self.teacher.driver.refresh()
        deleted_unopened = self.teacher.find_all(
            By.XPATH, '//label[@data-title="{0}"]'.format(assignment_name)
        )
        assert len(
            deleted_unopened) == 0, 'open Event not deleted'

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


    # Case C162184 013 Teacher | Change a draft event
    @pytest.mark.skipif(str(162184) not in TESTS, reason="Excluded")
    def test_teacher_change_a_draft_event_162184(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162184']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_013_%s' % randint(100, 500)
        assignment = Assignment()
        today = datetime.date.today()
        finish = randint(1, 5)
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create a draft assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'draft',
            }
        )

        # Find the draft Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()
        sleep(1)

        # Change the title
        self.teacher.find(
            By.ID, "reading-title"
        ).send_keys("changed")

        # Change the description
        self.teacher.find(
            By.CSS_SELECTOR, ".assignment-description>.form-control"
        ).send_keys("changed")

        # Set new due dates
        today = datetime.date.today()
        start = randint(1, 6)
        end = start + randint(1, 5)
        opens_on = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        closes_on = (today + datetime.timedelta(days=end)) \
            .strftime('%m/%d/%Y')
        assignment.assign_periods(
            self.teacher.driver,
            {'all': (opens_on, closes_on)}
        )

        # Save as draft
        self.teacher.find(
            By.XPATH, '//button[contains(@class,"-save")]'
        ).click()
        sleep(1)

        # Find the new title on the calendar
        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(
                    assignment_name + 'changed')
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(
                    assignment_name + 'changed')
            )

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


    # Case C162185 014 Teacher | Change an unopened event
    @pytest.mark.skipif(str(162185) not in TESTS, reason="Excluded")
    def test_teacher_change_an_unopened_event_162185(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162185']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_014_%s' % randint(100, 500)
        assignment = Assignment()

        today = datetime.date.today()
        start = randint(2, 3)
        finish = start + randint(1, 5)
        begin = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create an unopened assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'publish',
            }
        )

        # Find the unopened Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'edit-assignment-button')
            )
        ).click()

        # Change the title
        self.teacher.find(
            By.ID, "reading-title"
        ).send_keys("changed")

        # Change the description
        self.teacher.find(
            By.CSS_SELECTOR, ".assignment-description>.form-control"
        ).send_keys("changed")

        # Set new due dates
        today = datetime.date.today()
        start = randint(1, 6)
        end = start + randint(1, 5)
        opens_on = (today + datetime.timedelta(days=start)) \
            .strftime('%m/%d/%Y')
        closes_on = (today + datetime.timedelta(days=end)) \
            .strftime('%m/%d/%Y')
        assignment.assign_periods(
            self.teacher.driver,
            {'all': (opens_on, closes_on)}
        )

        # Publish
        self.teacher.find(
            By.XPATH, '//button[contains(@class,"-publish")]'
        ).click()
        sleep(1)

        # Find the new title on the calendar
        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(
                    assignment_name + 'changed')
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(
                    assignment_name + 'changed')
            )

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


    # Case C162186 015 Teacher | Change an open event
    @pytest.mark.skipif(str(162186) not in TESTS, reason="Excluded")
    def test_teacher_change_an_open_event_162186(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162186']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_015_%s' % randint(100, 500)
        assignment = Assignment()

        today = datetime.date.today()
        finish = randint(1, 5)
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)) \
            .strftime('%m/%d/%Y')

        # Create an open assignment
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'publish',
            }
        )

        # Find the open Event on the calendar
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH,
            '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'edit-assignment-button')
            )
        ).click()

        # Change the title
        self.teacher.find(
            By.ID, "reading-title"
        ).send_keys("changed")

        # Change the description
        self.teacher.find(
            By.CSS_SELECTOR, ".assignment-description>.form-control"
        ).send_keys("changed")

        # Set new due dates
        end = randint(1, 5)
        closes_on = (today + datetime.timedelta(days=end)) \
            .strftime('%m/%d/%Y')
        assignment.assign_date(
            driver=self.teacher.driver, date=closes_on, is_all=True,
            target='due'
        )

        # Publish
        self.teacher.find(
            By.XPATH, '//button[contains(@class,"-publish")]'
        ).click()
        sleep(1)

        # Find the new title on the calendar
        try:
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(
                    assignment_name + 'changed')
            )
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                '//a[contains(@class,"header-control next")]'
            ).click()
            self.teacher.find(
                By.XPATH,
                '//label[contains(text(),"{0}")]'.format(
                    assignment_name + 'changed')
            )

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


    # Case C162187 016 Teacher | Add an event by dragging and dropping
    @pytest.mark.skipif(str(162187) not in TESTS, reason="Excluded")
    def test_teacher_add_an_event_by_drag_and_drop_162187(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162187']
        self.ps.test_updates['passed'] = False

        # Test verification
        self.teacher.assign.open_assignment_menu(self.teacher.driver)
        event_tab = self.teacher.find(
            By.LINK_TEXT, 'Add Event'
        )

        due_date = self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//div[contains(@class,"Day--upcoming")]')
            )
        )
        actions = ActionChains(self.teacher.driver)
        actions.move_to_element(event_tab)

        actions.drag_and_drop(event_tab, due_date).perform()
        sleep(3)

        assert ('event/new' in self.teacher.current_url()), \
            'not at Add Event page'

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


    # Case C162188 017 Teacher| Get assignment link test info icons
    @pytest.mark.skipif(str(162188) not in TESTS, reason="Excluded")
    def test_teacher_get_assignment_link_and_view_info_icons_162188(self):
        self.ps.test_updates['name'] = 'tutor_event_teacher' \
                                       + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['tutor', 'event', 'teacher',
                                        '162188']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        assignment_name = 'event_017_%d' % (randint(100, 999))
        assignment = Assignment()
        today = datetime.date.today()
        start = randint(2, 6)
        finish = start + randint(1, 5)
        begin_today = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=finish)).strftime('%m/%d/%Y')

        # Open Add Event page
        assignment.open_assignment_menu(self.teacher.driver)
        self.teacher.find(By.LINK_TEXT, 'Add Event').click()
        assert ('event/new' in self.teacher.current_url()), \
            'not at add event screen'

        # Test info icon
        self.teacher.find(
            By.XPATH, '//button[contains(@class, "footer-instructions")]'
        ).click()
        self.teacher.find(By.ID, 'plan-footer-popover')

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

        # Back to dashboard
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'builder-cancel-button')
            )
        ).click()
        assert ('month' in self.teacher.current_url()), \
            'not back at calendar after cancelling event'

        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin_today, end)},
                'url': 'www.openstax.org',
                'status': 'publish'
            }
        )

        # View assignment summary
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.CLASS_NAME, 'month-wrapper')
            )
        )
        self.teacher.find(
            By.XPATH, '//label[contains(text(),"{0}")]'.format(assignment_name)
        ).click()

        # Get assignment link
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.ID, 'lms-info-link')
            )
        ).click()
        sleep(3)
        self.teacher.find(
            By.XPATH, '//div[contains(@id, "sharable-link-popover")]'
        )

        self.ps.test_updates['passed'] = True
Пример #8
0
class TestStaxingTutorTeacher(unittest.TestCase):
    """Staxing case tests for Teacher."""

    book_sections = None
    class_start_end_dates = None

    def setUp(self):
        """Pretest settings."""
        self.teacher = Teacher(use_env_vars=True, driver_type=DRIVER)
        self.teacher.username = os.getenv('TEACHER_USER_MULTI',
                                          self.teacher.username)
        self.teacher.set_window_size(height=700, width=1200)
        self.teacher.login()
        courses = self.teacher.get_course_list()
        if len(courses) < 1:
            raise ValueError('No course available for selection')
        course = courses[randint(0, len(courses) - 1)]

        self.teacher.select_course(title=course.get_attribute('data-title'))

        if not self.__class__.book_sections:
            self.__class__.book_sections = self.teacher.get_book_sections()
        if not self.__class__.class_start_end_dates:
            self.__class__.class_start_end_dates = \
                self.teacher.get_course_begin_end()

        self.book_sections = self.__class__.book_sections
        self.start_end = self.__class__.class_start_end_dates

    def tearDown(self):
        """Test destructor."""
        try:
            self.teacher.delete()
        except Exception:
            pass

    @pytest.mark.skipif(str(301) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_individual_publish_301(self):
        """Build reading assignments.

        Type:     reading
        Sections: individualized
        Action:   publish
        """
        assignment_title = 'Reading-%s' % Assignment.rword(5)

        left_delta = randint(0, 20)
        left = datetime.date.today() + datetime.timedelta(left_delta)
        start_date_1 = self.teacher.date_string(day_delta=left_delta)
        start_date_2 = self.teacher.date_string(day_delta=left_delta + 1)
        start_date_3 = self.teacher.date_string(day_delta=left_delta + 2)
        start_date_4 = self.teacher.date_string(day_delta=left_delta + 3)
        if not self.teacher.date_is_valid(left):
            start_date_1 = (self.class_start_end_dates[0]) \
                .strftime('%m/%d/%Y')
            start_date_2 = \
                (self.class_start_end_dates[0] + datetime.timedelta(1)) \
                .strftime('%m/%d/%Y')
            start_date_3 = \
                (self.class_start_end_dates[0] + datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
            start_date_4 = \
                (self.class_start_end_dates[0] + datetime.timedelta(3)) \
                .strftime('%m/%d/%Y')
        right_delta = left_delta + randint(1, 10)
        right = datetime.date.today() + datetime.timedelta(right_delta)
        end_date_1 = self.teacher.date_string(day_delta=right_delta)
        end_date_2 = self.teacher.date_string(day_delta=right_delta + 1)
        end_date_3 = self.teacher.date_string(day_delta=right_delta + 2)
        end_date_4 = self.teacher.date_string(day_delta=right_delta + 3)
        if not self.teacher.date_is_valid(right):
            end_date_1 = \
                (self.class_start_end_dates[1] - datetime.timedelta(3)) \
                .strftime('%m/%d/%Y')
            end_date_2 = \
                (self.class_start_end_dates[1] - datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
            end_date_3 = \
                (self.class_start_end_dates[1] - datetime.timedelta(1)) \
                .strftime('%m/%d/%Y')
            end_date_4 = \
                (self.class_start_end_dates[1]) \
                .strftime('%m/%d/%Y')
        print('Left: %s  Right: %s' % (left, right))
        start_time_2 = '6:30 am'
        end_time_2 = '11:59 pm'
        reading_start = randint(0, (len(self.book_sections) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = self.book_sections[reading_start:reading_end]
        sections = self.teacher.get_course_sections()
        assign_sections = {}
        if len(sections) >= 1 and sections[0]:
            assign_sections[sections[0]] = (start_date_1, end_date_1)
        if len(sections) >= 2 and sections[1]:
            assign_sections[sections[1]] = ((start_date_2, start_time_2),
                                            (end_date_2, end_time_2))
        if len(sections) >= 3 and sections[2]:
            assign_sections[sections[2]] = (start_date_3, end_date_3)
        if len(sections) >= 4 and sections[3]:
            assign_sections[sections[3]] = (start_date_4, end_date_4)
        for number, section in enumerate(sections):
            assign_sections[section] = ((start_date_1, start_time_2),
                                        (end_date_1, end_time_2))
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description':
                'Staxing test reading - individual periods - ' + 'publish',
                'periods': assign_sections,
                'reading_list': reading_list,
                'status': 'publish',
                'break_point': None,
            })
        assert('course' in self.teacher.current_url()), \
            'Not at dashboard'
        print(self.teacher.current_url())
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(By.XPATH,
                                    '//label[text()="%s"]' % assignment_title)
        time.sleep(5.0)
        assert (reading), '%s not publishing on %s' % (assignment_title,
                                                       end_date_1)

    @pytest.mark.skipif(str(302) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_all_publish_302(self):
        """Build reading assignments."""
        # Reading, all periods, publish
        assignment_title = 'Reading-%s' % Assignment.rword(5)

        left_delta = randint(0, 20)
        left = datetime.date.today() + datetime.timedelta(left_delta)
        # start_date_1 = self.teacher.date_string(day_delta=left_delta)
        start_date_2 = self.teacher.date_string(day_delta=left_delta + 1)
        if not self.teacher.date_is_valid(left):
            # start_date_1 = \
            #     (self.class_start_end_dates[0]) \
            #     .strftime('%m/%d/%Y')
            start_date_2 = \
                (self.class_start_end_dates[0] + datetime.timedelta(1)) \
                .strftime('%m/%d/%Y')
        right_delta = left_delta + randint(1, 10)
        right = datetime.date.today() + datetime.timedelta(right_delta)
        end_date_1 = self.teacher.date_string(day_delta=right_delta)
        end_date_2 = self.teacher.date_string(day_delta=right_delta + 1)
        if not self.teacher.date_is_valid(right):
            end_date_1 = \
                (self.class_start_end_dates[1] - datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
            end_date_2 = \
                (self.class_start_end_dates[1] - datetime.timedelta(1)) \
                .strftime('%m/%d/%Y')
        print('Left: %s  Right: %s' % (left, right))
        # self.book_sections = self.teacher.get_book_sections()
        reading_start = randint(0, (len(self.book_sections) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = self.book_sections[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - all periods - publish',
                'periods': {
                    # '1st': (start_date_1, end_date_1),
                    'all': (start_date_2, end_date_2),
                },
                'reading_list': reading_list,
                'status': 'publish',
                'break_point': None,
            })
        assert('course' in self.teacher.current_url()), \
            'Not at dashboard'
        time.sleep(2.0)
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(By.XPATH,
                                    '//label[text()="%s"]' % assignment_title)
        time.sleep(5.0)
        assert (reading), '%s not publishing on %s' % (assignment_title,
                                                       end_date_2)

    @pytest.mark.skipif(str(303) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_individual_draft_303(self):
        """Build reading assignments."""
        # Reading, individual periods, draft
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left_delta = randint(0, 20)
        left = datetime.date.today() + datetime.timedelta(left_delta)
        '''start_date_1 = self.teacher.date_string(day_delta=left_delta)
        start_date_2 = self.teacher.date_string(day_delta=left_delta + 1)
        start_date_3 = self.teacher.date_string(day_delta=left_delta + 2)
        if not self.teacher.date_is_valid(left):
            start_date_1 = \
                (self.class_start_end_dates[0]).strftime('%m/%d/%Y')
            start_date_2 = \
                (self.class_start_end_dates[0] + datetime.timedelta(1)) \
                .strftime('%m/%d/%Y')
            start_date_3 = \
                (self.class_start_end_dates[0] + datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')'''
        right_delta = left_delta + randint(1, 10)
        right = datetime.date.today() + datetime.timedelta(right_delta)
        end_date_1 = self.teacher.date_string(day_delta=right_delta)
        # end_date_2 = self.teacher.date_string(day_delta=right_delta + 1)
        end_date_3 = self.teacher.date_string(day_delta=right_delta + 2)
        if not self.teacher.date_is_valid(right):
            end_date_1 = \
                (self.class_start_end_dates[1] - datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
            # end_date_2 = \
            #     (self.class_start_end_dates[1] - datetime.timedelta(1)) \
            #     .strftime('%m/%d/%Y')
            end_date_3 = \
                (self.class_start_end_dates[1]) \
                .strftime('%m/%d/%Y')
        print('Left: %s  Right: %s' % (left, right))
        # self.book_sections = self.teacher.get_book_sections()
        reading_start = randint(0, (len(self.book_sections) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = self.book_sections[reading_start:reading_end]
        sections = self.teacher.get_course_sections()
        periods = {}
        for index, section in enumerate(sections):
            periods[section] = \
                (self.teacher.date_string(day_delta=left_delta + index),
                 self.teacher.date_string(day_delta=right_delta + index))
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description':
                'Staxing test reading - individual periods ' + '- draft',
                'periods': periods,
                'reading_list': reading_list,
                'status': 'draft',
                'break_point': None,
            })
        assert('course' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(By.XPATH,
                                    '//label[text()="%s"]' % assignment_title)
        time.sleep(5.0)
        assert (reading), '%s not publishing on %s' % (assignment_title,
                                                       end_date_3)

    @pytest.mark.skipif(str(304) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_all_draft_304(self):
        """Build reading assignments."""
        # Reading, all periods, draft
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left_delta = randint(0, 20)
        left = datetime.date.today() + datetime.timedelta(left_delta)
        start_date_1 = self.teacher.date_string(day_delta=left_delta)
        if not self.teacher.date_is_valid(left):
            start_date_1 = \
                (self.class_start_end_dates[0]) \
                .strftime('%m/%d/%Y')

        right_delta = left_delta + randint(1, 10)
        right = datetime.date.today() + datetime.timedelta(right_delta)
        end_date_1 = self.teacher.date_string(day_delta=right_delta)
        if not self.teacher.date_is_valid(right):
            end_date_1 = \
                (self.class_start_end_dates[1] - datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
        print('Left: %s  Right: %s' % (left, right))
        # self.book_sections = self.teacher.get_book_sections()
        reading_start = randint(0, (len(self.book_sections) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = self.book_sections[reading_start:reading_end]
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_title,
                'description': 'Staxing test reading - all periods - draft',
                'periods': {
                    'all': (start_date_1, end_date_1),
                },
                'reading_list': reading_list,
                'status': 'draft',
                'break_point': None,
            })
        assert('course' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        reading = self.teacher.find(By.XPATH,
                                    '//label[text()="%s"]' % assignment_title)
        time.sleep(5.0)
        assert (reading), '%s not publishing on %s' % (assignment_title,
                                                       end_date_1)

    @pytest.mark.skipif(str(305) not in TESTS, reason='Excluded')
    def test_add_reading_assignment_one_cancel_305(self):
        """Build reading assignments."""
        # Reading, one period, cancel
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left_delta = randint(0, 20)
        left = datetime.date.today() + datetime.timedelta(left_delta)
        start_date_1 = self.teacher.date_string(day_delta=left_delta)
        if not self.teacher.date_is_valid(left):
            start_date_1 = \
                (self.class_start_end_dates[0]) \
                .strftime('%m/%d/%Y')
        right_delta = left_delta + randint(1, 10)
        right = datetime.date.today() + datetime.timedelta(right_delta)
        end_date_1 = self.teacher.date_string(day_delta=right_delta)
        if not self.teacher.date_is_valid(right):
            end_date_1 = \
                (self.class_start_end_dates[1] - datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
        print('Left: %s  Right: %s' % (left, right))
        # self.book_sections = self.teacher.get_book_sections()
        reading_start = randint(0, (len(self.book_sections) - 1))
        reading_end = reading_start + randint(1, 5)
        reading_list = self.book_sections[reading_start:reading_end]
        sections = self.teacher.get_course_sections()
        if not isinstance(sections, list):
            sections = [sections]
        self.teacher.add_assignment(assignment='reading',
                                    args={
                                        'title': assignment_title,
                                        'description':
                                        'Staxing test reading - cancel',
                                        'periods': {
                                            sections[0]:
                                            (start_date_1, end_date_1),
                                        },
                                        'reading_list': reading_list,
                                        'status': 'cancel',
                                        'break_point': None,
                                    })
        assert('course' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date_1)
        time.sleep(5.0)
        with pytest.raises(NoSuchElementException):
            self.teacher.find(By.XPATH,
                              '//label[text()="%s"]' % assignment_title)

    @pytest.mark.skipif(str(306) not in TESTS, reason='Excluded')
    def test_change_assignment_306(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(307) not in TESTS, reason='Excluded')
    def test_delete_assignment_307(self):
        """No test placeholder."""
        assignment_title = 'Reading-%s' % Assignment.rword(5)
        left_delta = randint(0, 20)
        left = datetime.date.today() + datetime.timedelta(left_delta)
        start_date = self.teacher.date_string(day_delta=left_delta)
        if not self.teacher.date_is_valid(left):
            start_date = \
                (self.class_start_end_dates[0]) \
                .strftime('%m/%d/%Y')
        right_delta = left_delta + randint(1, 10)
        right = datetime.date.today() + datetime.timedelta(right_delta)
        end_date = self.teacher.date_string(day_delta=right_delta)
        if not self.teacher.date_is_valid(right):
            end_date = \
                (self.class_start_end_dates[1] - datetime.timedelta(2)) \
                .strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='reading',
                                    args={
                                        'title': assignment_title,
                                        'periods': {
                                            'all': (start_date, end_date),
                                        },
                                        'reading_list': ['1', '1.1'],
                                        'status': 'publish',
                                        'break_point': None,
                                    })
        assert('course' in self.teacher.current_url()), \
            'Not at dashboard'
        self.teacher.rotate_calendar(end_date)
        reading = self.teacher.find(By.XPATH,
                                    '//label[text()="%s"]' % assignment_title)
        print('Waiting for publish')

        time.sleep(5.0)
        assert(reading), \
            '%s not publishing on %s' % (assignment_title, end_date)
        self.teacher.delete_assignment(assignment='reading',
                                       args={
                                           'title': assignment_title,
                                           'periods': {
                                               'all': (start_date, end_date),
                                           },
                                       })
        self.teacher.rotate_calendar(end_date)
        time.sleep(5.0)
        try:
            self.teacher.find(By.XPATH,
                              '//label[text()="%s"]' % assignment_title)
            assert (False), '%s still exists' % assignment_title
        except Exception:
            pass

    @pytest.mark.skipif(str(308) not in TESTS, reason='Excluded')
    def test_goto_menu_item_308(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(309) not in TESTS, reason='Excluded')
    def test_goto_calendar_309(self):
        """No test placeholder."""
        pass

    @pytest.mark.skipif(str(310) not in TESTS, reason='Excluded')
    def test_goto_performance_forecast_310(self):
        """No test placeholder."""
        self.teacher.goto_performance_forecast()

    @pytest.mark.skipif(str(311) not in TESTS, reason='Excluded')
    def test_goto_student_scores_311(self):
        """No test placeholder."""
        self.teacher.goto_student_scores()

    @pytest.mark.skipif(str(312) not in TESTS, reason='Excluded')
    def test_goto_course_roster_312(self):
        """No test placeholder."""
        self.teacher.goto_course_roster()

    @pytest.mark.skipif(str(313) not in TESTS, reason='Excluded')
    def test_goto_course_settings_313(self):
        """No test placeholder."""
        self.teacher.goto_course_settings()

    @pytest.mark.skipif(str(314) not in TESTS, reason='Excluded')
    def test_add_course_section_314(self):
        """Add a course section to a class."""
        section_name = 'New Section'
        self.teacher.add_course_section(section_name)
        classes = self.teacher.find_all(By.CSS_SELECTOR, 'a[role*="tab"]')
        section_names = []
        for section in classes:
            section_names.append(section.get_attribute('innerHTML'))
        assert(section_name in section_names), \
            '%s not in %s' % (section_name, section_names)
        self.teacher.goto_course_settings()
        self.teacher.find

    @pytest.mark.skipif(str(315) not in TESTS, reason='Excluded')
    def test_get_enrollment_code_315(self):
        """No test placeholder."""
        code = self.teacher.get_enrollment_code()
        assert('enroll' in code and re.search('\d{6}', code) is not None), \
            '%s is not the correct enrollment URL' % code

    @pytest.mark.skipif(str(316) not in TESTS, reason='Excluded')
    def test_teacher_handle_modals_316(self):
        self.teacher.enable_debug_mode()
        self.teacher.close_beta_windows()
        time.sleep(3)
        assert ("modal closed")
class TestAnalyzeCollegeWorkflow(unittest.TestCase):
    """T2.05 - Analyze College Workflow."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
            self.student = Student(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities,
                                   existing_driver=self.teacher.driver)
        else:
            self.teacher = Teacher(use_env_vars=True)
            self.student = Student(use_env_vars=True,
                                   existing_driver=self.teacher.driver)

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

    @pytest.mark.skipif(str(1) not in TESTS, reason='Excluded')
    def test_create_assignment_links_teacher(self):
        """
        Go to https://tutor-qa.openstax.org/
        Click on the 'Login' button
        Login to student account
        Click 'Next'
        Enter the teacher password [ password ] in the password text box
        Click on the 'Login' button
        If the user has more than one course, click on a Tutor course name
        Click on a published reading assignment on the calendar dashboard
        Click "Get Assignment Link"
        ***User is presented with links to assigned readings (t2.05.04)***

        Click on 'X' to get out of pop-up menu
        Click on a published homework assignment on the calendar dashboard
        ***Click "Get Assignment Link"
        User is presented with links to assigned homework (t2.05.05)***

        Expected Results:


        Corresponds to...
        t2.05.04 --> 05
        :return:
        """
        # t2.05.04 --> ser is presented with links to assigned readings (t2.05.04)
        self.teacher.login()

        self.teacher.select_course(appearance='biology')
        assignment_name = 'reading004_%d' % (randint(100, 999))
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=4)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='reading',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'reading_list': ['1.1'],
                                        'status': 'publish'
                                    })
        try:
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                "//a[contains(@class, 'header-control next')]").click()
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[@class="get-link"]'))).click()
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[@class="popover-content"]' +
                 '//input[contains(@value,"https://tutor")]')))

        # t2.05.05 --> Clicking "Get Assignment Link presents
        # user with links to assigned homework (t2.05.05)***

        ### FIND A WAY TO GET BACK TO MY CURRENT COURSES PAGE (maybe use teacher goto... method)

        self.teacher.select_course(appearance='biology')
        assignment_name = 'hw005_%d' % (randint(100, 999))
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=4)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='homework',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'problems': {
                                            '1.1': (2, 3),
                                        },
                                        'status': 'publish',
                                        'feedback': 'immediate'
                                    })
        try:
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.sleep(1)
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                "//a[contains(@class, 'header-control next')]").click()
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[@class="get-link"]'))).click()
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[@class="popover-content"]' +
                 '//input[contains(@value,"https://tutor")]')))
class TestViewTheCalendarDashboard(unittest.TestCase):
    """T1.13 - View the calendar."""

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

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

    # Case C7978 - 001 - Teacher | View the calendar dashboard
    @pytest.mark.skipif(str(7978) not in TESTS, reason='Excluded')
    def test_teacher_view_the_calendar_dashboard_7978(self):
        """View the calendar dashboard.

        Steps:
        If the user has more than one course, click on a Tutor course name

        Expected Result:
        The teacher is presented their calendar dashboard.
        """
        self.ps.test_updates['name'] = 't1.13.001' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.001', '7978']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

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

    # Case C7979 - 002 - Teacher | View student scores using dashboard button
    @pytest.mark.skipif(str(7979) not in TESTS, reason='Excluded')
    def test_teacher_view_student_scores_using_the_dashboard_button_7979(self):
        """View student scores using the dashboard button.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Student Scores' button

        Expected Result:
        The teacher is presented with the student scores
        """
        self.ps.test_updates['name'] = 't1.13.002' + \
            inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.002', '7979']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.find(By.LINK_TEXT, 'Student Scores').click()
        assert('scores' in self.teacher.current_url()), \
            'Not viewing student scores'

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

    # Case C7980 - 003 - Teacher | View student scores using the user menu link
    @pytest.mark.skipif(str(7980) not in TESTS, reason='Excluded')
    def test_teacher_view_student_scores_using_the_user_menu_link_7980(self):
        """View student scores using the user menu link.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the user menu
        Click on the 'Student Scores' link

        Expected Result:
        The teacher is presented with the student scores
        """
        self.ps.test_updates['name'] = 't1.13.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.003', '7980']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.open_user_menu()
        self.teacher.find(By.CLASS_NAME, 'viewScores'). \
            find_element_by_tag_name('a'). \
            click()
        assert('scores' in self.teacher.current_url()), \
            'Not viewing the student scores'

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

    # Case C7981 - 004 - Teacher | View performance forecast using the
    # dashboard button
    @pytest.mark.skipif(str(7981) not in TESTS, reason='Excluded')
    def test_teacher_view_performance_forecast_using_dash_button_7981(self):
        """View performance forecast using the dashboard button.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Performance Forecast' button on the dashboard

        Expected Result:
        The teacher is presented with the performance forecast
        """
        self.ps.test_updates['name'] = 't1.13.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.004', '7981']
        self.ps.test_updates['passed'] = False

        self.teacher.find(By.LINK_TEXT, 'Performance Forecast').click()
        self.teacher.page.wait_for_page_load()
        assert('guide' in self.teacher.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C7982 - 005 - Teacher | View performace forecast using
    # the user menu link
    @pytest.mark.skipif(str(7982) not in TESTS, reason='Excluded')
    def test_teacher_view_performance_forecast_using_user_menu_link_7982(self):
        """View performance forecast using the user menu link.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the user menu
        Click on the 'Performance Forecast' link

        Expected Result:
        The teacher is presented with the performance forecast
        """
        self.ps.test_updates['name'] = 't1.13.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.005', '7982']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.open_user_menu()
        self.teacher.find(By.CLASS_NAME, 'viewTeacherPerformanceForecast'). \
            find_element_by_tag_name('a'). \
            click()
        self.teacher.page.wait_for_page_load()
        assert('guide' in self.teacher.current_url()), \
            'Not viewing the performance forecast'

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

    # Case C7983 - 006 - Teacher | View a reading assignment summary
    @pytest.mark.skipif(str(7983) not in TESTS, reason='Excluded')
    def test_teacher_view_a_reading_assignment_summary_7983(self):
        """View a reading assignment summary.

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

        Expected Result:
        The teacher is presented with the reading assignment summary
        """
        self.ps.test_updates['name'] = 't1.13.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.006', '7983']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        # create an assignment
        assignment_name = 'reading-%s' % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='reading',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'reading_list': ['1.1'],
                'status': 'publish',
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )

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

    # Case C7984 - 007 - Teacher | View a homework assignment summary
    @pytest.mark.skipif(str(7984) not in TESTS, reason='Excluded')
    def test_teacher_view_a_homework_assignment_summary_7984(self):
        """View a homework assignment summary.

        Steps:
        create a homework assignment
        If the user has more than one course, click on a Tutor course name
        Click on a homework assignment on the calendar

        Expected Result:
        The teacher is presented with the homework assignment summary
        """
        self.ps.test_updates['name'] = 't1.13.007' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.007', '7984']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        # create an assignment
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='homework',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'problems': {'1.1': (2, 3), },
                'status': 'publish',
                'feedback': 'immediate'
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )
        self.ps.test_updates['passed'] = True

    # NOT DONE
    # Case C7985 - 008 - Teacher | View an external assignment summary
    @pytest.mark.skipif(str(7985) not in TESTS, reason='Excluded')
    def test_teacher_view_an_external_assignment_summary_7985(self):
        """View an external assignment summary.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on an external assignment on the calendar

        Expected Result:
        The teacher is presented with the external assignment summary
        """
        self.ps.test_updates['name'] = 't1.13.008' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.008', '7985']
        self.ps.test_updates['passed'] = False

        # create an assignment
        assignment_name = 'external-%s' % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='external',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'url': 'google.com',
                'status': 'publish'
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )

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

    # Case C7986 - 009 - Teacher | View an event summary
    @pytest.mark.skipif(str(7986) not in TESTS, reason='Excluded')
    def test_teacher_view_an_event_summary_7986(self):
        """View an event summary.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on an event on the calendar

        Expected Result:
        The teacher is presented with the event summary
        """
        self.ps.test_updates['name'] = 't1.13.009' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.009', '7986']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        # create an assignment
        assignment_name = "homework-%s" % randint(100, 999)
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=2)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=5)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(
            assignment='event',
            args={
                'title': assignment_name,
                'description': 'description',
                'periods': {'all': (begin, end)},
                'status': 'publish'
            }
        )
        # click on assignment
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//label[contains(text(), "%s")]' % assignment_name)
            )
        ).click()
        # check that it opened
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH,
                 '//*[@class="modal-title" and ' +
                 'contains(text(), "%s")]' % assignment_name)
            )
        )

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

    # Case C7987 - 010 - Teacher | Open the refrenece book using the dashboard
    # button
    @pytest.mark.skipif(str(7987) not in TESTS, reason='Excluded')
    def test_teacher_open_the_reference_book_using_dashboard_button_7987(self):
        """Open the refrenece book using the dashboard button.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Browse The Book'button

        Expected Result:
        The teacher is preseneted with the book in a new tab
        """
        self.ps.test_updates['name'] = 't1.13.010' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.010', '7987']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.driver.find_element(
            By.LINK_TEXT,
            'Browse The Book'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('book' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C7988 - 011 - Teacher | Open the refrenece book using user menu link
    @pytest.mark.skipif(str(7988) not in TESTS, reason='Excluded')
    def test_teacher_open_the_reference_book_using_user_menu_link_7988(self):
        """Open the refrenece book using the user menu link.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the user menu
        Click on the 'Browse the Book' link

        Expected Result:
        The teacher is presented with the book in a new tab
        """
        self.ps.test_updates['name'] = 't1.13.011' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.011', '7988']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(title='HS Physics')
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.LINK_TEXT,
            'Browse the Book'
        ).click()
        window_with_book = self.teacher.driver.window_handles[1]
        self.teacher.driver.switch_to_window(window_with_book)
        assert('book' in self.teacher.current_url()), \
            'Not viewing the textbook PDF'

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

    # Case C7989 - 012 - Teacher | Click on the course name to return to
    # the dashboard
    @pytest.mark.skipif(str(7989) not in TESTS, reason='Excluded')
    def test_teacher_click_course_name_to_return_to_the_dashboard_7989(self):
        """Click on the course name to return to the dashboard.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click on the 'Performance Forecast' button
        Click on the course name in the header

        Expected Result:
        The teacher is presented with their calendar dashboard
        """
        self.ps.test_updates['name'] = 't1.13.012' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.012', '7989']
        self.ps.test_updates['passed'] = False

        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.CLASS_NAME,
            'viewTeacherPerformanceForecast'
        ).click()
        self.teacher.driver.find_element(
            By.CLASS_NAME,
            'course-name'
        ).click()
        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

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

    # Case C7990 - 013 - Teacher | Cick on the OpenStax logo to return to
    # the course picker
    @pytest.mark.skipif(str(7990) not in TESTS, reason='Excluded')
    def test_teacher_click_openstax_logo_to_return_to_course_picker_7990(self):
        """Cick on the OpenStax logo to return to the course picker.

        Steps:
        If the user has more than one course, click on a Tutor course name
        Click in the OpenStax logo in the header

        Expected Result:
        The teacher is presented with the course picker
        """
        self.ps.test_updates['name'] = 't1.13.013' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.013', '7990']
        self.ps.test_updates['passed'] = False

        # self.teacher.select_course(appearance='physics')
        self.teacher.driver.find_element(
            By.CLASS_NAME,
            'ui-brand-logo'
        ).click()
        assert('dashboard' in self.teacher.current_url()), \
            'Not viewing the course picker'

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

    # Case C7991 - 014 - Teacher | CLick in the OpenStax logo to return to the
    # dashboard
    @pytest.mark.skipif(str(7991) not in TESTS, reason='Excluded')
    def test_teacher_clicks_openstax_logo_to_return_to_dashboard_7991(self):
        """CLick in the OpenStax logo to return to the dashboard.

        Steps:
        Click on the 'Performance Forecast' button
        Click on the OpenStax logo in the header

        Expected Result:
        The teacher is presented with their calendar dashboard
        """
        self.ps.test_updates['name'] = 't1.13.014' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t1', 't1.13', 't1.13.014', '7991']
        self.ps.test_updates['passed'] = False

        self.teacher.logout()
        teacher2 = Teacher(
            username=os.getenv('TEACHER_USER_ONE_COURSE'),
            password=os.getenv('TEACHER_PASSWORD'),
            site='https://tutor-qa.openstax.org',
            existing_driver=self.teacher.driver,
            pasta_user=self.ps,
            capabilities=self.desired_capabilities,
        )
        print(teacher2.username)
        print(teacher2.password)
        teacher2.login()
        self.teacher.open_user_menu()
        self.teacher.driver.find_element(
            By.CLASS_NAME,
            'viewTeacherPerformanceForecast'
        ).click()
        self.teacher.driver.find_element(
            By.CLASS_NAME,
            'ui-brand-logo'
        ).click()
        assert('calendar' in self.teacher.current_url()), \
            'Not viewing the calendar dashboard'

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

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

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

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

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

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

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

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

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

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

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

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

        self.ps.test_updates["passed"] = True
class TestWorkAHomework(unittest.TestCase):

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

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

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

        Click on a homework assignment (with immediate feedback) on the list
        dashboard
        ***The user starts an open homework assignment (t1.71.22)***

        Enter a free response into the free response text box
        Click "Answer"
        Select a multiple choice answer
        Click "Submit"
        ***A multiple choice answer is submitted (t1.71.23)***
        ***Answer feedback is presented
        (t1.71.24)***

        Expected results:

        Corresponds to...
        t1.71 22 --> 24

        :return:
        """
        # go to course
        self.teacher.login()

        # t1.71 22 --> The user starts an open homework assignment

        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=0)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=3)).strftime('%m/%d/%Y')
        assignment_name = 'hw no.{0}: {1}'.format(
            str(randint(0, 100)),
            str(today)
        )

        # get course name and term
        course_title = "Physics"  # name of course or part of the name
        current_term = current_tutor_term(begin)

        open_course_xpath = '//div[contains(@data-title,"{0}") and ' \
            'contains(@data-term,"{1}")]//a'.format(
                course_title,
                current_term
            )

        # we do the above in order to ensure that the course is open right now
        target_course = self.teacher.find(By.XPATH, open_course_xpath)

        # for reference later as student
        course_number = target_course.get_attribute('data-course-id')
        target_course.click()
        # immediate feedback
        self.teacher.add_assignment(assignment='homework',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {'all': (begin, end)},
                                        'status': 'publish',
                                        'problems': {'ch1': 5},
                                        'feedback': 'immediate'
                                    })
        self.teacher.logout()

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

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

        homework = self.student.find(
            By.XPATH,
            '//a[contains(@aria-labelledby, "%s")]' % assignment_name
        )

        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();',
            homework
        )
        ActionChains(self.student.driver).move_to_element(homework).perform()
        homework.click()

        # make sure that we're at the HW

        # t1.71 24 --> Answer feedback is presented
        wait = WebDriverWait(self.student.driver, Assignment.WAIT_TIME)
        wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"question-stem")]')
            )
        )

        try:
            # if the question is two part must answer free response to get mc
            text_box = self.student.find(
                By.TAG_NAME, 'textarea')
            self.teacher.driver.execute_script(
                "arguments[0].scrollIntoView(true);",
                text_box
            )

            answer_text = "hello"
            for i in answer_text:
                text_box.send_keys(i)
            self.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//button[contains(@class,"continue")]')
                )
            ).click()
        except:
            pass

        mc_choice = self.student.find(
            By.XPATH, '//div[@class="answer-letter"]')
        self.student.driver.execute_script(
            'return arguments[0].scrollIntoView();',
            mc_choice
        )

        self.student.driver.execute_script('window.scrollBy(0, -150);')
        mc_choice.click()
        self.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//button[contains(@class,"continue")]')
            )
        ).click()

        try:
            # this is looking for question feedback -- though not all questions
            # might have
            self.student.find(
                By.XPATH,
                '//div[contains(@class,"question-feedback-content")]'
            )

        except:
            correct_answer = self.student.find(
                By.XPATH,
                "//div[contains(@class,'disabled answer-correct')]"
            )
            print(correct_answer)

        # you should expect to see the answer feedback

        # t1.71 23 --> A multiple choice answer is submitted and
        # you can navigate to the next assessment
        self.student.find(
            By.XPATH, '//button[contains(text(),"Next")]')
class TestSimplifyAndImproveReadings(unittest.TestCase):
    """T2.13 - Simplify and Improve Readings."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        self.teacher = Teacher(use_env_vars=True,
                               pasta_user=self.ps,
                               capabilities=self.desired_capabilities)
        # create a reading for the student to work
        self.teacher.login()
        self.teacher.driver.execute_script("window.resizeTo(1920,1080)")
        self.teacher.select_course(appearance='ap_biology')
        self.assignment_name = 't1.18 reading-%s' % randint(100, 999)
        today = datetime.date.today()
        begin = today.strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=randint(1, 10))) \
            .strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='reading',
                                    args={
                                        'title': self.assignment_name,
                                        'description': chomsky(),
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'reading_list': ['1.1'],
                                        'status': 'publish',
                                    })
        self.teacher.wait.until(
            expect.visibility_of_element_located(
                (By.XPATH, '//div[contains(@class,"calendar-container")]')))
        self.teacher.logout()
        # login as a student to work the reading
        self.student = Student(existing_driver=self.teacher.driver,
                               use_env_vars=True,
                               pasta_user=self.ps,
                               capabilities=self.desired_capabilities)
        self.student.login()
        self.student.select_course(appearance='ap_biology')
        self.student.wait.until(
            expect.visibility_of_element_located((By.LINK_TEXT, 'This Week')))
        reading = self.student.driver.find_element(
            By.XPATH, '//div[text()="%s"]' % self.assignment_name)
        self.teacher.driver.execute_script(
            'return arguments[0].scrollIntoView();', reading)
        self.teacher.driver.execute_script('window.scrollBy(0, -80);')
        reading.click()
        self.student.driver.set_window_size(width=1300, height=1200)

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

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

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

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

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

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

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

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

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

        # Test steps and verification assertions
        self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click()
        self.student.sleep(1)
        self.student.find(By.CSS_SELECTOR, 'a.paging-control.next').click()
        self.student.sleep(5)
        self.student.driver.execute_script("window.scrollTo(0, 0);")
        element = self.student.find(By.XPATH,
                                    "//a[@class='milestones-toggle']")
        actions = ActionChains(self.student.driver)
        actions.move_to_element(element)
        actions.click()
        actions.perform()
        self.student.sleep(1)
        self.student.driver.execute_script("window.scrollTo(0, 0);")
        cards = self.student.find_all(
            By.XPATH, "//div[@class='milestone milestone-reading']")
        # preview = ''
        if not isinstance(cards, list):
            # preview = cards.find_element(
            #    By.XPATH,
            #    "//div[@class='milestone milestone-reading']"
            # ).text
            cards.click()
        else:
            card = randint(0, len(cards))
            # preview = cards[card].find_element(
            #    By.XPATH,
            #    "//div[@class='milestone milestone-reading']"
            # ).text
            cards[card].click()

        string = "step/" + str(card + 1)

        assert(self.student.driver.current_url.find(string) >= 0), \
            'Something'

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

    # C85291 - 003 - Student | Reading Review card appears before the first
    # spaced practice question
    @pytest.mark.skipif(str(85291) not in TESTS, reason='Excluded')
    def test_student_reading_review_card_appears_before_first_spac_85291(self):
        """Reading Review card appears before first spaced practice question.

        Steps:
        Login as student
        Work the reading assignment
        After completing reading the sections you get a spaced practice problem

        Expected Result:
        The reading review card should appear before the first spaced practice
            question
        """
        self.ps.test_updates['name'] = 't2.08.003' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.003', '85291']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        while (1):
            while ('paging-control next' in self.student.driver.page_source
                   and 'Concept Coach' not in self.student.driver.page_source
                   and 'exercise-multiple-choice'
                   not in self.student.driver.page_source
                   and 'textarea' not in self.student.driver.page_source):
                self.student.find(By.XPATH,
                                  "//a[@class='paging-control next']").click()

            # multiple choice case
            if ('exercise-multiple-choice' in self.student.driver.page_source):

                answers = self.student.driver.find_elements(
                    By.CLASS_NAME, 'answer-letter')
                self.student.sleep(0.8)
                rand = randint(0, len(answers) - 1)
                answer = chr(ord('a') + rand)
                Assignment.scroll_to(self.student.driver, answers[0])
                if answer == 'a':
                    self.student.driver.execute_script(
                        'window.scrollBy(0, -160);')
                elif answer == 'd':
                    self.student.driver.execute_script(
                        'window.scrollBy(0, 160);')
                answers[rand].click()

                self.student.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH, '//button[contains(@class,"async-button")' +
                         ' and contains(@class,"continue")]'))).click()
                self.student.sleep(5)
                page = self.student.driver.page_source
                assert('question-feedback bottom' in page), \
                    'Did not submit MC'

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

            # free response case
            elif ('textarea' in self.student.driver.page_source):
                self.student.find(
                    By.TAG_NAME,
                    'textarea').send_keys('An answer for this textarea')
                self.student.sleep(2)
                self.student.wait.until(
                    expect.element_to_be_clickable(
                        (By.XPATH, '//button[contains(@class,"async-button")' +
                         ' and contains(@class,"continue")]'))).click()

                self.student.wait.until(
                    expect.visibility_of_element_located(
                        (By.CLASS_NAME, 'exercise-multiple-choice')))

                self.student.sleep(2)

            # Reached Concept Coach card
            if ('Spaced Practice' in self.student.driver.page_source
                    and 'spaced-practice-intro'
                    in self.student.driver.page_source):
                self.student.sleep(5)
                break

            self.student.sleep(2)

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

    # C100126 - 004 - Student | Section number is seen at the beginning of each
    # new section in a reading assignment
    @pytest.mark.skipif(str(100126) not in TESTS, reason='Excluded')
    def test_student_section_number_is_seen_st_the_beginning_of_e_100126(self):
        """Section number seen at beginning of each new section in a reading.

        Steps:
        Login as a student
        Click on a tutor course
        Click on a reading assignment
        Continue to work through reading assignment

        Expected Result:
        At the start of each new section, the section number is displayed
        """
        self.ps.test_updates['name'] = 't2.08.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.004', '100126']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.find(By.XPATH, "//span[@class='section']")
        self.student.sleep(3)

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

    # C100127 - 005 - Teacher | Section numbers are listed at the top of each
    # section in reference view
    @pytest.mark.skipif(str(100127) not in TESTS, reason='Excluded')
    def test_student_section_numbers_listed_at_the_top_of_each_se_100127(self):
        """Section numbers listed at the top of each section in reference view.

        Steps:
        Login as teacher
        Click on a tutor course
        Click "Browse the Book" or select "Browse the Book" from the user menu
        Select a section from the contents

        Expected Result:
        Section number listed in header
        """
        self.ps.test_updates['name'] = 't2.08.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.005', '100127']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.logout()
        self.teacher.login()
        self.teacher.select_course(appearance='ap_biology')
        self.teacher.open_user_menu()
        self.teacher.find(By.LINK_TEXT, "Browse the Book").click()
        self.teacher.sleep(5)
        self.teacher.driver.switch_to_window(
            self.student.driver.window_handles[-1])
        self.teacher.find(By.XPATH,
                          "//li[3]/ul[@class='section']/li/a").click()
        self.teacher.find(By.XPATH, "//span[@class='section']")
        self.teacher.sleep(3)

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

    # C100128 - 006 - Student | Section numbers are listed at the top of each
    # section in reference view
    @pytest.mark.skipif(str(100128) not in TESTS, reason='Excluded')
    def test_student_section_numbers_listed_at_the_top_of_each_se_100128(self):
        """Section numbers listed at the top of each section in reference view.

        Steps:
        Login as student
        Click on a tutor course
        Click "Browse the Book" or select "Browse the Book" from the user menu
        Select a section from the contents

        Expected Result:
        Section number listed in header
        """
        self.ps.test_updates['name'] = 't2.08.006' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.08', 't2.08.006', '100128']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.open_user_menu()
        self.student.find(By.LINK_TEXT, "Browse the Book").click()
        self.student.sleep(5)
        self.student.driver.switch_to_window(
            self.student.driver.window_handles[-1])
        self.student.find(By.XPATH,
                          "//li[3]/ul[@class='section']/li/a").click()
        self.student.find(By.XPATH, "//span[@class='section']")
        self.student.sleep(3)

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

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

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

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

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

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

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

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

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

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

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

        self.ps.test_updates['passed'] = True
Пример #15
0
class TestAnalyzeCollegeWorkflow(unittest.TestCase):
    """T2.05 - Analyze College Workflow."""
    def setUp(self):
        """Pretest settings."""
        self.ps = PastaSauce()
        self.desired_capabilities['name'] = self.id()
        if not LOCAL_RUN:
            self.teacher = Teacher(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities)
            self.student = Student(use_env_vars=True,
                                   pasta_user=self.ps,
                                   capabilities=self.desired_capabilities,
                                   existing_driver=self.teacher.driver)
        else:
            self.teacher = Teacher(use_env_vars=True)
            self.student = Student(use_env_vars=True,
                                   existing_driver=self.teacher.driver)

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

    # 14645 - 001 - Student | All work is visible for college students
    # not just "This Week"
    @pytest.mark.skipif(str(14645) not in TESTS, reason='Excluded')
    def test_student_all_work_is_visible_for_college_students_14645(self):
        """All work is visible for college students, not just 'This Week'.

        Steps:
        Log into tutor-qa as student
        Click on a college course

        Expected Result:
        Can view assignments due later than this week
        """
        self.ps.test_updates['name'] = 't2.05.001' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.001', '14645']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.student.login()
        self.student.select_course(title='College Physics with Courseware')

        # find either upcoming events, or a message stating there are none.
        try:
            self.teacher.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH, '//span[contains(text(),"%s")]' % "Coming Up")))
        except TimeoutException:
            self.teacher.wait.until(
                expect.visibility_of_element_located(
                    (By.XPATH,
                     '//div[contains(text(),"%s")]' % "No upcoming events")))
        self.ps.test_updates['passed'] = True

    '''
    # 14646 - 002 - Teacher | Create a link to the OpenStax Dashboard
    @pytest.mark.skipif(str(14646) not in TESTS, reason='Excluded')
    def test_teacher_create_a_link_to_the_openstax_dashboard_14646(self):
        """Create a link to the OpenStax Dashboard.

        Steps:

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

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

        self.ps.test_updates['passed'] = True
    '''
    '''
    # 14647 - 003 - Teacher | Create a link to the OpenStax Dashboard
    @pytest.mark.skipif(str(14647) not in TESTS, reason='Excluded')
    def test_teacher_create_a_link_to_the_openstax_dashboard_14647(self):
        """Create a link to the OpenStax Dashboard.

        Steps:

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

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

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

    # 14648 - 004 - Teacher | Create links to assigned readings in their LMS
    @pytest.mark.skipif(str(14648) not in TESTS, reason='Excluded')
    def test_teacher_create_links_to_assigned_readings_in_lms_14648(self):
        """Create links to assigned readings in their LMS.

        Steps:
        Login as a teacher
        If the user has more than one course, click on a tutor course name
        Click on a published reading assignment on the calendar dashboard
        Click "Get Assignment Link"

        Expected Result:
        The user is presented with links to assigned readings
        """
        self.ps.test_updates['name'] = 't2.05.004' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.004', '14648']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()

        self.teacher.select_course(appearance='biology')
        assignment_name = 'reading004_%d' % (randint(100, 999))
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=4)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='reading',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'reading_list': ['1.1'],
                                        'status': 'publish'
                                    })
        try:
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                "//a[contains(@class, 'header-control next')]").click()
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[@class="get-link"]'))).click()
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[@class="popover-content"]' +
                 '//input[contains(@value,"https://tutor")]')))
        self.ps.test_updates['passed'] = True

    # 14649 - 005 - Teacher | Create links to assigned homework in their LMS
    @pytest.mark.skipif(str(14649) not in TESTS, reason='Excluded')
    def test_teacher_create_links_to_assigned_homework_in_lms_14649(self):
        """Create links to assigned homework in their LMS.

        Steps:
        Go to Tutor
        Click on the 'Login' button
        Enter the teacher user account in the username and password text boxes
        Click on the 'Sign in' button
        If the user has more than one course, click on a CC course name
        Click on a published homework assignment on the calendar dashboard
        Click "Get Assignment Link"

        Expected Result:
        The user is presented with links to assigned homework
        """
        self.ps.test_updates['name'] = 't2.05.005' \
            + inspect.currentframe().f_code.co_name[4:]
        self.ps.test_updates['tags'] = ['t2', 't2.05', 't2.05.005', '14649']
        self.ps.test_updates['passed'] = False

        # Test steps and verification assertions
        self.teacher.login()

        self.teacher.select_course(appearance='biology')
        assignment_name = 'hw005_%d' % (randint(100, 999))
        today = datetime.date.today()
        begin = (today + datetime.timedelta(days=1)).strftime('%m/%d/%Y')
        end = (today + datetime.timedelta(days=4)).strftime('%m/%d/%Y')
        self.teacher.add_assignment(assignment='homework',
                                    args={
                                        'title': assignment_name,
                                        'description': 'description',
                                        'periods': {
                                            'all': (begin, end)
                                        },
                                        'problems': {
                                            '1.1': (2, 3),
                                        },
                                        'status': 'publish',
                                        'feedback': 'immediate'
                                    })
        try:
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.sleep(1)
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        except NoSuchElementException:
            self.teacher.find(
                By.XPATH,
                "//a[contains(@class, 'header-control next')]").click()
            self.teacher.wait.until(
                expect.presence_of_element_located(
                    (By.XPATH, '//div[@class="month-wrapper"]')))
            self.teacher.find(
                By.XPATH, "//div/label[contains(text(), '" + assignment_name +
                "')]").click()
        self.teacher.wait.until(
            expect.element_to_be_clickable(
                (By.XPATH, '//a[@class="get-link"]'))).click()
        self.teacher.wait.until(
            expect.presence_of_element_located(
                (By.XPATH, '//div[@class="popover-content"]' +
                 '//input[contains(@value,"https://tutor")]')))
        self.ps.test_updates['passed'] = True

    '''