Exemplo n.º 1
0
        def rename_section(self, name=None):
            """Rename a current course section or period.

            .. note::

               If the name matches an existing section (case-sensitive), an
               HTML 422 error will be thrown by Tutor; server errors are not
               handled by the automation code.

            If name is not provided, open and return the Rename Section modal.
            If it is provided, rename the current section or period and return
            the course roster.

            :param str name: (optional) the section or period name
            :return: the Rename Section modal if name is not provided or the
                course roster if name is provided
            :rtype: :py:class:`RenameSection` or :py:class:`CourseRoster`

            """
            link = self.find_element(*self._rename_section_link_locator)
            Utility.click_option(self.driver, element=link)
            sleep(0.5)
            dialog_root = self.driver.execute_script(GET_ROOT.format('dialog'))
            modal = RenameSection(self.page, dialog_root)
            if not name:
                return modal
            Utility.clear_field(self.driver, field=modal.section_name)
            modal.section_name = name
            return modal.rename()
Exemplo n.º 2
0
    def add(self) -> Page:
        """Add a new log in method to the account.

        :return: the password setup page, the Facebook log in page or the
            Google log in page
        :rtype: :py:class:`~pages.accounts.reset.SetPassword`,
            :py:class:`~pages.facebook.home.Facebook`, or
            :py:class:`~pages.google.home.Google`

        """
        provider = self.name.lower()
        base_url = None
        if 'password' in provider:
            from pages.accounts.reset import SetPassword
            Destination = SetPassword
            base_url = Utility.parent_page(self).base_url
        elif 'facebook' in provider:
            from pages.facebook.home import Facebook
            Destination = Facebook
        else:
            from pages.google.home import Google
            Destination = Google
        button = self.find_element(*self._add_button_locator)
        Utility.click_option(self.driver, element=button)
        return go_to_(Destination(self.driver, base_url=base_url))
Exemplo n.º 3
0
                def search_for(self, topic: str) \
                        -> List[Profile.Console.PopupConsole.Users.Result]:
                    r"""Use the pop up console to search for a given string.

                    :param str topic: the search string
                    :return: the list of users matching the search string
                    :rtype: list(:py:class:`~pages.accounts.profile. \
                                            Profile.Console.PopupConsole. \
                                            Users.Result`)

                    """
                    results_list = self.find_element(
                        *self._results_list_root_locator)
                    self.find_element(*self._search_bar_locator) \
                        .send_keys(topic)
                    search_button = self.find_element(
                        *self._search_button_locator)
                    Utility.click_option(self.driver, element=search_button)
                    try:
                        self.wait.until(
                            lambda _: Utility.has_children(results_list))
                    except TimeoutException:
                        raise AccountsException('search not completed')
                    return [
                        self.Result(self, line) for line in self.find_elements(
                            *self._search_result_row_locator)
                    ]
Exemplo n.º 4
0
 def learn_more(self):
     """Click the 'Learn More' button."""
     Utility.click_option(
         self.driver,
         element=self.find_element(*self._how_it_works_locator))
     sleep(0.75)
     return self.page
Exemplo n.º 5
0
 def _selection_helper(self, locator, destination):
     """Menu option helper for duplicated actions."""
     if not self.is_open:
         self.open()
     target = self.find_element(*locator)
     Utility.click_option(self.driver, element=target)
     return go_to_(destination(self.driver))
Exemplo n.º 6
0
 def view_errata(self):
     """View the errata item in detail."""
     Utility.click_option(self.driver, element=self.errata)
     return go_to_(
         ErrataDetail(self.driver,
                      base_url=self.base_url,
                      _id=self.errata_id))
Exemplo n.º 7
0
 def toggle(self):
     """Open or close a nav menu."""
     Utility.scroll_top(self.driver)
     menu = self.find_element(*self._toggle_locator)
     Utility.click_option(self.driver, element=menu)
     sleep(0.15)
     return self
Exemplo n.º 8
0
    def i_agree(self) -> Union[BuyAccess, StudentCourse]:
        """Click on the 'I agree' button.

        After clicking on the I agree button, one of two destinations are
        possible:

            1. the student course page with the product purchase modal open for
               paid courses
            #. the student course page without a modal open for existing
               students in a free course

        :return: the course page with the product purchase modal displayed
        :rtype: :py:class:`~pages.tutor.enrollment.BuyAccess` or
            :py:class:`~pages.tutor.course.StudentCourse`

        """
        button = self.find_element(*self._i_agree_button_locator)
        Utility.click_option(self.driver, element=button)
        sleep(1.25)
        course = StudentCourse(self.driver, base_url=self.page.base_url)
        dialog_root = self.driver.execute_script(GET_ROOT.format('document'))
        if (dialog_root
                and 'pay-now-or-later' in dialog_root.get_attribute('class')):
            return BuyAccess(course, dialog_root)
        return go_to_(course)
