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. 4 5 import httplib 6 import json 7 8 9 class _Method(object): 10 GET = 'GET' 11 POST = 'POST' 12 DELETE = 'DELETE' 13 14 15 class Command(object): 16 NEW_SESSION = (_Method.POST, '/session') 17 GET_SESSION_CAPABILITIES = (_Method.GET, '/session/:sessionId') 18 QUIT = (_Method.DELETE, '/session/:sessionId') 19 GET_CURRENT_WINDOW_HANDLE = (_Method.GET, '/session/:sessionId/window_handle') 20 GET_WINDOW_HANDLES = (_Method.GET, '/session/:sessionId/window_handles') 21 GET = (_Method.POST, '/session/:sessionId/url') 22 GET_ALERT = (_Method.GET, '/session/:sessionId/alert') 23 DISMISS_ALERT = (_Method.POST, '/session/:sessionId/dismiss_alert') 24 ACCEPT_ALERT = (_Method.POST, '/session/:sessionId/accept_alert') 25 GET_ALERT_TEXT = (_Method.GET, '/session/:sessionId/alert_text') 26 SET_ALERT_VALUE = (_Method.POST, '/session/:sessionId/alert_text') 27 GO_FORWARD = (_Method.POST, '/session/:sessionId/forward') 28 GO_BACK = (_Method.POST, '/session/:sessionId/back') 29 REFRESH = (_Method.POST, '/session/:sessionId/refresh') 30 EXECUTE_SCRIPT = (_Method.POST, '/session/:sessionId/execute') 31 EXECUTE_ASYNC_SCRIPT = (_Method.POST, '/session/:sessionId/execute_async') 32 GET_CURRENT_URL = (_Method.GET, '/session/:sessionId/url') 33 GET_TITLE = (_Method.GET, '/session/:sessionId/title') 34 GET_PAGE_SOURCE = (_Method.GET, '/session/:sessionId/source') 35 SCREENSHOT = (_Method.GET, '/session/:sessionId/screenshot') 36 SET_BROWSER_VISIBLE = (_Method.POST, '/session/:sessionId/visible') 37 IS_BROWSER_VISIBLE = (_Method.GET, '/session/:sessionId/visible') 38 FIND_ELEMENT = (_Method.POST, '/session/:sessionId/element') 39 FIND_ELEMENTS = (_Method.POST, '/session/:sessionId/elements') 40 GET_ACTIVE_ELEMENT = (_Method.POST, '/session/:sessionId/element/active') 41 FIND_CHILD_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/element') 42 FIND_CHILD_ELEMENTS = ( 43 _Method.POST, '/session/:sessionId/element/:id/elements') 44 CLICK_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/click') 45 CLEAR_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/clear') 46 SUBMIT_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/submit') 47 GET_ELEMENT_TEXT = (_Method.GET, '/session/:sessionId/element/:id/text') 48 SEND_KEYS_TO_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/value') 49 UPLOAD_FILE = (_Method.POST, '/session/:sessionId/file') 50 GET_ELEMENT_VALUE = (_Method.GET, '/session/:sessionId/element/:id/value') 51 GET_ELEMENT_TAG_NAME = (_Method.GET, '/session/:sessionId/element/:id/name') 52 IS_ELEMENT_SELECTED = ( 53 _Method.GET, '/session/:sessionId/element/:id/selected') 54 IS_ELEMENT_ENABLED = (_Method.GET, '/session/:sessionId/element/:id/enabled') 55 IS_ELEMENT_DISPLAYED = ( 56 _Method.GET, '/session/:sessionId/element/:id/displayed') 57 HOVER_OVER_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/hover') 58 GET_ELEMENT_LOCATION = ( 59 _Method.GET, '/session/:sessionId/element/:id/location') 60 GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW = ( 61 _Method.GET, '/session/:sessionId/element/:id/location_in_view') 62 GET_ELEMENT_SIZE = (_Method.GET, '/session/:sessionId/element/:id/size') 63 GET_ELEMENT_ATTRIBUTE = ( 64 _Method.GET, '/session/:sessionId/element/:id/attribute/:name') 65 ELEMENT_EQUALS = ( 66 _Method.GET, '/session/:sessionId/element/:id/equals/:other') 67 GET_COOKIES = (_Method.GET, '/session/:sessionId/cookie') 68 ADD_COOKIE = (_Method.POST, '/session/:sessionId/cookie') 69 DELETE_ALL_COOKIES = (_Method.DELETE, '/session/:sessionId/cookie') 70 DELETE_COOKIE = (_Method.DELETE, '/session/:sessionId/cookie/:name') 71 SWITCH_TO_FRAME = (_Method.POST, '/session/:sessionId/frame') 72 SWITCH_TO_WINDOW = (_Method.POST, '/session/:sessionId/window') 73 GET_WINDOW_SIZE = ( 74 _Method.GET, '/session/:sessionId/window/:windowHandle/size') 75 GET_WINDOW_POSITION = ( 76 _Method.GET, '/session/:sessionId/window/:windowHandle/position') 77 SET_WINDOW_SIZE = ( 78 _Method.POST, '/session/:sessionId/window/:windowHandle/size') 79 SET_WINDOW_POSITION = ( 80 _Method.POST, '/session/:sessionId/window/:windowHandle/position') 81 MAXIMIZE_WINDOW = ( 82 _Method.POST, '/session/:sessionId/window/:windowHandle/maximize') 83 CLOSE = (_Method.DELETE, '/session/:sessionId/window') 84 DRAG_ELEMENT = (_Method.POST, '/session/:sessionId/element/:id/drag') 85 GET_ELEMENT_VALUE_OF_CSS_PROPERTY = ( 86 _Method.GET, '/session/:sessionId/element/:id/css/:propertyName') 87 IMPLICITLY_WAIT = ( 88 _Method.POST, '/session/:sessionId/timeouts/implicit_wait') 89 SET_SCRIPT_TIMEOUT = ( 90 _Method.POST, '/session/:sessionId/timeouts/async_script') 91 SET_TIMEOUT = (_Method.POST, '/session/:sessionId/timeouts') 92 EXECUTE_SQL = (_Method.POST, '/session/:sessionId/execute_sql') 93 GET_LOCATION = (_Method.GET, '/session/:sessionId/location') 94 SET_LOCATION = (_Method.POST, '/session/:sessionId/location') 95 GET_STATUS = (_Method.GET, '/session/:sessionId/application_cache/status') 96 IS_BROWSER_ONLINE = (_Method.GET, '/session/:sessionId/browser_connection') 97 SET_BROWSER_ONLINE = (_Method.POST, '/session/:sessionId/browser_connection') 98 GET_LOCAL_STORAGE_ITEM = ( 99 _Method.GET, '/session/:sessionId/local_storage/key/:key') 100 REMOVE_LOCAL_STORAGE_ITEM = ( 101 _Method.DELETE, '/session/:sessionId/local_storage/key/:key') 102 GET_LOCAL_STORAGE_KEYS = (_Method.GET, '/session/:sessionId/local_storage') 103 SET_LOCAL_STORAGE_ITEM = (_Method.POST, '/session/:sessionId/local_storage') 104 CLEAR_LOCAL_STORAGE = (_Method.DELETE, '/session/:sessionId/local_storage') 105 GET_LOCAL_STORAGE_SIZE = ( 106 _Method.GET, '/session/:sessionId/local_storage/size') 107 GET_SESSION_STORAGE_ITEM = ( 108 _Method.GET, '/session/:sessionId/session_storage/key/:key') 109 REMOVE_SESSION_STORAGE_ITEM = ( 110 _Method.DELETE, '/session/:sessionId/session_storage/key/:key') 111 GET_SESSION_STORAGE_KEY = (_Method.GET, '/session/:sessionId/session_storage') 112 SET_SESSION_STORAGE_ITEM = ( 113 _Method.POST, '/session/:sessionId/session_storage') 114 CLEAR_SESSION_STORAGE = ( 115 _Method.DELETE, '/session/:sessionId/session_storage') 116 GET_SESSION_STORAGE_SIZE = ( 117 _Method.GET, '/session/:sessionId/session_storage/size') 118 GET_SCREEN_ORIENTATION = (_Method.GET, '/session/:sessionId/orientation') 119 SET_SCREEN_ORIENTATION = (_Method.POST, '/session/:sessionId/orientation') 120 MOUSE_CLICK = (_Method.POST, '/session/:sessionId/click') 121 MOUSE_DOUBLE_CLICK = (_Method.POST, '/session/:sessionId/doubleclick') 122 MOUSE_BUTTON_DOWN = (_Method.POST, '/session/:sessionId/buttondown') 123 MOUSE_BUTTON_UP = (_Method.POST, '/session/:sessionId/buttonup') 124 MOUSE_MOVE_TO = (_Method.POST, '/session/:sessionId/moveto') 125 SEND_KEYS_TO_ACTIVE_ELEMENT = (_Method.POST, '/session/:sessionId/keys') 126 TOUCH_SINGLE_TAP = (_Method.POST, '/session/:sessionId/touch/click') 127 TOUCH_DOWN = (_Method.POST, '/session/:sessionId/touch/down') 128 TOUCH_UP = (_Method.POST, '/session/:sessionId/touch/up') 129 TOUCH_MOVE = (_Method.POST, '/session/:sessionId/touch/move') 130 TOUCH_SCROLL = (_Method.POST, '/session/:sessionId/touch/scroll') 131 TOUCH_DOUBLE_TAP = (_Method.POST, '/session/:sessionId/touch/doubleclick') 132 TOUCH_LONG_PRESS = (_Method.POST, '/session/:sessionId/touch/longclick') 133 TOUCH_FLICK = (_Method.POST, '/session/:sessionId/touch/flick') 134 GET_LOG = (_Method.POST, '/session/:sessionId/log') 135 GET_AVAILABLE_LOG_TYPES = (_Method.GET, '/session/:sessionId/log/types') 136 GET_SESSION_LOGS = (_Method.POST, '/logs') 137 STATUS = (_Method.GET, '/status') 138 139 # Custom Chrome commands. 140 IS_LOADING = (_Method.GET, '/session/:sessionId/is_loading') 141 142 143 class CommandExecutor(object): 144 def __init__(self, server_url): 145 self._server_url = server_url 146 port = int(server_url.split(':')[2].split('/')[0]) 147 self._http_client = httplib.HTTPConnection('127.0.0.1', port, timeout=30) 148 149 def Execute(self, command, params): 150 url_parts = command[1].split('/') 151 substituted_parts = [] 152 for part in url_parts: 153 if part.startswith(':'): 154 key = part[1:] 155 substituted_parts += [params[key]] 156 del params[key] 157 else: 158 substituted_parts += [part] 159 160 body = None 161 if command[0] == _Method.POST: 162 body = json.dumps(params) 163 self._http_client.request(command[0], '/'.join(substituted_parts), body) 164 response = self._http_client.getresponse() 165 166 if response.status == 303: 167 self._http_client.request(_Method.GET, response.getheader('location')) 168 response = self._http_client.getresponse() 169 if response.status != 200: 170 raise RuntimeError('Server returned error: ' + response.reason) 171 172 return json.loads(response.read()) 173