示例#1
0
    def get_page_content(self, index=0):
        """
        Get the contents of a page present at the index passed.

        Arguments:
            index (int): Index of page
        Returns:
            str: Content of page.
        """
        click_css(
            page=self,
            css='.action-button-text',
            source_index=index,
            require_notification=False
        )
        content = self.browser.execute_script(
            'return tinyMCE.activeEditor.getContent()'
        )
        click_css(
            page=self,
            css='.button.action-cancel',
            source_index=0,
            require_notification=False
        )
        return content
示例#2
0
 def cancel_upload(self):
     """
     Click 'cancel' on the file upload dialog.
     """
     click_css(
         self, '.button.action-cancel', 0, False
     )
示例#3
0
def upload_new_file(page, file_names):
    """
    Upload file(s).

    Arguments:
        page (PageObject): Page to upload file to.
        file_names (list): file name(s) we want to upload.
    """
    # Make file input field visible.
    file_input_css = '.file-input'
    page.browser.execute_script(
        '$("{}").css("display","block");'.format(file_input_css))
    page.wait_for_element_visibility(
        file_input_css, "Upload button is visible.")
    # Loop through each file and upload.
    for file_name in file_names:
        page.q(css=file_input_css).results[0].send_keys(
            UPLOAD_FILE_DIR + "/" + file_name)
        page.wait_for_element_visibility(
            '.progress-bar', 'Upload progress bar is visible.')
        page.wait_for(
            lambda: page.q(
                css='.progress-fill').text[0] == 'Upload completed',
            description='Upload complete.')
    # Close the upload prompt.
    click_css(page, '.close-button', 0, False)
    page.wait_for_element_invisibility(
        page.UPLOAD_FORM_CSS, 'New file upload prompt has been closed.')
示例#4
0
def add_advanced_component(page, menu_index, name):
    """
    Adds an instance of the advanced component with the specified name.

    menu_index specifies which instance of the menus should be used (based on vertical
    placement within the page).
    """
    # Click on the Advanced icon.
    page.wait_for_component_menu()
    click_css(page,
              'button>span.large-advanced-icon',
              menu_index,
              require_notification=False)

    # This does an animation to hide the first level of buttons
    # and instead show the Advanced buttons that are available.
    # We should be OK though because click_css turns off jQuery animations

    # Make sure that the menu of advanced components is visible before clicking (the HTML is always on the
    # page, but will have display none until the large-advanced-icon is clicked).
    page.wait_for_element_visibility('.new-component-advanced',
                                     'Advanced component menu is visible')

    # Now click on the component to add it.
    component_css = u'button[data-category={}]'.format(name)
    page.wait_for_element_visibility(
        component_css, u'Advanced component {} is visible'.format(name))

    # Adding some components, e.g. the Discussion component, will make an ajax call
    # but we should be OK because the click_css method is written to handle that.
    click_css(page, component_css, 0)
示例#5
0
 def view_live(self):
     """
     Clicks the "View Live" link and switches to the new tab
     """
     click_css(self, '.view-live-button', require_notification=False)
     self.wait_for_page()
     self.browser.switch_to_window(self.browser.window_handles[-1])
示例#6
0
def add_html_component(page, menu_index, boilerplate=None):
    """
    Adds an instance of the HTML component with the specified name.

    menu_index specifies which instance of the menus should be used (based on vertical
    placement within the page).
    """
    # Click on the HTML icon.
    page.wait_for_component_menu()
    click_css(page,
              'button>span.large-html-icon',
              menu_index,
              require_notification=False)

    # Make sure that the menu of HTML components is visible before clicking
    page.wait_for_element_visibility('.new-component-html',
                                     'HTML component menu is visible')

    # Now click on the component to add it.
    component_css = u'button[data-category=html]'
    if boilerplate:
        component_css += u'[data-boilerplate={}]'.format(boilerplate)
    else:
        component_css += u':not([data-boilerplate])'

    page.wait_for_element_visibility(
        component_css, u'HTML component {} is visible'.format(boilerplate))

    # Adding some components will make an ajax call but we should be OK because
    # the click_css method is written to handle that.
    click_css(page, component_css, 0)
示例#7
0
 def publish(self):
     """
     Publish the unit.
     """
     click_css(self, self._bounded_selector('.action-publish'), require_notification=False)
     modal = CourseOutlineModal(self)
     EmptyPromise(lambda: modal.is_shown(), 'Modal is shown.')  # pylint: disable=unnecessary-lambda
     modal.publish()
