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 android_activity=None, android_process=None,
65 android_use_running_app=None, chrome_switches=None,
66 chrome_extensions=None, chrome_log_path=None,
67 debugger_address=None, browser_log_level=None,
68 experimental_options=None):
69 self._executor = command_executor.CommandExecutor(server_url)
73 if experimental_options:
74 assert isinstance(experimental_options, dict)
75 options = experimental_options.copy()
78 options['androidPackage'] = android_package
80 options['androidActivity'] = android_activity
82 options['androidProcess'] = android_process
83 if android_use_running_app:
84 options['androidUseRunningApp'] = android_use_running_app
86 options['binary'] = chrome_binary
89 assert type(chrome_switches) is list
90 options['args'] = chrome_switches
93 assert type(chrome_extensions) is list
94 options['extensions'] = chrome_extensions
97 assert type(chrome_log_path) is str
98 options['logPath'] = chrome_log_path
101 assert type(debugger_address) is str
102 options['debuggerAddress'] = debugger_address
105 log_levels = ['ALL', 'DEBUG', 'INFO', 'WARNING', 'SEVERE', 'OFF']
106 if browser_log_level:
107 assert browser_log_level in log_levels
108 logging_prefs['browser'] = browser_log_level
111 'desiredCapabilities': {
112 'chromeOptions': options,
113 'loggingPrefs': logging_prefs
117 response = self._ExecuteCommand(Command.NEW_SESSION, params)
118 self._session_id = response['sessionId']
119 self.capabilities = self._UnwrapValue(response['value'])
121 def _WrapValue(self, value):
122 """Wrap value from client side for chromedriver side."""
123 if isinstance(value, dict):
125 for key, val in value.items():
126 converted[key] = self._WrapValue(val)
128 elif isinstance(value, WebElement):
129 return {'ELEMENT': value._id}
130 elif isinstance(value, list):
131 return list(self._WrapValue(item) for item in value)
135 def _UnwrapValue(self, value):
136 """Unwrap value from chromedriver side for client side."""
137 if isinstance(value, dict):
138 if (len(value) == 1 and 'ELEMENT' in value
139 and isinstance(value['ELEMENT'], basestring)):
140 return WebElement(self, value['ELEMENT'])
143 for key, val in value.items():
144 unwraped[key] = self._UnwrapValue(val)
146 elif isinstance(value, list):
147 return list(self._UnwrapValue(item) for item in value)
151 def _ExecuteCommand(self, command, params={}):
152 params = self._WrapValue(params)
153 response = self._executor.Execute(command, params)
154 if response['status'] != 0:
155 raise _ExceptionForResponse(response)
158 def ExecuteCommand(self, command, params={}):
159 params['sessionId'] = self._session_id
160 response = self._ExecuteCommand(command, params)
161 return self._UnwrapValue(response['value'])
163 def GetWindowHandles(self):
164 return self.ExecuteCommand(Command.GET_WINDOW_HANDLES)
166 def SwitchToWindow(self, handle_or_name):
167 self.ExecuteCommand(Command.SWITCH_TO_WINDOW, {'name': handle_or_name})
169 def GetCurrentWindowHandle(self):
170 return self.ExecuteCommand(Command.GET_CURRENT_WINDOW_HANDLE)
172 def CloseWindow(self):
173 self.ExecuteCommand(Command.CLOSE)
176 self.ExecuteCommand(Command.GET, {'url': url})
178 def ExecuteScript(self, script, *args):
179 converted_args = list(args)
180 return self.ExecuteCommand(
181 Command.EXECUTE_SCRIPT, {'script': script, 'args': converted_args})
183 def ExecuteAsyncScript(self, script, *args):
184 converted_args = list(args)
185 return self.ExecuteCommand(
186 Command.EXECUTE_ASYNC_SCRIPT,
187 {'script': script, 'args': converted_args})
189 def SwitchToFrame(self, id_or_name):
190 self.ExecuteCommand(Command.SWITCH_TO_FRAME, {'id': id_or_name})
192 def SwitchToFrameByIndex(self, index):
193 self.SwitchToFrame(index)
195 def SwitchToMainFrame(self):
196 self.SwitchToFrame(None)
199 return self.ExecuteCommand(Command.GET_TITLE)
201 def GetPageSource(self):
202 return self.ExecuteCommand(Command.GET_PAGE_SOURCE)
204 def FindElement(self, strategy, target):
205 return self.ExecuteCommand(
206 Command.FIND_ELEMENT, {'using': strategy, 'value': target})
208 def FindElements(self, strategy, target):
209 return self.ExecuteCommand(
210 Command.FIND_ELEMENTS, {'using': strategy, 'value': target})
212 def SetTimeout(self, type, timeout):
213 return self.ExecuteCommand(
214 Command.SET_TIMEOUT, {'type' : type, 'ms': timeout})
216 def GetCurrentUrl(self):
217 return self.ExecuteCommand(Command.GET_CURRENT_URL)
220 return self.ExecuteCommand(Command.GO_BACK)
223 return self.ExecuteCommand(Command.GO_FORWARD)
226 return self.ExecuteCommand(Command.REFRESH)
228 def MouseMoveTo(self, element=None, x_offset=None, y_offset=None):
230 if element is not None:
231 params['element'] = element._id
232 if x_offset is not None:
233 params['xoffset'] = x_offset
234 if y_offset is not None:
235 params['yoffset'] = y_offset
236 self.ExecuteCommand(Command.MOUSE_MOVE_TO, params)
238 def MouseClick(self, button=0):
239 self.ExecuteCommand(Command.MOUSE_CLICK, {'button': button})
241 def MouseButtonDown(self, button=0):
242 self.ExecuteCommand(Command.MOUSE_BUTTON_DOWN, {'button': button})
244 def MouseButtonUp(self, button=0):
245 self.ExecuteCommand(Command.MOUSE_BUTTON_UP, {'button': button})
247 def MouseDoubleClick(self, button=0):
248 self.ExecuteCommand(Command.MOUSE_DOUBLE_CLICK, {'button': button})
250 def TouchDown(self, x, y):
251 self.ExecuteCommand(Command.TOUCH_DOWN, {'x': x, 'y': y})
253 def TouchUp(self, x, y):
254 self.ExecuteCommand(Command.TOUCH_UP, {'x': x, 'y': y})
256 def TouchMove(self, x, y):
257 self.ExecuteCommand(Command.TOUCH_MOVE, {'x': x, 'y': y})
259 def TouchFlick(self, element, xoffset, yoffset, speed):
261 'element': element._id,
266 self.ExecuteCommand(Command.TOUCH_FLICK, params)
268 def GetCookies(self):
269 return self.ExecuteCommand(Command.GET_COOKIES)
271 def AddCookie(self, cookie):
272 self.ExecuteCommand(Command.ADD_COOKIE, {'cookie': cookie})
274 def DeleteCookie(self, name):
275 self.ExecuteCommand(Command.DELETE_COOKIE, {'name': name})
277 def DeleteAllCookies(self):
278 self.ExecuteCommand(Command.DELETE_ALL_COOKIES)
280 def IsAlertOpen(self):
281 return self.ExecuteCommand(Command.GET_ALERT)
283 def GetAlertMessage(self):
284 return self.ExecuteCommand(Command.GET_ALERT_TEXT)
286 def HandleAlert(self, accept, prompt_text=''):
288 self.ExecuteCommand(Command.SET_ALERT_VALUE, {'text': prompt_text})
290 cmd = Command.ACCEPT_ALERT
292 cmd = Command.DISMISS_ALERT
293 self.ExecuteCommand(cmd)
296 return self.ExecuteCommand(Command.IS_LOADING)
298 def GetWindowPosition(self):
299 position = self.ExecuteCommand(Command.GET_WINDOW_POSITION,
300 {'windowHandle': 'current'})
301 return [position['x'], position['y']]
303 def SetWindowPosition(self, x, y):
304 self.ExecuteCommand(Command.SET_WINDOW_POSITION,
305 {'windowHandle': 'current', 'x': x, 'y': y})
307 def GetWindowSize(self):
308 size = self.ExecuteCommand(Command.GET_WINDOW_SIZE,
309 {'windowHandle': 'current'})
310 return [size['width'], size['height']]
312 def SetWindowSize(self, width, height):
314 Command.SET_WINDOW_SIZE,
315 {'windowHandle': 'current', 'width': width, 'height': height})
317 def MaximizeWindow(self):
318 self.ExecuteCommand(Command.MAXIMIZE_WINDOW, {'windowHandle': 'current'})
321 """Quits the browser and ends the session."""
322 self.ExecuteCommand(Command.QUIT)
324 def GetLog(self, type):
325 return self.ExecuteCommand(Command.GET_LOG, {'type': type})
327 def GetAvailableLogTypes(self):
328 return self.ExecuteCommand(Command.GET_AVAILABLE_LOG_TYPES)
330 def IsAutoReporting(self):
331 return self.ExecuteCommand(Command.IS_AUTO_REPORTING)
333 def SetAutoReporting(self, enabled):
334 self.ExecuteCommand(Command.SET_AUTO_REPORTING, {'enabled': enabled})