| """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 |
| |