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