OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/automation/automation_json_requests.h" | 5 #include "chrome/test/automation/automation_json_requests.h" |
6 | 6 |
7 #include "base/scoped_ptr.h" | 7 #include "base/scoped_ptr.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
11 #include "chrome/common/automation_messages.h" | 11 #include "chrome/common/automation_messages.h" |
| 12 #include "chrome/common/json_value_serializer.h" |
12 #include "chrome/test/automation/automation_proxy.h" | 13 #include "chrome/test/automation/automation_proxy.h" |
13 | 14 |
14 namespace { | 15 namespace { |
15 | 16 |
16 bool SendAutomationJSONRequest(AutomationMessageSender* sender, | 17 bool SendAutomationJSONRequest(AutomationMessageSender* sender, |
17 const DictionaryValue& request_dict, | 18 const DictionaryValue& request_dict, |
18 DictionaryValue* reply_dict) { | 19 DictionaryValue* reply_dict) { |
19 std::string request, reply; | 20 std::string request, reply; |
20 base::JSONWriter::Write(&request_dict, false, &request); | 21 base::JSONWriter::Write(&request_dict, false, &request); |
21 bool success = false; | 22 bool success = false; |
22 if (!SendAutomationJSONRequest(sender, request, &reply, &success)) | 23 if (!SendAutomationJSONRequest(sender, request, &reply, &success)) |
23 return false; | 24 return false; |
24 if (!success) { | 25 scoped_ptr<Value> value(base::JSONReader::Read(reply, true)); |
| 26 if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) { |
25 std::string command; | 27 std::string command; |
26 request_dict.GetString("command", &command); | 28 request_dict.GetString("command", &command); |
27 LOG(ERROR) << "JSON request failed: " << command; | 29 LOG(ERROR) << "JSON request did not return dict: " << command << "\n"; |
28 return false; | 30 return false; |
29 } | 31 } |
30 scoped_ptr<Value> value(base::JSONReader::Read(reply, true)); | 32 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
31 if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) | 33 if (!success) { |
| 34 std::string command, error; |
| 35 request_dict.GetString("command", &command); |
| 36 dict->GetString("error", &error); |
| 37 LOG(ERROR) << "JSON request failed: " << command << "\n" |
| 38 << " with error: " << error; |
32 return false; | 39 return false; |
33 reply_dict->MergeDictionary(static_cast<DictionaryValue*>(value.get())); | 40 } |
| 41 reply_dict->MergeDictionary(dict); |
34 return true; | 42 return true; |
35 } | 43 } |
36 | 44 |
37 } // namespace | 45 } // namespace |
38 | 46 |
| 47 WebKeyEvent::WebKeyEvent(automation::KeyEventTypes type, |
| 48 ui::KeyboardCode key_code, |
| 49 const std::string& unmodified_text, |
| 50 const std::string& modified_text, |
| 51 int modifiers) |
| 52 : type(type), |
| 53 key_code(key_code), |
| 54 unmodified_text(unmodified_text), |
| 55 modified_text(modified_text), |
| 56 modifiers(modifiers) {} |
| 57 |
39 bool SendAutomationJSONRequest(AutomationMessageSender* sender, | 58 bool SendAutomationJSONRequest(AutomationMessageSender* sender, |
40 const std::string& request, | 59 const std::string& request, |
41 std::string* reply, | 60 std::string* reply, |
42 bool* success) { | 61 bool* success) { |
43 return sender->Send(new AutomationMsg_SendJSONRequest( | 62 return sender->Send(new AutomationMsg_SendJSONRequest( |
44 -1, request, reply, success)); | 63 -1, request, reply, success)); |
45 } | 64 } |
46 | 65 |
47 bool SendGetIndicesFromTabJSONRequest( | 66 bool SendGetIndicesFromTabIdJSONRequest( |
48 AutomationMessageSender* sender, | 67 AutomationMessageSender* sender, |
49 int handle, | 68 int tab_id, |
50 int* browser_index, | 69 int* browser_index, |
51 int* tab_index) { | 70 int* tab_index) { |
52 DictionaryValue request_dict; | 71 DictionaryValue request_dict; |
53 request_dict.SetString("command", "GetIndicesFromTab"); | 72 request_dict.SetString("command", "GetIndicesFromTab"); |
54 request_dict.SetInteger("tab_handle", handle); | 73 request_dict.SetInteger("tab_id", tab_id); |
55 DictionaryValue reply_dict; | 74 DictionaryValue reply_dict; |
56 if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict)) | 75 if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict)) |
57 return false; | 76 return false; |
| 77 if (!reply_dict.GetInteger("windex", browser_index)) |
| 78 return false; |
| 79 if (!reply_dict.GetInteger("tab_index", tab_index)) |
| 80 return false; |
| 81 return true; |
| 82 } |
| 83 |
| 84 bool SendGetIndicesFromTabHandleJSONRequest( |
| 85 AutomationMessageSender* sender, |
| 86 int tab_handle, |
| 87 int* browser_index, |
| 88 int* tab_index) { |
| 89 DictionaryValue request_dict; |
| 90 request_dict.SetString("command", "GetIndicesFromTab"); |
| 91 request_dict.SetInteger("tab_handle", tab_handle); |
| 92 DictionaryValue reply_dict; |
| 93 if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict)) |
| 94 return false; |
58 if (!reply_dict.GetInteger("windex", browser_index)) | 95 if (!reply_dict.GetInteger("windex", browser_index)) |
59 return false; | 96 return false; |
60 if (!reply_dict.GetInteger("tab_index", tab_index)) | 97 if (!reply_dict.GetInteger("tab_index", tab_index)) |
61 return false; | 98 return false; |
62 return true; | 99 return true; |
63 } | 100 } |
64 | 101 |
65 bool SendNavigateToURLJSONRequest( | 102 bool SendNavigateToURLJSONRequest( |
66 AutomationMessageSender* sender, | 103 AutomationMessageSender* sender, |
67 int browser_index, | 104 int browser_index, |
68 int tab_index, | 105 int tab_index, |
69 const GURL& url, | 106 const GURL& url, |
70 int navigation_count, | 107 int navigation_count, |
71 AutomationMsg_NavigationResponseValues* nav_response) { | 108 AutomationMsg_NavigationResponseValues* nav_response) { |
72 DictionaryValue dict; | 109 DictionaryValue dict; |
73 dict.SetString("command", "NavigateToURL"); | 110 dict.SetString("command", "NavigateToURL"); |
74 dict.SetInteger("windex", browser_index); | 111 dict.SetInteger("windex", browser_index); |
75 dict.SetInteger("tab_index", tab_index); | 112 dict.SetInteger("tab_index", tab_index); |
76 dict.SetString("url", url.possibly_invalid_spec()); | 113 dict.SetString("url", url.possibly_invalid_spec()); |
77 dict.SetInteger("navigation_count", navigation_count); | 114 dict.SetInteger("navigation_count", navigation_count); |
78 DictionaryValue reply_dict; | 115 DictionaryValue reply_dict; |
79 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) | 116 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
80 return false; | 117 return false; |
81 int response = 0; | 118 int response = 0; |
82 if (!reply_dict.GetInteger("result", &response)) | 119 if (!reply_dict.GetInteger("result", &response)) |
83 return false; | 120 return false; |
84 *nav_response = static_cast<AutomationMsg_NavigationResponseValues>(response); | 121 *nav_response = static_cast<AutomationMsg_NavigationResponseValues>(response); |
85 return true; | 122 return true; |
86 } | 123 } |
| 124 |
| 125 bool SendExecuteJavascriptJSONRequest( |
| 126 AutomationMessageSender* sender, |
| 127 int browser_index, |
| 128 int tab_index, |
| 129 const std::string& frame_xpath, |
| 130 const std::string& javascript, |
| 131 Value** result) { |
| 132 DictionaryValue dict; |
| 133 dict.SetString("command", "ExecuteJavascript"); |
| 134 dict.SetInteger("windex", browser_index); |
| 135 dict.SetInteger("tab_index", tab_index); |
| 136 dict.SetString("frame_xpath", frame_xpath); |
| 137 dict.SetString("javascript", javascript); |
| 138 DictionaryValue reply_dict; |
| 139 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
| 140 return false; |
| 141 |
| 142 std::string json; |
| 143 if (!reply_dict.GetString("result", &json)) { |
| 144 LOG(ERROR) << "Executed javascript but received no 'result'"; |
| 145 return false; |
| 146 } |
| 147 // Wrap |json| in an array before deserializing because valid JSON has an |
| 148 // array or an object as the root. |
| 149 json.insert(0, "["); |
| 150 json.append("]"); |
| 151 |
| 152 JSONStringValueSerializer deserializer(json); |
| 153 Value* value = deserializer.Deserialize(NULL, NULL); |
| 154 if (!value || !value->IsType(Value::TYPE_LIST)) { |
| 155 LOG(ERROR) << "Unable to deserialize returned JSON"; |
| 156 return false; |
| 157 } |
| 158 scoped_ptr<ListValue> list(static_cast<ListValue*>(value)); |
| 159 return list->Remove(0, result); |
| 160 } |
| 161 |
| 162 bool SendGoForwardJSONRequest( |
| 163 AutomationMessageSender* sender, |
| 164 int browser_index, |
| 165 int tab_index) { |
| 166 DictionaryValue dict; |
| 167 dict.SetString("command", "GoForward"); |
| 168 dict.SetInteger("windex", browser_index); |
| 169 dict.SetInteger("tab_index", tab_index); |
| 170 DictionaryValue reply_dict; |
| 171 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 172 } |
| 173 |
| 174 bool SendGoBackJSONRequest( |
| 175 AutomationMessageSender* sender, |
| 176 int browser_index, |
| 177 int tab_index) { |
| 178 DictionaryValue dict; |
| 179 dict.SetString("command", "GoBack"); |
| 180 dict.SetInteger("windex", browser_index); |
| 181 dict.SetInteger("tab_index", tab_index); |
| 182 DictionaryValue reply_dict; |
| 183 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 184 } |
| 185 |
| 186 bool SendReloadJSONRequest( |
| 187 AutomationMessageSender* sender, |
| 188 int browser_index, |
| 189 int tab_index) { |
| 190 DictionaryValue dict; |
| 191 dict.SetString("command", "Reload"); |
| 192 dict.SetInteger("windex", browser_index); |
| 193 dict.SetInteger("tab_index", tab_index); |
| 194 DictionaryValue reply_dict; |
| 195 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 196 } |
| 197 |
| 198 bool SendGetTabURLJSONRequest( |
| 199 AutomationMessageSender* sender, |
| 200 int browser_index, |
| 201 int tab_index, |
| 202 std::string* url) { |
| 203 DictionaryValue dict; |
| 204 dict.SetString("command", "GetTabURL"); |
| 205 dict.SetInteger("windex", browser_index); |
| 206 dict.SetInteger("tab_index", tab_index); |
| 207 DictionaryValue reply_dict; |
| 208 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
| 209 return false; |
| 210 return reply_dict.GetString("url", url); |
| 211 } |
| 212 |
| 213 bool SendGetTabTitleJSONRequest( |
| 214 AutomationMessageSender* sender, |
| 215 int browser_index, |
| 216 int tab_index, |
| 217 std::string* tab_title) { |
| 218 DictionaryValue dict; |
| 219 dict.SetString("command", "GetTabTitle"); |
| 220 dict.SetInteger("windex", browser_index); |
| 221 dict.SetInteger("tab_index", tab_index); |
| 222 DictionaryValue reply_dict; |
| 223 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
| 224 return false; |
| 225 return reply_dict.GetString("title", tab_title); |
| 226 } |
| 227 |
| 228 bool SendGetCookiesJSONRequest( |
| 229 AutomationMessageSender* sender, |
| 230 int browser_index, |
| 231 const std::string& url, |
| 232 std::string* cookies) { |
| 233 DictionaryValue dict; |
| 234 dict.SetString("command", "GetCookies"); |
| 235 dict.SetInteger("windex", browser_index); |
| 236 dict.SetString("url", url); |
| 237 DictionaryValue reply_dict; |
| 238 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
| 239 return false; |
| 240 return reply_dict.GetString("cookies", cookies); |
| 241 } |
| 242 |
| 243 bool SendDeleteCookieJSONRequest( |
| 244 AutomationMessageSender* sender, |
| 245 int browser_index, |
| 246 const std::string& url, |
| 247 const std::string& cookie_name) { |
| 248 DictionaryValue dict; |
| 249 dict.SetString("command", "DeleteCookie"); |
| 250 dict.SetInteger("windex", browser_index); |
| 251 dict.SetString("url", url); |
| 252 dict.SetString("name", cookie_name); |
| 253 DictionaryValue reply_dict; |
| 254 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 255 } |
| 256 |
| 257 bool SendSetCookieJSONRequest( |
| 258 AutomationMessageSender* sender, |
| 259 int browser_index, |
| 260 const std::string& url, |
| 261 const std::string& cookie) { |
| 262 DictionaryValue dict; |
| 263 dict.SetString("command", "SetCookie"); |
| 264 dict.SetInteger("windex", browser_index); |
| 265 dict.SetString("url", url); |
| 266 dict.SetString("cookie", cookie); |
| 267 DictionaryValue reply_dict; |
| 268 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 269 } |
| 270 |
| 271 bool SendGetTabIdsJSONRequest( |
| 272 AutomationMessageSender* sender, std::vector<int>* tab_ids) { |
| 273 DictionaryValue dict; |
| 274 dict.SetString("command", "GetTabIds"); |
| 275 DictionaryValue reply_dict; |
| 276 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
| 277 return false; |
| 278 ListValue* id_list; |
| 279 if (!reply_dict.GetList("ids", &id_list)) { |
| 280 LOG(ERROR) << "Returned 'ids' key is missing or invalid"; |
| 281 return false; |
| 282 } |
| 283 std::vector<int> temp_ids; |
| 284 for (size_t i = 0; i < id_list->GetSize(); ++i) { |
| 285 int id; |
| 286 if (!id_list->GetInteger(i, &id)) { |
| 287 LOG(ERROR) << "Returned 'ids' key contains non-integer values"; |
| 288 return false; |
| 289 } |
| 290 temp_ids.push_back(id); |
| 291 } |
| 292 *tab_ids = temp_ids; |
| 293 return true; |
| 294 } |
| 295 |
| 296 bool SendIsTabIdValidJSONRequest( |
| 297 AutomationMessageSender* sender, int tab_id, bool* is_valid) { |
| 298 DictionaryValue dict; |
| 299 dict.SetString("command", "IsTabIdValid"); |
| 300 dict.SetInteger("id", tab_id); |
| 301 DictionaryValue reply_dict; |
| 302 if (!SendAutomationJSONRequest(sender, dict, &reply_dict)) |
| 303 return false; |
| 304 return reply_dict.GetBoolean("is_valid", is_valid); |
| 305 } |
| 306 |
| 307 bool SendCloseTabJSONRequest( |
| 308 AutomationMessageSender* sender, int browser_index, int tab_index) { |
| 309 DictionaryValue dict; |
| 310 dict.SetString("command", "CloseTab"); |
| 311 dict.SetInteger("windex", browser_index); |
| 312 dict.SetInteger("tab_index", tab_index); |
| 313 DictionaryValue reply_dict; |
| 314 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 315 } |
| 316 |
| 317 bool SendMouseMoveJSONRequest( |
| 318 AutomationMessageSender* sender, |
| 319 int browser_index, |
| 320 int tab_index, |
| 321 int x, |
| 322 int y) { |
| 323 DictionaryValue dict; |
| 324 dict.SetString("command", "WebkitMouseMove"); |
| 325 dict.SetInteger("windex", browser_index); |
| 326 dict.SetInteger("tab_index", tab_index); |
| 327 dict.SetInteger("x", x); |
| 328 dict.SetInteger("y", y); |
| 329 DictionaryValue reply_dict; |
| 330 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 331 } |
| 332 |
| 333 bool SendMouseClickJSONRequest( |
| 334 AutomationMessageSender* sender, |
| 335 int browser_index, |
| 336 int tab_index, |
| 337 automation::MouseButton button, |
| 338 int x, |
| 339 int y) { |
| 340 // TODO get rid of the evil flags. |
| 341 DictionaryValue dict; |
| 342 dict.SetString("command", "WebkitMouseClick"); |
| 343 dict.SetInteger("windex", browser_index); |
| 344 dict.SetInteger("tab_index", tab_index); |
| 345 dict.SetInteger("button", button); |
| 346 dict.SetInteger("x", x); |
| 347 dict.SetInteger("y", y); |
| 348 DictionaryValue reply_dict; |
| 349 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 350 } |
| 351 |
| 352 bool SendMouseDragJSONRequest( |
| 353 AutomationMessageSender* sender, |
| 354 int browser_index, |
| 355 int tab_index, |
| 356 int start_x, |
| 357 int start_y, |
| 358 int end_x, |
| 359 int end_y) { |
| 360 DictionaryValue dict; |
| 361 dict.SetString("command", "WebkitMouseDrag"); |
| 362 dict.SetInteger("windex", browser_index); |
| 363 dict.SetInteger("tab_index", tab_index); |
| 364 dict.SetInteger("start_x", start_x); |
| 365 dict.SetInteger("start_y", start_y); |
| 366 dict.SetInteger("end_x", end_x); |
| 367 dict.SetInteger("end_y", end_y); |
| 368 DictionaryValue reply_dict; |
| 369 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 370 } |
| 371 |
| 372 bool SendWebKeyEventJSONRequest( |
| 373 AutomationMessageSender* sender, |
| 374 int browser_index, |
| 375 int tab_index, |
| 376 const WebKeyEvent& key_event) { |
| 377 DictionaryValue dict; |
| 378 dict.SetString("command", "SendWebkitKeyEvent"); |
| 379 dict.SetInteger("windex", browser_index); |
| 380 dict.SetInteger("tab_index", tab_index); |
| 381 dict.SetInteger("type", key_event.type); |
| 382 dict.SetInteger("nativeKeyCode", key_event.key_code); |
| 383 dict.SetInteger("windowsKeyCode", key_event.key_code); |
| 384 dict.SetString("unmodifiedText", key_event.unmodified_text); |
| 385 dict.SetString("text", key_event.modified_text); |
| 386 dict.SetInteger("modifiers", key_event.modifiers); |
| 387 dict.SetBoolean("isSystemKey", false); |
| 388 DictionaryValue reply_dict; |
| 389 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 390 } |
| 391 |
| 392 bool SendWaitForAllTabsToStopLoadingJSONRequest( |
| 393 AutomationMessageSender* sender) { |
| 394 DictionaryValue dict; |
| 395 dict.SetString("command", "WaitForAllTabsToStopLoading"); |
| 396 DictionaryValue reply_dict; |
| 397 return SendAutomationJSONRequest(sender, dict, &reply_dict); |
| 398 } |
OLD | NEW |