Source code for nerodia.window

import re

from selenium.common.exceptions import NoSuchWindowException, WebDriverException

from .exception import NoMatchingWindowFoundException
from .wait.wait import Waitable, TimeoutError


[docs]class Window(Waitable): def __init__(self, browser, selector): self.browser = browser self.driver = browser.driver self.selector = selector self.original = self._current_window self.window_handle = None if not selector: self.window_handle = self.original elif 'handle' in selector: self.window_handle = selector.pop('handle') else: if not all(key in ['title', 'url', 'index'] for key in selector.keys()): raise ValueError('invalid window selector: {}'.format(self.selector_string)) def __repr__(self): return '#<{}:0x{:x} located={}>'.format(self.__class__.__name__, hash(self) * 2, self.handle is not None) def __enter__(self): self.original = self._current_window return self.use() def __exit__(self, *args): self.unuse() @property def size(self): """ Returns window size :rtype: dict :Example: browser.window().size #=> {width: 1600, height: 1200} """ with self: size = self.driver.get_window_size() return Dimension(**size) @property def position(self): """ Returns window position :rtype: dict :Example: browser.window().position #=> {x: 92, y: 76} """ with self: pos = self.driver.get_window_position() return Point(**pos)
[docs] def resize_to(self, width, height): """ Resizes window to given width and height :param width: width to resize to :param height: height to resize to :Example: browser.window().resize_to(1600, 1200) """ size = {'width': width, 'height': height} with self: self.driver.set_window_size(**size) return size
[docs] def move_to(self, x, y): """ Moves window to given x and y coordinates :param x: horizontal position :param y: vertical position :Example: browser.window().move_to(300, 200) """ point = {'x': x, 'y': y} with self: self.driver.set_window_position(**point) return point
[docs] def maximize(self): """ Maximizes window :Example: browser.window().maximize() """ with self: self.driver.maximize_window()
@property def exists(self): """ Returns True if the window exists :rtype: bool """ try: self.assert_exists() return True except NoMatchingWindowFoundException: return False present = exists exist = exists def __eq__(self, other): """ Returns True if two windows are equal :param other: the other window :rtype: bool :Example: browser.window(index=0) == browser.window(index=1) #=> False """ if not isinstance(other, Window): return False return self.handle == other.handle eql = __eq__ def __hash__(self): return hash(self.handle) ^ hash(self.__class__) @property def is_current(self): """ Returns True if the window is current :Example: browse.window.is_current :rtype: bool """ return self._current_window == self.handle
[docs] def close(self): """ Closes the window """ if self == self.browser.original_window: self.browser._original_window = None if self._current_window == self.handle: self.driver.close() else: with self: self.driver.close()
@property def title(self): """ Returns the window title :rtype: str """ with self: title = self.driver.title return title @property def url(self): """ Returns the window URL :rtype: str """ with self: url = self.driver.current_url return url
[docs] def use(self): """ Switches to given window :Example: browser.window(title='closeable window').use() :rtype: Window """ if self.browser.original_window is None: self.browser._original_window = self self.wait_for_exists() self.driver.switch_to.window(self.handle) return self
[docs] def unuse(self): """ Returns to the original window :Example: window = browser.window(title='closeable window').use() window.unuse() :rtype: Window """ current = self.driver.window_handles orig = self.original if self.original in current else current[0] self.driver.switch_to.window(orig) return self
@property def handle(self): return self.window_handle or self.locate() @property def selector_string(self): return repr(self.selector)
[docs] def assert_exists(self): if self.handle not in self.driver.window_handles: raise NoMatchingWindowFoundException(self.selector_string)
[docs] def wait_for_exists(self): import nerodia if not nerodia.relaxed_locate: self.assert_exists() try: self.wait_until(lambda w: w.exists) except TimeoutError: raise NoMatchingWindowFoundException(self.selector_string)
[docs] def locate(self): if not self.selector: self.window_handle = None elif 'index' in self.selector: try: self.window_handle = self.driver.window_handles[int(self.selector.get('index'))] except IndexError: self.window_handle = None else: self.window_handle = next((x for x in self.driver.window_handles if self._matches(x) is True), False) return self.window_handle
# private @property def _current_window(self): try: return self.driver.current_window_handle except WebDriverException: return None def _matches(self, handle): try: orig = self.driver.current_window_handle except NoSuchWindowException: orig = None try: self.driver.switch_to.window(handle) if 'title' in self.selector: title_value = self.selector.get('title') driver_title = self.browser.title matches_title = re.search(title_value, driver_title) is not None else: matches_title = True if 'url' in self.selector: url_value = self.selector.get('url') driver_url = self.browser.url matches_url = re.search(url_value, driver_url) is not None else: matches_url = True return matches_title and matches_url except NoSuchWindowException: return False finally: current = self.driver.window_handles orig = orig if orig in current else current[0] self.driver.switch_to.window(orig)
[docs]class Dimension(object): __slots__ = ['width', 'height'] def __init__(self, width=None, height=None): self.width = width self.height = height def __eq__(self, other): return self.width == other.width and self.height == other.height
[docs]class Point(object): __slots__ = ['x', 'y'] def __init__(self, x=None, y=None): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y