Esempio n. 1
0
    def __init__(self, user_agent=None, wait_time=2):
        self.wait_time = wait_time
        self._history = []
        self._last_urls = []
        self._forms = {}

        self.links = FindLinks(self)
Esempio n. 2
0
    def __init__(self, wait_time=2):
        self.wait_time = wait_time
        self._browser = Browser()

        self._cookie_manager = CookieManager(self._browser)
        self._last_urls = []

        self.links = FindLinks(self)
Esempio n. 3
0
    def __init__(self, element, parent):
        self._element = element
        self.parent = parent

        self.driver = self.parent.driver
        self.wait_time = self.parent.wait_time
        self.element_class = self.parent.element_class

        self.links = FindLinks(self)
Esempio n. 4
0
    def __init__(self, driver=None, wait_time=2):
        self.wait_time = wait_time

        self.links = FindLinks(self)

        self.driver = driver

        self.element_class = WebDriverElement

        self._cookie_manager = CookieManager(self.driver)
Esempio n. 5
0
    def __init__(self, wait_time=2):
        self.wait_time = wait_time

        self.links = FindLinks(self)
Esempio n. 6
0
class BaseWebDriver(DriverAPI):
    driver = None
    find_by = find_by

    def __init__(self, wait_time=2):
        self.wait_time = wait_time

        self.links = FindLinks(self)

    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

    @property
    def status_code(self):
        raise NotImplementedError

    def visit(self, url):
        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, *args):
        return self.driver.execute_script(script, *args)

    def evaluate_script(self, script, *args):
        return self.driver.execute_script("return %s" % script, *args)

    def is_element_visible(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, wait_time=wait_time) and finder(
                    selector, wait_time=wait_time).visible:
                return True
        return False

    def is_element_not_visible(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:
            element = finder(selector, wait_time=0)
            if not element or (element and not element.visible):
                return True
        return False

    def is_element_visible_by_css(self, css_selector, wait_time=None):
        return self.is_element_visible(self.find_by_css, css_selector,
                                       wait_time)

    def is_element_not_visible_by_css(self, css_selector, wait_time=None):
        return self.is_element_not_visible(self.find_by_css, css_selector,
                                           wait_time)

    def is_element_visible_by_xpath(self, xpath, wait_time=None):
        return self.is_element_visible(self.find_by_xpath, xpath, wait_time)

    def is_element_not_visible_by_xpath(self, xpath, wait_time=None):
        return self.is_element_not_visible(self.find_by_xpath, xpath,
                                           wait_time)

    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, wait_time=wait_time):
                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, wait_time=0):
                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_text(self, text, wait_time=None):
        return self.is_element_present(self.find_by_text, text, wait_time)

    def is_element_not_present_by_text(self, text, wait_time=None):
        return self.is_element_not_present(self.find_by_text, text, 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, wait_time=None):
        wait_time = wait_time or self.wait_time

        try:
            alert = WebDriverWait(self.driver,
                                  wait_time).until(EC.alert_is_present())
            return alert
        except TimeoutException:
            return None

    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
            except NoSuchElementException:
                # This exception will be thrown if the body tag isn't present
                # This has occasionally been observed. Assume that the
                # page isn't fully loaded yet
                pass
            except StaleElementReferenceException:
                # This exception is sometimes thrown if the page changes
                # quickly
                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
            except NoSuchElementException:
                # This exception will be thrown if the body tag isn't present
                # This has occasionally been observed. Assume that the
                # page isn't fully loaded yet
                pass
            except StaleElementReferenceException:
                # This exception is sometimes thrown if the page changes
                # quickly
                pass
        return False

    @contextmanager
    def get_iframe(self, frame_reference):

        # If a WebDriverElement is provided, send the underlying element
        if isinstance(frame_reference, WebDriverElement):
            frame_reference = frame_reference._element

        self.driver.switch_to.frame(frame_reference)

        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):
        warnings.warn(
            'browser.find_link_by_href is deprecated.'
            ' Use browser.links.find_by_href instead.',
            FutureWarning,
        )
        return self.links.find_by_href(href)

    def find_link_by_partial_href(self, partial_href):
        warnings.warn(
            'browser.find_link_by_partial_href is deprecated.'
            ' Use browser.links.find_by_partial_href instead.',
            FutureWarning,
        )
        return self.links.find_by_partial_href(partial_href)

    def find_link_by_partial_text(self, partial_text):
        warnings.warn(
            'browser.find_link_by_partial_text is deprecated.'
            ' Use browser.links.find_by_partial_text instead.',
            FutureWarning,
        )
        return self.links.find_by_partial_text(partial_text)

    def find_link_by_text(self, text):
        warnings.warn(
            'browser.find_link_by_text is deprecated.'
            ' Use browser.links.find_by_text instead.',
            FutureWarning,
        )
        return self.links.find_by_text(text)

    def find_by_css(self, css_selector, wait_time=None):
        return self.find_by(
            self.driver.find_elements_by_css_selector,
            css_selector,
            original_find="css",
            original_query=css_selector,
            wait_time=wait_time,
        )

    def find_by_xpath(self,
                      xpath,
                      original_find=None,
                      original_query=None,
                      wait_time=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,
            wait_time=wait_time,
        )

    def find_by_name(self, name, wait_time=None):
        return self.find_by(
            self.driver.find_elements_by_name,
            name,
            wait_time=wait_time,
        )

    def find_by_tag(self, tag, wait_time=None):
        return self.find_by(
            self.driver.find_elements_by_tag_name,
            tag,
            wait_time=wait_time,
        )

    def find_by_value(self, value, wait_time=None):
        elem = self.find_by_xpath(
            '//*[@value="{}"]'.format(value),
            original_find="value",
            original_query=value,
            wait_time=wait_time,
        )
        if elem:
            return elem
        return self.find_by_xpath('//*[.="%s"]' % value)

    def find_by_text(self, text=None, wait_time=None):
        xpath_str = _concat_xpath_from_str(text)
        return self.find_by_xpath(
            xpath_str,
            original_find="text",
            original_query=text,
            wait_time=wait_time,
        )

    def find_by_id(self, id, wait_time=None):
        return self.find_by(
            self.driver.find_element_by_id,
            id,
            wait_time=wait_time,
        )

    def fill(self, name, value):
        field = self.find_by_name(name).first
        field.value = value

    attach_file = fill

    def fill_form(self, field_values, form_id=None, name=None):
        form = None

        if name is not None:
            form = self.find_by_name(name)
        if form_id is not None:
            form = self.find_by_id(form_id)

        for name, value in field_values.items():
            if form:
                elements = form.find_by_name(name)
            else:
                elements = self.find_by_name(name)
            element = elements.first
            if (element["type"] in ["text", "password", "tel"]
                    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.select(value)
            else:
                element.value = value

    def type(self, name, value, slowly=False):
        element = self.find_by_name(name).first._element
        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 screenshot(self, name="", suffix=".png", full=False):

        name = name or ""

        (fd, filename) = tempfile.mkstemp(prefix=name, suffix=suffix)
        # don't hold the file
        os.close(fd)

        if full:
            ori_window_size = self.driver.get_window_size()
            self.full_screen()

        self.driver.get_screenshot_as_file(filename)

        if full:
            self.recover_screen(ori_window_size)

        return filename

    def select(self, name, value):
        self.find_by_xpath('//select[@name="%s"]//option[@value="%s"]' %
                           (name, value)).first._element.click()

    def select_by_text(self, name, text):
        self.find_by_xpath('//select[@name="%s"]/option[text()="%s"]' %
                           (name, text)).first._element.click()

    def quit(self):
        try:
            self.driver.quit()
        except WebDriverException:
            pass

    def full_screen(self):
        width = self.driver.execute_script(
            "return Math.max(document.body.scrollWidth, document.body.offsetWidth);"
        )
        height = self.driver.execute_script(
            "return Math.max(document.body.scrollHeight, document.body.offsetHeight);"
        )
        self.driver.set_window_size(width, height)

    def recover_screen(self, size):
        width = size.get('width')
        height = size.get('height')
        self.driver.set_window_size(width, height)

    def html_snapshot(self, name="", suffix=".html", encoding='utf-8'):
        """Write the current html to a file."""
        name = name or ""

        (fd, filename) = tempfile.mkstemp(prefix=name, suffix=suffix)
        # Don't hold the file
        os.close(fd)

        with io.open(filename, 'w', encoding=encoding) as f:
            f.write(self.html)

        return filename

    @property
    def cookies(self):
        return self._cookie_manager

    @property
    def windows(self):
        return Windows(self)