• splinter webdriver API 的基本实现


    # -*- coding: utf-8 -*-
    
    # Copyright 2012 splinter authors. All rights reserved.
    # Use of this source code is governed by a BSD-style
    # license that can be found in the LICENSE file.
    
    from __future__ import with_statement
    import logging
    import subprocess
    import time
    import re
    from contextlib import contextmanager
    
    from selenium.common.exceptions import NoSuchElementException
    from selenium.webdriver.common.action_chains import ActionChains
    
    from splinter.driver import DriverAPI, ElementAPI
    from splinter.element_list import ElementList
    from splinter.utils import warn_deprecated
    from tempfile import TemporaryFile
    
    
    class BaseWebDriver(DriverAPI):
        old_popen = subprocess.Popen
    
        def __init__(self, wait_time=2):
            self.wait_time = wait_time
    
        def _patch_subprocess(self):
            loggers_to_silence = [
                'selenium.webdriver.firefox.extension_connection',
                'selenium.webdriver.remote.remote_connection',
                'selenium.webdriver.remote.utils',
            ]
    
            class MutedHandler(logging.Handler):
                pass
    
            for name in loggers_to_silence:
                logger = logging.getLogger(name)
                logger.addHandler(MutedHandler())
                logger.setLevel(99999)
    
            # selenium is such a verbose guy let's make it open the
            # browser without showing all the meaningless output
            def MyPopen(*args, **kw):
                kw['stdout'] = TemporaryFile()
                kw['stderr'] = TemporaryFile()
                kw['close_fds'] = True
                return self.old_popen(*args, **kw)
    
            subprocess.Popen = MyPopen
    
        def _unpatch_subprocess(self):
            # cleaning up the house
            subprocess.Popen = self.old_popen
    
        def __enter__(self):
            return self
    
        def __exit__(self, exc_type, exc_value, traceback):
            self.quit()
    
        @property
        def title(self):
            return self.driver.title
    
        @property
        def html(self):
            return self.driver.page_source
    
        @property
        def url(self):
            return self.driver.current_url
    
        def visit(self, url):
            self.connect(url)
            self.ensure_success_response()
            self.driver.get(url)
    
        def back(self):
            self.driver.back()
    
        def forward(self):
            self.driver.forward()
    
        def reload(self):
            self.driver.refresh()
    
        def execute_script(self, script):
            self.driver.execute_script(script)
    
        def evaluate_script(self, script):
            return self.driver.execute_script("return %s" % script)
    
        def is_element_present(self, finder, selector, wait_time=None):
            wait_time = wait_time or self.wait_time
            end_time = time.time() + wait_time
    
            while time.time() < end_time:
                if finder(selector):
                    return True
            return False
    
        def is_element_not_present(self, finder, selector, wait_time=None):
            wait_time = wait_time or self.wait_time
            end_time = time.time() + wait_time
    
            while time.time() < end_time:
                if not finder(selector):
                    return True
            return False
    
        def is_element_present_by_css(self, css_selector, wait_time=None):
            return self.is_element_present(self.find_by_css, css_selector, wait_time)
    
        def is_element_not_present_by_css(self, css_selector, wait_time=None):
            return self.is_element_not_present(self.find_by_css, css_selector, wait_time)
    
        def is_element_present_by_xpath(self, xpath, wait_time=None):
            return self.is_element_present(self.find_by_xpath, xpath, wait_time)
    
        def is_element_not_present_by_xpath(self, xpath, wait_time=None):
            return self.is_element_not_present(self.find_by_xpath, xpath, wait_time)
    
        def is_element_present_by_tag(self, tag, wait_time=None):
            return self.is_element_present(self.find_by_tag, tag, wait_time)
    
        def is_element_not_present_by_tag(self, tag, wait_time=None):
            return self.is_element_not_present(self.find_by_tag, tag, wait_time)
    
        def is_element_present_by_name(self, name, wait_time=None):
            return self.is_element_present(self.find_by_name, name, wait_time)
    
        def is_element_not_present_by_name(self, name, wait_time=None):
            return self.is_element_not_present(self.find_by_name, name, wait_time)
    
        def is_element_present_by_value(self, value, wait_time=None):
            return self.is_element_present(self.find_by_value, value, wait_time)
    
        def is_element_not_present_by_value(self, value, wait_time=None):
            return self.is_element_not_present(self.find_by_value, value, wait_time)
    
        def is_element_present_by_id(self, id, wait_time=None):
            return self.is_element_present(self.find_by_id, id, wait_time)
    
        def is_element_not_present_by_id(self, id, wait_time=None):
            return self.is_element_not_present(self.find_by_id, id, wait_time)
    
        def get_alert(self):
            return AlertElement(self.driver.switch_to_alert())
    
        def is_text_present(self, text, wait_time=None):
            wait_time = wait_time or self.wait_time
            end_time = time.time() + wait_time
    
            while time.time() < end_time:
                try:
                    self.driver.find_element_by_tag_name('body').text.index(text)
                    return True
                except ValueError:
                    pass
            return False
    
        def is_text_not_present(self, text, wait_time=None):
            wait_time = wait_time or self.wait_time
            end_time = time.time() + wait_time
    
            while time.time() < end_time:
                try:
                    self.driver.find_element_by_tag_name('body').text.index(text)
                except ValueError:
                    return True
            return False
    
        @contextmanager
        def get_iframe(self, id):
            self.driver.switch_to_frame(id)
            try:
                yield self
            finally:
                self.driver.switch_to_frame(None)
    
        def find_option_by_value(self, value):
            return self.find_by_xpath('//option[@value="%s"]' % value, original_find="option by value", original_query=value)
    
        def find_option_by_text(self, text):
            return self.find_by_xpath('//option[normalize-space(text())="%s"]' % text, original_find="option by text", original_query=text)
    
        def find_link_by_href(self, href):
            return self.find_by_xpath('//a[@href="%s"]' % href, original_find="link by href", original_query=href)
    
        def find_link_by_partial_href(self, partial_href):
            return self.find_by_xpath('//a[contains(@href, "%s")]' % partial_href, original_find="link by partial href", original_query=partial_href)
    
        def find_link_by_partial_text(self, partial_text):
            return self.find_by_xpath('//a[contains(text(), "%s")]' % partial_text, original_find="link by partial text", original_query=partial_text)
    
        def find_link_by_text(self, text):
            return self.find_by_xpath('//a[text()="%s"]' % text, original_find="link by text", original_query=text)
    
        def find_by(self, finder, selector, original_find=None, original_query=None):
            elements = None
            end_time = time.time() + self.wait_time
    
            func_name = finder.im_func.func_name
            find_by = original_find or func_name[func_name.rfind('_by_') + 4:]
            query = original_query or selector
    
            while time.time() < end_time:
                try:
                    elements = finder(selector)
                    if not isinstance(elements, list):
                        elements = [elements]
                except NoSuchElementException:
                    pass
    
                if elements:
                    return ElementList([self.element_class(element, self) for element in elements], find_by=find_by, query=query)
            return ElementList([], find_by=find_by, query=query)
    
        def find_by_css(self, css_selector):
            return self.find_by(self.driver.find_elements_by_css_selector, css_selector, original_find='css', original_query=css_selector)
    
        def find_by_xpath(self, xpath, original_find=None, original_query=None):
            original_find = original_find or "xpath"
            original_query = original_query or xpath
            return self.find_by(self.driver.find_elements_by_xpath, xpath, original_find=original_find, original_query=original_query)
    
        def find_by_name(self, name):
            return self.find_by(self.driver.find_elements_by_name, name)
    
        def find_by_tag(self, tag):
            return self.find_by(self.driver.find_elements_by_tag_name, tag)
    
        def find_by_value(self, value):
            return self.find_by_xpath('//*[@value="%s"]' % value, original_find='value', original_query=value)
    
        def find_by_id(self, id):
            return self.find_by(self.driver.find_element_by_id, id)
    
        def fill(self, name, value):
            field = self.find_by_name(name).first
            field.value = value
    
        attach_file = fill
    
        def fill_form(self, field_values):
            for name, value in field_values.items():
                elements = self.find_by_name(name)
                element = elements.first
                if element['type'] == 'text' or element.tag_name == 'textarea':
                    element.value = value
                elif element['type'] == 'checkbox':
                    if value:
                        element.check()
                    else:
                        element.uncheck()
                elif element['type'] == 'radio':
                    for field in elements:
                        if field.value == value:
                            field.click()
                elif element._element.tag_name == 'select':
                    element.find_by_value(value).first._element.click()
    
        def type(self, name, value, slowly=False):
            element = self.driver.find_element_by_css_selector('input[name="%s"]' % name)
            if slowly:
                return TypeIterator(element, value)
            element.send_keys(value)
            return value
    
        def choose(self, name, value):
            fields = self.find_by_name(name)
            for field in fields:
                if field.value == value:
                    field.click()
    
        def check(self, name):
            self.find_by_name(name).first.check()
    
        def uncheck(self, name):
            self.find_by_name(name).first.uncheck()
    
        def select(self, name, value):
            self.find_by_xpath('//select[@name="%s"]/option[@value="%s"]' % (name, value)).first._element.click()
    
        def quit(self):
            self.driver.quit()
    
        @property
        def cookies(self):
            return self._cookie_manager
    
    
    class TypeIterator(object):
    
    
        def __init__(self, element, keys):
            self._element = element
            self._keys = keys
    
        def __iter__(self):
            for key in self._keys:
                self._element.send_keys(key)
                yield key
    
    
    class WebDriverElement(ElementAPI):
    
        def __init__(self, element, parent):
            self._element = element
            self.parent = parent
            self.action_chains = ActionChains(parent.driver)
    
        def _get_value(self):
            return self["value"] or self._element.text
    
        def _set_value(self, value):
            if self._element.get_attribute('type') != 'file':
                self._element.clear()
            self._element.send_keys(value)
    
        value = property(_get_value, _set_value)
    
        @property
        def text(self):
            return self._element.text
    
        @property
        def tag_name(self):
            return self._element.tag_name
    
        def fill(self, value):
            self.value = value
    
        def type(self, value, slowly=False):
            if slowly:
                return TypeIterator(self._element, value)
    
            self._element.send_keys(value)
            return value
    
        def click(self):
            self._element.click()
    
        def check(self):
            if not self.checked:
                self._element.click()
    
        def uncheck(self):
            if self.checked:
                self._element.click()
    
        @property
        def checked(self):
            return self._element.is_selected()
    
        selected = checked
    
        @property
        def visible(self):
            return self._element.is_displayed()
    
        def find_by_css(self, selector, original_find=None, original_query=None):
            find_by = original_find or 'css'
            query = original_query or selector
    
            elements = self._element.find_elements_by_css_selector(selector)
            return ElementList([self.__class__(element, self.parent) for element in elements], find_by=find_by, query=query)
    
        def find_by_xpath(self, selector):
            elements = ElementList(self._element.find_elements_by_xpath(selector))
            return ElementList([self.__class__(element, self.parent) for element in elements], find_by='xpath', query=selector)
    
        def find_by_name(self, name):
            elements = ElementList(self._element.find_elements_by_name(name))
            return ElementList([self.__class__(element, self.parent) for element in elements], find_by='name', query=name)
    
        def find_by_tag(self, tag):
            elements = ElementList(self._element.find_elements_by_tag_name(tag))
            return ElementList([self.__class__(element, self.parent) for element in elements], find_by='tag', query=tag)
    
        def find_by_value(self, value):
            selector = '[value="%s"]' % value
            return self.find_by_css(selector, original_find='value', original_query=value)
    
        def find_by_id(self, id):
            elements = ElementList(self._element.find_elements_by_id(id))
            return ElementList([self.__class__(element, self.parent) for element in elements], find_by='id', query=id)
    
        def has_class(self, class_name):
            element_class_name = self._element.get_attribute('class')
            return bool(re.search(r'(?:^|\s)' + re.escape(class_name) + r'(?:$|\s)', element_class_name))
    
        def mouse_over(self):
            """
            Performs a mouse over the element.
    
            Currently works only on Chrome driver.
            """
            self.action_chains.move_to_element(self._element)
            self.action_chains.perform()
    
        def mouse_out(self):
            """
            Performs a mouse out the element.
    
            Currently works only on Chrome driver.
            """
            self.action_chains.move_by_offset(5000, 5000)
            self.action_chains.perform()
    
        mouseover = warn_deprecated(mouse_over, 'mouseover')
        mouseout = warn_deprecated(mouse_out, 'mouseout')
    
        def double_click(self):
            """
            Performs a double click in the element.
    
            Currently works only on Chrome driver.
            """
            self.action_chains.double_click(self._element)
            self.action_chains.perform()
    
        def right_click(self):
            """
            Performs a right click in the element.
    
            Currently works only on Chrome driver.
            """
            self.action_chains.context_click(self._element)
            self.action_chains.perform()
    
        def drag_and_drop(self, droppable):
            """
            Performs drag a element to another elmenet.
    
            Currently works only on Chrome driver.
            """
            self.action_chains.drag_and_drop(self._element, droppable._element)
            self.action_chains.perform()
    
        def __getitem__(self, attr):
            return self._element.get_attribute(attr)
    
    
    class AlertElement(object):
    
        def __init__(self, alert):
            self._alert = alert
            self.text = alert.text
    
        def accept(self):
            self._alert.accept()
    
        def dismiss(self):
            self._alert.dismiss()
    
        def fill_with(self, text):
            self._alert.send_keys(text)
    
        def __enter__(self):
            return self
    
        def __exit__(self, type, value, traceback):
            pass
  • 相关阅读:
    Java中的Java.lang.ThreadLocal类
    Java中线程的生命周期和状态
    Circular Linked List数据结构
    Linked List数据结构
    JVM如何工作
    JVM运行时数据区域
    queue数据结构
    stack数据结构
    Java中Set/HashSet的内部处理
    POJO,JavaBean 以及他们之间的区别
  • 原文地址:https://www.cnblogs.com/hzhida/p/2634553.html
Copyright © 2020-2023  润新知