示例#8
0
 def write_update_and_save(self, new_update):
     """
     Write new update and save it.
     """
     type_in_codemirror(self, 0, new_update)
     click_css(self, '.save-button', 0, True)
     self.wait_for_element_invisibility('.new-update-form',
                                        'Update form is not visible')
示例#9
0
 def discard_changes(self):
     """
     Discards draft changes (which will then re-render the page).
     """
     self.scroll_to_element('a.action-discard')
     click_css(self, 'a.action-discard', 0, require_notification=False)
     confirm_prompt(self)
     self.wait_for_ajax()
示例#10
0
 def edit_course_update(self, course_update_edit_text, index=0):
     """
     Edit course update
     """
     click_css(self, '#course-update-view .edit-button', index, False)
     self.wait_for_element_presence(
         '.new-update-form', 'Update form has been opened')
     self.write_update_and_save(course_update_edit_text)
示例#11
0
 def write_update_and_save(self, new_update):
     """
     Write new update and save it.
     """
     type_in_codemirror(self, 0, new_update)
     click_css(self, '.save-button', 0, True)
     self.wait_for_element_invisibility(
         '.new-update-form', 'Update form is not visible')
示例#12
0
 def click_delete_update_button(self):
     """
     Clicks the delete update post button and confirms the delete notification.
     """
     click_css(self,
               '.post-preview .delete-button',
               require_notification=False)
     confirm_prompt(self)
示例#13
0
 def edit_course_update(self, course_update_edit_text, index=0):
     """
     Edit course update
     """
     click_css(self, '#course-update-view .edit-button', index, False)
     self.wait_for_element_presence('.new-update-form',
                                    'Update form has been opened')
     self.write_update_and_save(course_update_edit_text)
示例#14
0
 def click_take_me_there_link(self):
     """
     Click take me there link.
     """
     click_css(
         self,
         '#page-alert .alert.confirmation .nav-actions .action-secondary',
         require_notification=False)
示例#15
0
    def add_section_from_bottom_button(self, click_child_icon=False):
        """
        Clicks the button for adding a section which resides at the bottom of the screen.
        """
        element_css = self.BOTTOM_ADD_SECTION_BUTTON
        if click_child_icon:
            element_css += " .fa-plus"

        click_css(self, element_css)
示例#16
0
    def click_hint(self, hint_index=0):
        """
        Click the Hint button.

        Arguments:
            hint_index (int): Index of a displayed hint
        """
        click_css(self, '.problem .hint-button', require_notification=False)
        self.wait_for_focus_on_hint_notification(hint_index)
示例#17
0
 def open_new_update_form(self):
     """
     Open update form
     """
     self.wait_for_element_visibility(
         '.button.new-button.new-update-button', 'Update form visibility')
     click_css(self, '.button.new-button.new-update-button', 0, False)
     self.wait_for_element_presence('.new-update-form',
                                    'Update form has been opened')
示例#18
0
 def add_child(self, require_notification=True):
     """
     Adds a child to this xblock, waiting for notifications.
     """
     click_css(
         self,
         self._bounded_selector(self.ADD_BUTTON_SELECTOR),
         require_notification=require_notification,
     )
示例#19
0
 def click_edit_update_button(self):
     """
     Clicks the edit update post button.
     """
     click_css(self,
               '.post-preview .edit-button',
               require_notification=False)
     self.wait_for_element_visibility('.CodeMirror',
                                      'Waiting for .CodeMirror')
示例#20
0
def add_discussion(page, menu_index=0):
    """
    Add a new instance of the discussion category.

    menu_index specifies which instance of the menus should be used (based on vertical
    placement within the page).
    """
    page.wait_for_component_menu()
    click_css(page, 'button>span.large-discussion-icon', menu_index)
示例#21
0
 def open_new_update_form(self):
     """
     Open update form
     """
     self.wait_for_element_visibility(
         '.button.new-button.new-update-button', 'Update form visibility'
     )
     click_css(self, '.button.new-button.new-update-button', 0, False)
     self.wait_for_element_presence(
         '.new-update-form', 'Update form has been opened')
 def add_page(self):
     """
     Adds a new empty page.
     """
     click_css(page=self,
               css='.button.new-button.new-tab',
               source_index=0,
               require_notification=False)
     self.wait_for_element_visibility('.component.course-tab.is-movable',
                                      'New page is not visible')
