1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import command_executor
6 from command_executor import Command
7 from webelement import WebElement
10 class ChromeDriverException(Exception):
12 class NoSuchElement(ChromeDriverException):
14 class NoSuchFrame(ChromeDriverException):
16 class UnknownCommand(ChromeDriverException):
18 class StaleElementReference(ChromeDriverException):
20 class UnknownError(ChromeDriverException):
22 class JavaScriptError(ChromeDriverException):
24 class XPathLookupError(ChromeDriverException):
26 class NoSuchWindow(ChromeDriverException):
28 class InvalidCookieDomain(ChromeDriverException):
30 class ScriptTimeout(ChromeDriverException):
32 class InvalidSelector(ChromeDriverException):
34 class SessionNotCreatedException(ChromeDriverException):
36 class NoSuchSession(ChromeDriverException):
39 def _ExceptionForResponse(response):
40 exception_class_map = {
45 10: StaleElementReference,
50 24: InvalidCookieDomain,
53 33: SessionNotCreatedException
55 status = response['status']
56 msg = response['value']['message']
57 return exception_class_map.get(status, ChromeDriverException)(msg)
60 class ChromeDriver(object):
61 """Starts and controls a single Chrome instance on this machine."""
63 def __init__(self, server_url, chrome_binary=None, android_package=None,
64 chrome_switches=None, chrome_extensions=None,
65 chrome_log_path=None, debugger_address=None,
66 browser_log_level=None):
67 self._executor = command_executor.CommandExecutor(server_url)
71 options['androidPackage'] = android_package
73 options['binary'] = chrome_binary
76 assert type(chrome_switches) is list
77 options['args'] = chrome_switches
80 assert type(chrome_extensions) is list
81 options['extensions'] = chrome_extensions
84 assert type(chrome_log_path) is str
85 options['logPath'] = chrome_log_path
88 assert type(debugger_address) is str
89 options['debuggerAddress'] = debugger_address
92 log_levels = ['ALL', 'DEBUG', 'INFO', 'WARNING', 'SEVERE', 'OFF']
94 assert browser_log_level in log_levels
95 logging_prefs['browser'] = browser_log_level
98 'desiredCapabilities': {
99 'chromeOptions': options,
100 'loggingPrefs': logging_prefs
104 self._session_id = self._ExecuteCommand(
105 Command.NEW_SESSION, params)['sessionId']
107 def _WrapValue(self, value):
108 """Wrap value from client side for chromedriver side."""
109 if isinstance(value, dict):
111 for key, val in value.items():
112 converted[key] = self._WrapValue(val)
114 elif isinstance(value, WebElement):
115 return {'ELEMENT': value._id}
116 elif isinstance(value, list):
117 return list(self._WrapValue(item) for item in value)
121 def _UnwrapValue(self, value):
122 """Unwrap value from chromedriver side for client side."""
123 if isinstance(value, dict):
124 if (len(value) == 1 and 'ELEMENT' in value
125 and isinstance(value['ELEMENT'], basestring)):
126 return WebElement(self, value['ELEMENT'])
129 for key, val in value.items():
130 unwraped[key] = self._UnwrapValue(val)
132 elif isinstance(value, list):
133 return list(self._UnwrapValue(item) for item in value)
137 def _ExecuteCommand(self, command, params={}):
138 params = self._WrapValue(params)
139 response = self._executor.Execute(command, params)
140 if response['status'] != 0:
141 raise _ExceptionForResponse(response)
144 def ExecuteCommand(self, command, params={}):
145 params['sessionId'] = self._session_id
146 response = self._ExecuteCommand(command, params)
147 return self._UnwrapValue(response['value'])
149 def GetWindowHandles(self):
150 return self.ExecuteCommand(Command.GET_WINDOW_HANDLES)
152 def SwitchToWindow(self, handle_or_name):
153 self.ExecuteCommand(Command.SWITCH_TO_WINDOW, {'name': handle_or_name})
155 def GetCurrentWindowHandle(self):
156 return self.ExecuteCommand(Command.GET_CURRENT_WINDOW_HANDLE)
158 def CloseWindow(self):
159 self.ExecuteCommand(Command.CLOSE)
162 self.ExecuteCommand(Command.GET, {'url': url})
164 def ExecuteScript(self, script, *args):
165 converted_args = list(args)
166 return self.ExecuteCommand(
167 Command.EXECUTE_SCRIPT, {'script': script, 'args': converted_args})
169 def ExecuteAsyncScript(self, script, *args):
170 converted_args = list(args)
171 return self.ExecuteCommand(
172 Command.EXECUTE_ASYNC_SCRIPT,
173 {'script': script, 'args': converted_args})
175 def SwitchToFrame(self, id_or_name):
176 self.ExecuteCommand(Command.SWITCH_TO_FRAME, {'id': id_or_name})
178 def SwitchToFrameByIndex(self, index):
179 self.SwitchToFrame(index)
181 def SwitchToMainFrame(self):
182 self.SwitchToFrame(None)
185 return self.ExecuteCommand(Command.GET_TITLE)
187 def GetPageSource(self):
188 return self.ExecuteCommand(Command.GET_PAGE_SOURCE)
190 def FindElement(self, strategy, target):
191 return self.ExecuteCommand(
192 Command.FIND_ELEMENT, {'using': strategy, 'value': target})
194 def FindElements(self, strategy, target):
195 return self.ExecuteCommand(
196 Command.FIND_ELEMENTS, {'using': strategy, 'value': target})
198 def SetTimeout(self, type, timeout):
199 return self.ExecuteCommand(
200 Command.SET_TIMEOUT, {'type' : type, 'ms': timeout})
202 def GetCurrentUrl(self):
203 return self.ExecuteCommand(Command.GET_CURRENT_URL)
206 return self.ExecuteCommand(Command.GO_BACK)
209 return self.ExecuteCommand(Command.GO_FORWARD)
212 return self.ExecuteCommand(Command.REFRESH)
214 def MouseMoveTo(self, element=None, x_offset=None, y_offset=None):
216 if element is not None:
217 params['element'] = element._id
218 if x_offset is not None:
219 params['xoffset'] = x_offset
220 if y_offset is not None:
221 params['yoffset'] = y_offset
222 self.ExecuteCommand(Command.MOUSE_MOVE_TO, params)
224 def MouseClick(self, button=0):
225 self.ExecuteCommand(Command.MOUSE_CLICK, {'button': button})
227 def MouseButtonDown(self, button=0):
228 self.ExecuteCommand(Command.MOUSE_BUTTON_DOWN, {'button': button})
230 def MouseButtonUp(self, button=0):
231 self.ExecuteCommand(Command.MOUSE_BUTTON_UP, {'button': button})
233 def MouseDoubleClick(self, button=0):
234 self.ExecuteCommand(Command.MOUSE_DOUBLE_CLICK, {'button': button})
236 def TouchDown(self, x, y):
237 self.ExecuteCommand(Command.TOUCH_DOWN, {'x': x, 'y': y})
239 def TouchUp(self, x, y):
240 self.ExecuteCommand(Command.TOUCH_UP, {'x': x, 'y': y})
242 def TouchMove(self, x, y):
243 self.ExecuteCommand(Command.TOUCH_MOVE, {'x': x, 'y': y})
245 def GetCookies(self):
246 return self.ExecuteCommand(Command.GET_COOKIES)
248 def AddCookie(self, cookie):
249 self.ExecuteCommand(Command.ADD_COOKIE, {'cookie': cookie})
251 def DeleteCookie(self, name):
252 self.ExecuteCommand(Command.DELETE_COOKIE, {'name': name})
254 def DeleteAllCookies(self):
255 self.ExecuteCommand(Command.DELETE_ALL_COOKIES)
257 def IsAlertOpen(self):
258 return self.ExecuteCommand(Command.GET_ALERT)
260 def GetAlertMessage(self):
261 return self.ExecuteCommand(Command.GET_ALERT_TEXT)
263 def HandleAlert(self, accept, prompt_text=''):
265 self.ExecuteCommand(Command.SET_ALERT_VALUE, {'text': prompt_text})
267 cmd = Command.ACCEPT_ALERT
269 cmd = Command.DISMISS_ALERT
270 self.ExecuteCommand(cmd)
273 return self.ExecuteCommand(Command.IS_LOADING)
275 def GetWindowPosition(self):
276 position = self.ExecuteCommand(Command.GET_WINDOW_POSITION,
277 {'windowHandle': 'current'})
278 return [position['x'], position['y']]
280 def SetWindowPosition(self, x, y):
281 self.ExecuteCommand(Command.SET_WINDOW_POSITION,
282 {'windowHandle': 'current', 'x': x, 'y': y})
284 def GetWindowSize(self):
285 size = self.ExecuteCommand(Command.GET_WINDOW_SIZE,
286 {'windowHandle': 'current'})
287 return [size['width'], size['height']]
289 def SetWindowSize(self, width, height):
291 Command.SET_WINDOW_SIZE,
292 {'windowHandle': 'current', 'width': width, 'height': height})
294 def MaximizeWindow(self):
295 self.ExecuteCommand(Command.MAXIMIZE_WINDOW, {'windowHandle': 'current'})
298 """Quits the browser and ends the session."""
299 self.ExecuteCommand(Command.QUIT)
301 def GetLog(self, type):
302 return self.ExecuteCommand(Command.GET_LOG, {'type': type})
304 def GetAvailableLogTypes(self):
305 return self.ExecuteCommand(Command.GET_AVAILABLE_LOG_TYPES)