Exemplo n.º 9
0
    def purchase(self) -> Union[PurchaseConfirmation]:
        """Click on the 'Purchase' Tutor button.

        :return: the purchase confirmation modal or the error message for a
            failed transaction
        :rtype: :py:class:`~pages.tutor.enrollment.PurchaseConfirmation`
        :raises: :py:class:`~utils.tutor.TutorException` if error messages are
            found

        """
        purchase = self.find_element(*self._base_iframe_locator)
        self.driver.switch_to.frame(purchase)
        button = self.wait.until(
            expect.presence_of_element_located(self._purchase_button_locator))
        sleep(0.25)
        is_not_chrome = not Utility.is_browser(self.driver, 'chrome')
        Utility.click_option(self.driver,
                             element=button,
                             force_js_click=is_not_chrome)
        sleep(1)
        self.driver.switch_to.default_content()
        errors = self.error_messages
        if errors:
            raise TutorException(errors)
        return PurchaseConfirmation(self.page)
Exemplo n.º 10
0
 def view_tutor_data(self):
     """View user information on Tutor."""
     if 'Tutor' in self.app:
         user = self.find_element(*self._view_app_user_info_locator)
         Utility.click_option(self.driver, element=user)
         from pages.tutor.admin.users import Details as TutorDetails
         return go_to_(TutorDetails(self.driver))
Exemplo n.º 11
0
 def go_to_student_learning(self):
     """Follow the improving student learning link."""
     learning = self.find_element(*self._tutor_marketing_link_locator)
     Utility.click_option(self.driver, element=learning)
     from pages.web.tutor import TutorMarketing
     return go_to_(
         TutorMarketing(self.driver, base_url=self.page.base_url))
Exemplo n.º 12
0
        def copy_this_course(self):
            """Clone the selected course.

            :return: the course cloning wizard
            :rtype: :py:class:`~pages.tutor.new_course.CloneCourse`

            """
            assert(self.is_teacher), \
                "Only verified instructors may clone a course"
            assert(not self.is_preview), \
                "Preview courses may not be cloned"
            if Utility.is_browser(self.driver, 'safari'):
                button = self.find_element(By.CSS_SELECTOR, '.btn-sm')
                Utility.click_option(self.driver, element=button)
            else:
                from selenium.webdriver.common.action_chains import \
                    ActionChains
                Utility.scroll_to(self.driver, element=self.root, shift=-80)
                ActionChains(self.driver) \
                    .move_to_element(self.course_brand) \
                    .pause(1) \
                    .move_to_element(
                        self.find_element(By.CSS_SELECTOR, '.btn-sm')) \
                    .pause(1) \
                    .click() \
                    .perform()
            from pages.tutor.new_course import CloneCourse
            return go_to_(CloneCourse(self.driver, self.page.page.base_url))
Exemplo n.º 13
0
            def click(self):
                """Go to the banner link destination.

                Return a 'Destination' so the function will fail if
                a new banner link is added.
                """
                destination = self.destination
                parent = self.page
                while not isinstance(parent, Page):
                    parent = parent.page
                base_url = parent.base_url
                if destination.endswith(Web.SUBJECTS):
                    from pages.web.subjects import Subjects as Destination
                elif destination.endswith(Web.ABOUT):
                    from pages.web.about import AboutUs as Destination
                elif destination.endswith(Web.SE_APP):
                    from pages.web.se_app import StudyEdge as Destination
                elif destination.endswith(Web.GLOBAL_REACH):
                    from pages.web.reach import GlobalReach as Destination
                elif destination.endswith(Web.ONLINE_RESOURCES):
                    from pages.web.online_resources \
                        import OnlineResources as Destination
                else:
                    raise WebException(
                        'Unknown destination: {0}'
                        .format(self.destination.split('/')[-1]))
                Utility.click_option(self.driver, element=self.root)
                return go_to_(Destination(self.driver, base_url=base_url))