示例#23
0
 def delete_course_update(self, index=0):
     """
     Delete a course update.
     """
     if self.get_course_update_count() > 0:
         click_css(self, '#course-update-view .delete-button', index, False)
         click_css(self, '.prompt.warning.has-actions .action-primary', 0,
                   True)
         self.wait_for_element_invisibility(
             '.prompt.warning.has-actions .action-primary',
             'Delete prompt is not visible')
示例#24
0
 def edit_course_handout(self, update_handout_text):
     """
     Edit course handout.
     """
     click_css(self, '#course-handouts-view .edit-button', 0, False)
     self.wait_for_element_visibility('.edit-handouts-form',
                                      'Handout edit form visible.')
     type_in_codemirror(self, 0, update_handout_text)
     click_css(self, '.save-button', 0, True)
     self.wait_for_element_invisibility('.edit-handouts-form',
                                        'Handout edit form is not visible')
示例#25
0
 def edit_course_handout(self, update_handout_text):
     """
     Edit course handout.
     """
     click_css(
         self, '#course-handouts-view .edit-button', 0, False)
     self.wait_for_element_visibility(
         '.edit-handouts-form', 'Handout edit form visible.')
     type_in_codemirror(self, 0, update_handout_text)
     click_css(self, '.save-button', 0, True)
     self.wait_for_element_invisibility(
         '.edit-handouts-form', 'Handout edit form is not visible')
示例#26
0
    def delete_page(self, index=0):
        """
        Deletes the page present at the index passed.

        Arguments:
            index (int): Index of page
        """
        click_css(page=self,
                  css='.delete-button.action-button',
                  source_index=index,
                  require_notification=False)
        self.q(css='.prompt.warning button.action-primary ').first.click()
        sync_on_notification(self)
示例#27
0
 def delete(self, source_index):
     """
     Delete the item with index source_index (based on vertical placement in page).
     Only visible items are counted in the source_index.
     The index of the first item is 0.
     """
     # Click the delete button
     click_css(self,
               '.delete-button',
               source_index,
               require_notification=False)
     # Click the confirmation dialog button
     confirm_prompt(self)
示例#28
0
 def delete_course_update(self, index=0):
     """
     Delete a course update.
     """
     if self.get_course_update_count() > 0:
         click_css(self, '#course-update-view .delete-button', index, False)
         click_css(
             self, '.prompt.warning.has-actions .action-primary', 0, True
         )
         self.wait_for_element_invisibility(
             '.prompt.warning.has-actions .action-primary',
             'Delete prompt is not visible'
         )
示例#29
0
 def add_static_page(self):
     """
     Adds a static page
     """
     total_tabs = len(self.q(css='.course-nav-list>li'))
     click_css(self, '.add-pages .new-tab', require_notification=False)
     self.wait_for(
         lambda: len(self.q(css='.course-nav-list>li')) == total_tabs + 1,
         description="Static tab is added"
     )
     self.wait_for_element_visibility(
         u'.tab-list :nth-child({}) .xblock-student_view'.format(total_tabs),
         'Static tab is visible'
     )
示例#30
0
    def click_leave_team_link(self, remaining_members=0, cancel=False):
        """ Click on Leave Team link"""
        leave_team_css = '.leave-team-link'
        self.scroll_to_element(leave_team_css)
        self.wait_for_element_visibility(leave_team_css,
                                         'Leave Team link is visible.')
        click_css(self, leave_team_css, require_notification=False)
        confirm_prompt(self, cancel, require_notification=False)

        if cancel is False:
            self.wait_for(
                lambda: self.join_team_button_present,
                description="Join Team button did not become present")
            self.wait_for_capacity_text(remaining_members)
示例#31
0
 def add_page(self):
     """
     Adds a new empty page.
     """
     self.wait_for_add_page_click_handler()
     click_css(
         page=self,
         css='.button.new-button.new-tab',
         source_index=0,
         require_notification=False
     )
     self.wait_for_element_visibility(
         '.component.course-tab.is-movable', 'New page is not visible'
     )
示例#32
0
    def delete_page(self, index=0):
        """
        Deletes the page present at the index passed.

        Arguments:
            index (int): Index of page
        """
        click_css(
            page=self,
            css='.delete-button.action-button',
            source_index=index,
            require_notification=False
        )
        self.q(css='.prompt.warning button.action-primary ').first.click()
        sync_on_notification(self)
