Пример #1
0
    def element_find(self,
                     value='',
                     by='xpath',
                     action='click',
                     keys=[],
                     index=0,
                     wait=10,
                     element=None,
                     fail=False,
                     return_list=False,
                     target=None,
                     x=None,
                     y=None,
                     modifier_key=None,
                     logs=True):
        """
            Find the element at Xpath and perform action 
            @param    value (string) - The string value of the xpath to use in the search
            @param    by (string) - The type of action to perform, click or send_keys
            @param    action (string) - The type of action to perform, such as click, send_keys, clear, or none
            @param    keys (list, or Keys ENUM) - The keys to send or a Key ENUM such as ENTER or ARROW_UP
            @param    index (int) - The index of elements to select, since this always finds a list
            @param    wait (float) - The amount of time to wait for the element to be found
            @param    element (WebElement) - If passed, will use that element for the searches
            @param    fail (bool) - If set, element_find does not expect to find the element, and that is ok
            @param    return_list (bool) - Specifies whether or not to return as a list
            @param    target (WebElement) - Specifies where to drop an element that is being dragged
            @param    x (float) - The X parameter used if you use click_at
            @param    y (float) - The y parameter used if you use click_at
            @param    modifier_key (string) - the modifier key to hold while clicking ("control", "command", etc.)
            @param    logs (bool) - If False, will not log the debug statements
            (for situations like element_gone that would spam the logs)
            @return   WebDriver Element
        """
        by = self.sanitize(by)
        if logs:
            logger.debug("using by_%s to find element [%s]" % (by, value))
        # Will Try to find the element, which the element may not need to be found
        w_object = self
        if element is not None:
            w_object = element
        try:
            if by == 'class_name':
                element = WebDriverWait(w_object, wait).until(
                    lambda driver: w_object.find_elements_by_class_name(value))
            elif by == 'css_selector':
                element = WebDriverWait(
                    w_object, wait).until(lambda driver: w_object.
                                          find_elements_by_css_selector(value))
            elif by == 'id':
                element = WebDriverWait(w_object, wait).until(
                    lambda driver: w_object.find_elements_by_id(value))
            elif by == 'link_text':
                element = WebDriverWait(w_object, wait).until(
                    lambda driver: w_object.find_elements_by_link_text(value))
            elif by == 'partial_link_text':
                element = WebDriverWait(
                    w_object,
                    wait).until(lambda driver: w_object.
                                find_elements_by_partial_link_text(value))
            elif by == 'name':
                element = WebDriverWait(w_object, wait).until(
                    lambda driver: w_object.find_elements_by_name(value))
            elif by == 'tag':
                element = WebDriverWait(w_object, wait).until(
                    lambda driver: w_object.find_elements_by_tag_name(value))
            elif by == 'xpath':
                element = WebDriverWait(w_object, wait).until(
                    lambda driver: w_object.find_elements_by_xpath(value))
        except Exception:
            # If fail is false, then not finding the element is unexpected
            if return_list:
                return []
            if not fail:
                raise TimeoutException("Value: %s, by: %s, wait: %s" %
                                       (value, by, wait))
            elif fail:
                return
        # If fail is set and we found the element, this has failed, as the element was not supposed to be there
        if fail:
            raise TimeoutException("Value: %s, by: %s, wait: %s" %
                                   (value, by, wait))
        # Found the element, now to sanitize the action and perform it
        # Note... none isn't an action, but wont match the if-elsif so is the default behavior of do nothing
        # Technically anything could get passed in that wasn't click, send_keys or clear and it will do nothing
        if logs:
            logger.debug("Found %d number of elements" % (len(element)))
        if return_list:
            return element

        action_chain = None
        # sanitize action
        if action is not None:
            action = self.sanitize(action)
            action_chain = ActionChains(self)

            if modifier_key:
                modifier_key = [
                    modifier_key
                ] if type(modifier_key) is not list else modifier_key
                for k in modifier_key:
                    action_chain.key_down(self.sanitize_modifier_key(k))

        # Click does not work with modifier keys, use click_action
        if action == 'click' and len(keys) == 0:
            element[index].click()
        # Use click action if you need to because you need the click in the correct place
        # in the action chain (because of modifier keys, etc.)
        elif action == 'click_action':
            action_chain.click(element[index])
        # FIREFOX DOESN'T WORK WITH CLICK_AT
        elif action == "click_at":
            action_chain.move_to_element_with_offset(element[index], x,
                                                     y).click()
        elif action == 'click_and_hold':
            action_chain.click_and_hold(element[index]).release(element[index])
        elif action == "double_click":
            action_chain.double_click(element[index])
        elif action == "right_click":
            action_chain.context_click(element[index])
        elif action == "drag_and_drop":
            action_chain.drag_and_drop(element[index], target)
        elif action == "drag_and_drop_by_offset":
            action_chain.drag_and_drop_by_offset(element[index], x, y)
        elif action == 'move_to_element':
            action_chain.move_to_element(element[index]).click()
        elif action == 'hover' or action == 'mouse_in':
            action_chain.move_to_element(element[index])
        elif action == 'send_keys':
            for val in keys:
                try:
                    logger.debug("sending [%s] to element" % value)
                    element[index].send_keys(val.decode('utf8'))
                except (UnicodeEncodeError, AttributeError):
                    element[index].send_keys(val)
                if len(keys) > 1 and not isinstance(keys, str):
                    sleep(0.1)
        elif action == 'clear':
            logger.debug("Clearing field")
            element[index].clear()
        elif action == 'select':
            element._setSelected()

        if action:
            if modifier_key:
                for k in modifier_key:
                    action_chain.key_up(self.sanitize_modifier_key(k))
            action_chain.perform()

        # ADDING THE ABILITY TO USE KEYS AFTER action == 'clear'
        if len(keys) > 0 and action != 'send_keys':
            for val in keys:
                try:
                    logger.debug("sending [%s] to element" % value)
                    element[index].send_keys(val.decode('utf8'))
                except (UnicodeEncodeError, AttributeError):
                    element[index].send_keys(val)
                if len(keys) > 1 and not isinstance(keys, str):
                    sleep(0.1)
        return element[index]