Exemplo n.º 14
0
            def student_id(self, _id=None):
                """Set the student's identification number.

                :param str _id: (optional) the student's new ID number; if _id
                    is '' or None, the field will be cleared
                :return: the course roster
                :rtype: :py:class:`CourseRoster`

                """
                from selenium.webdriver.common.keys import Keys
                edit_button = self.find_element(*self._edit_student_id_locator)
                Utility.click_option(self.driver, element=edit_button)
                sleep(0.25)
                id_field = self.find_element(
                    *self._student_id_input_box_locator)
                Utility.clear_field(self.driver, field=id_field)
                if _id:
                    edit_button = self.find_element(
                        *self._edit_student_id_locator)
                    Utility.click_option(self.driver, element=edit_button)
                    sleep(0.25)
                    id_field = self.find_element(
                        *self._student_id_input_box_locator)
                    id_field.send_keys(_id)
                id_field.send_keys(Keys.TAB)
                return self.page.page
Exemplo n.º 15
0
        def _add_assignment(self, assignment_type):
            """Click on an add assignment button.

            An internal helper function to select a new assignment.

            :param str assignment_type: the type of assignment to add
            :return: an assignment creation page
            :rtype: :py:class:`~pages.tutor.assignment.AddExternal` or
                :py:class:`~pages.tutor.assignment.AddEvent` or
                :py:class:`~pages.tutor.assignment.AddHomework` or
                :py:class:`~pages.tutor.assignment.AddReading`
            :raises :py:class:`~utils.tutor.TutorException`: if the
                assignment_type does not match a known assignment type

            :noindex:

            """
            if assignment_type == Tutor.EXTERNAL:
                locator = self._add_external_locator
                from pages.tutor.assignment import External as Assignment
            elif assignment_type == Tutor.EVENT:
                locator = self._add_event_locator
                from pages.tutor.assignment import Event as Assignment
            elif assignment_type == Tutor.HOMEWORK:
                locator = self._add_homework_locator
                from pages.tutor.assignment import Homework as Assignment
            elif assignment_type == Tutor.READING:
                locator = self._add_reading_locator
                from pages.tutor.assignment import Reading as Assignment
            else:
                raise TutorException('"{0}" is not a known assignment type.'
                                     .format(assignment_type))
            button = self.find_element(*locator)
            Utility.click_option(self.driver, element=button)
            return go_to_(Assignment(self.driver, self.page.base_url))
Exemplo n.º 16
0
    def select_assignment(self, name: str, _type: str = None):
        """Click on an assignment.

        :param str name: the assignment's name
        :param str _type: (optional) the assignment's type
        :return: the assignment task page(s)
        :rtype: :py:class:`~pages.tutor.task.Assignment`

        """
        for assignment in self.find_elements(*self._assignment_link_locator):
            if name in assignment.get_attribute('textContent'):
                description = assignment.get_attribute('class')
                if _type and _type not in description:
                    continue
                if Tutor.EVENT in description:
                    from pages.tutor.task import Event as Destination
                elif Tutor.EXTERNAL in description:
                    from pages.tutor.task import EXTERNAL as Destination
                elif Tutor.HOMEWORK in description:
                    from pages.tutor.task import Homework as Destination
                elif Tutor.READING in description:
                    from pages.tutor.task import Reading as Destination
                else:
                    raise TutorException(
                        f'Unknown assignment type in "{description}"')
                Utility.click_option(self.driver, element=assignment)
                sleep(1)
                return go_to_(Destination(self.driver, self.base_url))
        raise TutorException(f'"{name}" not found in the currently ' +
                             'available assignments')
Exemplo n.º 17
0
    def _remove_user(self, student=True, return_tooltip=False):
        """Remove the user from the course.

        :param bool student: (optional) use the Drop Student tooltip if
            ``True`` and the Remove Instructor tooltip if ``False``
        :param bool return_tooltip: (optional) don't drop the user; click the
            'Remove' or 'Drop' button to open the tooltip and return the pop up
        :return: None or the open tooltip
        :rtype: NoneType or :py:class:`Tooltip`

        """
        locator = self._remove_student_user_locator if student \
            else self._remove_instructor_user_locator
        button = self.find_element(*locator)
        Utility.click_option(self.driver, element=button)
        tooltip_root = self.driver.execute_script(GET_ROOT.format('tooltip'))
        if student:
            popup = DropStudent(self, tooltip_root)
            if return_tooltip:
                return popup
            popup.drop()
        else:
            popup = RemoveInstructor(self, tooltip_root)
            if return_tooltip:
                return popup
            popup.remove()
Exemplo n.º 18
0
            def select(self) -> None:
                """Click on the course option.

                :return: None

                """
                Utility.click_option(self.driver, element=self.root)