示例#33
0
    def upload_image(self, file_name):
        """
        Upload image and add description and click save to upload image via TinyMCE editor.
        """
        file_input_css = "[type='file']"

        # select file input element and change visibility to add file.
        self.browser.execute_script(
            '$("{}").css("display","block");'.format(file_input_css))
        self.wait_for_element_visibility(file_input_css, "Input is visible")
        self.q(css=file_input_css).results[0].send_keys(file_name)
        self.wait_for_element_visibility('#imageDescription',
                                         'Upload form is visible.')

        self.q(css='#imageDescription').results[0].send_keys('test image')
        click_css(self, '.modal-footer .btn-primary')
示例#34
0
    def click_new_update_button(self):
        """
        Clicks the new-update button.
        """
        def is_update_button_enabled():
            """
            Checks if the New Update button is enabled
            """
            return self.q(
                css='.new-update-button').attrs('disabled')[0] is None

        self.wait_for(
            promise_check_func=is_update_button_enabled,
            description='Waiting for the New update button to be enabled.')
        click_css(self, '.new-update-button', require_notification=False)
        self.wait_for_element_visibility('.CodeMirror',
                                         'Waiting for .CodeMirror')
示例#35
0
    def edit_page(self, new_content, index=0):
        """
        Edits the page present at the index passed.

        Arguments:
            new_content (str): New content to set.
            index (int): Index of page
        """
        click_css(page=self,
                  css='.action-button-text',
                  source_index=index,
                  require_notification=False)
        self.browser.execute_script(
            'tinyMCE.activeEditor.setContent("{}")'.format(new_content))
        self.browser.execute_script(
            'document.querySelectorAll(".button.action-primary'
            '.action-save")[0].click();')
        sync_on_notification(self)
示例#36
0
    def toggle_staff_lock(self, inherits_staff_lock=False):
        """
        Toggles "hide from students" which enables or disables a staff-only lock.

        Returns True if the lock is now enabled, else False.
        """
        was_locked_initially = self.is_staff_locked
        if not was_locked_initially:
            self.q(css='a.action-staff-lock').first.click()
        else:
            click_css(self,
                      'a.action-staff-lock',
                      0,
                      require_notification=False)
            if not inherits_staff_lock:
                confirm_prompt(self)
        self.wait_for_ajax()
        return not was_locked_initially
示例#37
0
 def upload_tarball(self, tarball_filename):
     """
     Upload a tarball to be imported.
     """
     asset_file_path = self.file_path(tarball_filename)
     # Make the upload elements visible to the WebDriver.
     self.browser.execute_script(
         '$(".file-name-block").show();$(".file-input").show()')
     # Upload the file.
     self.q(css='input[type="file"]')[0].send_keys(asset_file_path)
     # Upload the same file again. Reason behind this is to decrease the
     # probability or fraction of times the failure occur. Please be
     # noted this doesn't eradicate the root cause of the error, it
     # just decreases to failure rate to minimal.
     # Jira ticket reference: TNL-4191.
     self.q(css='input[type="file"]')[0].send_keys(asset_file_path)
     # Some of the tests need these lines to pass so don't remove them.
     self._wait_for_button()
     click_css(self, '.submit-button', require_notification=True)
示例#38
0
    def get_page_content(self, index=0):
        """
        Get the contents of a page present at the index passed.

        Arguments:
            index (int): Index of page
        Returns:
            str: Content of page.
        """
        click_css(page=self,
                  css='.action-button-text',
                  source_index=index,
                  require_notification=False)
        content = self.browser.execute_script(
            'return tinyMCE.activeEditor.getContent()')
        click_css(page=self,
                  css='.button.action-cancel',
                  source_index=0,
                  require_notification=False)
        return content
示例#39
0
    def edit_page(self, new_content, index=0):
        """
        Edits the page present at the index passed.

        Arguments:
            new_content (str): New content to set.
            index (int): Index of page
        """
        click_css(
            page=self,
            css='.action-button-text',
            source_index=index,
            require_notification=False
        )
        self.browser.execute_script(
            'tinyMCE.activeEditor.setContent("{}")'.format(new_content)
        )
        self.browser.execute_script(
            'document.querySelectorAll(".button.action-primary'
            '.action-save")[0].click();'
        )
        sync_on_notification(self)