blob: 27d543ed22b92b0cd28cf3429db6139ca08ff407 [file] [log] [blame]
"""Entry point for WebDriver."""
import alert
import command
import searchcontext
import webelement
import base64
class WebDriver(searchcontext.SearchContext):
"""Controls a web browser."""
def __init__(self, host, required, desired, mode='strict'):
args = { 'desiredCapabilities': desired }
if required:
args['requiredCapabilities'] = required
self._executor = command.CommandExecutor(host, mode)
resp = self._executor.execute(
'POST', '/session', None, 'newSession', args)
self.capabilities = resp['value']
self._session_id = resp['sessionId']
self.mode = mode
def execute(self, method, path, name, parameters= None):
"""Execute a command against the current WebDriver session."""
data = self._executor.execute(
method,
'/session/' + self._session_id + path,
self._session_id,
name,
parameters,
self._object_hook)
if data:
return data['value']
def get(self, url):
"""Navigate to url."""
self.execute('POST', '/url', 'get', { 'url': url })
def get_current_url(self):
"""Get the current value of the location bar."""
return self.execute('GET', '/url', 'getCurrentUrl')
def go_back(self):
"""Hit the browser back button."""
self.execute('POST', '/back', 'goBack')
def go_forward(self):
"""Hit the browser forward button."""
self.execute('POST', '/forward', 'goForward')
def refresh(self):
"""Refresh the current page in the browser."""
self.execute('POST', '/refresh', 'refresh')
def quit(self):
"""Shutdown the current WebDriver session."""
self.execute('DELETE', '', 'quit')
def get_window_handle(self):
"""Get the handle for the browser window/tab currently accepting
commands.
"""
return self.execute('GET', '/window_handle', 'getWindowHandle')
def get_window_handles(self):
"""Get handles for all open windows/tabs."""
return self.execute('GET', '/window_handles', 'getWindowHandles')
def close(self):
"""Close the current tab or window.
If this is the last tab or window, then this is the same as
calling quit.
"""
self.execute('DELETE', '/window', 'close')
def maximize_window(self):
"""Maximize the current window."""
return self._window_command('POST', '/maximize', 'maximize')
def get_window_size(self):
"""Get the dimensions of the current window."""
result = self._window_command('GET', '/size', 'getWindowSize')
return {'height': result['height'], 'width': result['width']}
def set_window_size(self, height, width):
"""Set the size of the current window."""
self._window_command(
'POST',
'/size',
'setWindowSize',
{ 'height': height, 'width': width})
def fullscreen_window(self):
"""Make the current window fullscreen."""
pass # implement when end point is defined
def switch_to_window(self, name):
"""Switch to the window with the given handle or name."""
self.execute('POST', '/window', 'switchToWindow', { 'name': name })
def switch_to_frame(self, id):
"""Switch to a frame.
id can be either a WebElement or an integer.
"""
self.execute('POST', '/frame', 'switchToFrame', { 'id': id})
def switch_to_parent_frame(self):
"""Move to the browsing context containing the currently selected frame.
If in the top-level browsing context, this is a no-op.
"""
self.execute('POST', '/frame/parent', 'switchToParentFrame')
def switch_to_alert(self):
"""Return an Alert object to interact with a modal dialog."""
alert_ = alert.Alert(self)
alert_.get_text()
return alert_
def execute_script(self, script, args=[]):
"""Execute a Javascript script in the current browsing context."""
return self.execute(
'POST',
'/execute',
'executeScript',
{ 'script': script, 'args': args })
def execute_script_async(self, script, args=[]):
"""Execute a Javascript script in the current browsing context."""
return self.execute(
'POST',
'/execute_async',
'executeScriptAsync',
{ 'script': script, 'args': args })
def take_screenshot(self, element=None):
"""Take a screenshot.
If element is not provided, the screenshot should be of the
current page, otherwise the screenshot should be of the given element.
"""
if self.mode == 'strict':
pass # implement when endpoint is defined
elif self.mode == 'compatibility':
if element:
pass # element screenshots are unsupported in compatibility
else:
return base64.standard_b64decode(
self.execute('GET', '/screenshot', 'takeScreenshot'))
def add_cookie(self, cookie):
"""Add a cookie to the browser."""
self.execute('POST', '/cookie', 'addCookie', { 'cookie': cookie })
def get_cookie(self, name = None):
"""Get the cookies accessible from the current page."""
if self.mode == 'compatibility':
cookies = self.execute('GET', '/cookie', 'getCookie')
if name:
cookies_ = []
for cookie in cookies:
if cookie['name'] == name:
cookies_.append(cookie)
return cookies_
return cookies
elif self.mode == 'strict':
pass # implement when wire protocol for this has been defined
def set_implicit_timeout(self, ms):
self._set_timeout('implicit', ms)
def set_page_load_timeout(self, ms):
self._set_timeout('page load', ms)
def set_script_timeout(self, ms):
self._set_timeout('script', ms)
def _set_timeout(self, type, ms):
params = { 'type': type, 'ms': ms }
self.execute('POST', '/timeouts', 'timeouts', params)
def _window_command(self, method, path, name, parameters = None):
if self.mode == 'compatibility':
return self.execute(
method, '/window/current' + path, name, parameters)
elif self.mode == 'strict':
pass # implement this when end-points are defined in doc
def _object_hook(self, obj):
if 'ELEMENT' in obj:
return webelement.WebElement(self, obj['ELEMENT'])
return obj