Exemplo n.º 19
0
        def _continue(self, previous: Page = None, base_url: str = None,
                      **kwargs) \
                -> Page:
            """Click the Continue button.

            :param Page previous: (optional) the Page object for the initial
                page that sent the log in request
            :param str base_url: (optional) the base URL for the previous Page
            :param kwargs: (optional) additional keyword arguments for the Page
            :return: the log in page if there is an error, the profile page if
                remaining on Accounts, the terms of use or privacy policy if a
                new policy is available, or the previous page if logging on to
                another OpenStax resource (like Tutor or OpenStax.org)
            :rtype: :py:class:`~pypom.Page`

            """
            current_page = self.page.location
            button = self.find_element(*self._continue_button_locator)
            Utility.click_option(self.driver, element=button)
            sleep(0.75)
            if self.driver.current_url == current_page:
                raise AccountsException(
                    self.driver.execute_script(
                        'return document.querySelector(".invalid-message")'
                        '.textContent;'))
            if previous:
                return go_to_(previous(self.driver, base_url, **kwargs))
            source = self.driver.page_source
            policies = 'Terms of Use' in source or 'Privacy policy' in source
            if 'accounts' in self.page.location and policies:
                from pages.accounts.legal import AcceptTerms
                return go_to_(AcceptTerms(self.driver, self.page.base_url))
            return go_to_(Profile(self.driver, self.page.base_url))
Exemplo n.º 20
0
 def view_course_settings(self):
     """Click on the 'Course settings' link if there are no students."""
     if self.no_students:
         link = self.find_element(*self._course_settings_locator)
         Utility.click_option(self.driver, element=link)
         from pages.tutor.settings import CourseSettings
         return go_to_(CourseSettings(self.driver, self.page.base_url))
Exemplo n.º 21
0
 def submit(self):
     """Click the Submit form button."""
     button = self.find_element(*self._submit_button_locator)
     Utility.scroll_to(self.driver, element=button, shift=-80)
     Utility.click_option(self.driver, element=button)
     sleep(1.0)
     return self
Exemplo n.º 22
0
 def back(self):
     """Click the Back button."""
     button = self.find_element(*self._back_button_locator)
     Utility.scroll_to(self.driver, element=button, shift=-80)
     Utility.click_option(self.driver, element=button)
     sleep(1.0)
     return self
Exemplo n.º 23
0
 def go_back(self, destination=WebBase, url=None):
     """Click the student GO BACK button."""
     back_button = self.find_element(*self._go_back_button_locator)
     Utility.click_option(self.driver, element=back_button)
     if url:
         return go_to_(destination(self.driver, url=url))
     return go_to_(destination(self.driver))
Exemplo n.º 24
0
 def send(self):
     """Submit the contact message."""
     button = self.find_element(*self._send_locator)
     Utility.click_option(self.driver, element=button)
     issues = self.errors
     if issues:
         return issues
     return go_to_(ContactConfirmation(self.driver, self.page.base_url))
Exemplo n.º 25
0
        def select(self) -> None:
            """Select the answer response.

            :return: None

            """
            Utility.click_option(self.driver, element=self.root)
            self.wait.until(lambda _: (not self.page.is_displayed()))
Exemplo n.º 26
0
    def back(self) -> None:
        """Go to the previous step in the wizard.

        :return: None

        """
        button = self.find_element(*self._back_button_locator)
        Utility.click_option(self.driver, element=button)
Exemplo n.º 27
0
            def select(self) -> None:
                """Click on the book option.

                :return: None

                """
                book = self.find_element(*self._book_content_locator)
                Utility.click_option(self.driver, element=book)
Exemplo n.º 28
0
    def cancel(self) -> None:
        """Cancel the course creation wizard.

        :return: None

        """
        button = self.find_element(*self._cancel_button_locator)
        Utility.click_option(self.driver, element=button)
Exemplo n.º 29
0
            def select(self) -> None:
                """Click on the term option.

                :return: None

                """
                button = self.find_element(*self._option_locator)
                Utility.click_option(self.driver, element=button)
Exemplo n.º 30
0
 def view_newer_releases(self):
     """View newer OpenStax press releases."""
     if not self.viewing_fewer_releases:
         switch = self.find_element(*self._newer_releases_locator)
         if 'presentation' not in switch.get_attribute('role'):
             # there is another pagination group of older or newer links
             Utility.click_option(self.driver, element=switch)
     return self