1 // Copyright (c) 2012 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 #include "chrome/test/automation/automation_json_requests.h" 6 7 #include "base/basictypes.h" 8 #include "base/files/file_path.h" 9 #include "base/format_macros.h" 10 #include "base/json/json_reader.h" 11 #include "base/json/json_string_value_serializer.h" 12 #include "base/json/json_writer.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/strings/stringprintf.h" 15 #include "base/test/test_timeouts.h" 16 #include "base/time/time.h" 17 #include "base/values.h" 18 #include "chrome/common/automation_messages.h" 19 #include "chrome/test/automation/automation_proxy.h" 20 21 using automation::Error; 22 using automation::ErrorCode; 23 using base::DictionaryValue; 24 using base::ListValue; 25 26 namespace { 27 28 bool SendAutomationJSONRequest(AutomationMessageSender* sender, 29 const DictionaryValue& request_dict, 30 DictionaryValue* reply_dict, 31 Error* error) { 32 std::string request, reply; 33 base::JSONWriter::Write(&request_dict, &request); 34 std::string command; 35 request_dict.GetString("command", &command); 36 LOG(INFO) << "Sending '" << command << "' command."; 37 38 base::Time before_sending = base::Time::Now(); 39 bool success = false; 40 if (!SendAutomationJSONRequestWithDefaultTimeout( 41 sender, request, &reply, &success)) { 42 *error = Error(base::StringPrintf( 43 "Chrome did not respond to '%s'. Elapsed time was %" PRId64 " ms.", 44 command.c_str(), 45 (base::Time::Now() - before_sending).InMilliseconds())); 46 LOG(INFO) << error->message(); 47 return false; 48 } 49 scoped_ptr<Value> value( 50 base::JSONReader::Read(reply, base::JSON_ALLOW_TRAILING_COMMAS)); 51 if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) { 52 *error = Error("JSON request did not return a dictionary"); 53 LOG(ERROR) << "JSON request did not return dict: " << command << "\n"; 54 return false; 55 } 56 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); 57 if (!success) { 58 std::string error_msg; 59 dict->GetString("error", &error_msg); 60 int int_code = automation::kUnknownError; 61 dict->GetInteger("code", &int_code); 62 ErrorCode code = static_cast<ErrorCode>(int_code); 63 *error = Error(code, error_msg); 64 LOG(INFO) << "JSON request failed: " << command << "\n" 65 << " with error: " << error_msg; 66 return false; 67 } 68 reply_dict->MergeDictionary(dict); 69 return true; 70 } 71 72 } // namespace 73 74 WebKeyEvent::WebKeyEvent(automation::KeyEventTypes type, 75 ui::KeyboardCode key_code, 76 const std::string& unmodified_text, 77 const std::string& modified_text, 78 int modifiers) 79 : type(type), 80 key_code(key_code), 81 unmodified_text(unmodified_text), 82 modified_text(modified_text), 83 modifiers(modifiers) {} 84 85 WebMouseEvent::WebMouseEvent(automation::MouseEventType type, 86 automation::MouseButton button, 87 int x, 88 int y, 89 int click_count, 90 int modifiers) 91 : type(type), 92 button(button), 93 x(x), 94 y(y), 95 click_count(click_count), 96 modifiers(modifiers) {} 97 98 // static 99 WebViewId WebViewId::ForView(const AutomationId& view_id) { 100 WebViewId id; 101 id.old_style_ = false; 102 id.id_ = view_id; 103 return id; 104 } 105 106 // static 107 WebViewId WebViewId::ForOldStyleTab(int tab_id) { 108 WebViewId id; 109 id.old_style_ = true; 110 id.tab_id_ = tab_id; 111 return id; 112 } 113 114 WebViewId::WebViewId() : old_style_(true) {} 115 116 void WebViewId::UpdateDictionary(DictionaryValue* dict, 117 const std::string& view_id_key) const { 118 if (old_style_) { 119 dict->SetInteger("id", tab_id_); 120 } else { 121 dict->Set(view_id_key, id_.ToValue()); 122 } 123 } 124 125 bool WebViewId::IsValid() const { 126 if (old_style_) 127 return tab_id_ != 0; 128 else 129 return id_.is_valid(); 130 } 131 132 AutomationId WebViewId::GetId() const { 133 if (old_style_) 134 return AutomationId(AutomationId::kTypeTab, base::IntToString(tab_id_)); 135 else 136 return id_; 137 } 138 139 bool WebViewId::IsTab() const { 140 return old_style_ || id_.type() == AutomationId::kTypeTab; 141 } 142 143 int WebViewId::tab_id() const { 144 return tab_id_; 145 } 146 147 bool WebViewId::old_style() const { 148 return old_style_; 149 } 150 151 // static 152 WebViewLocator WebViewLocator::ForIndexPair(int browser_index, int tab_index) { 153 WebViewLocator locator; 154 locator.type_ = kTypeIndexPair; 155 locator.locator_.index_pair.browser_index = browser_index; 156 locator.locator_.index_pair.tab_index = tab_index; 157 return locator; 158 } 159 160 // static 161 WebViewLocator WebViewLocator::ForViewId(const AutomationId& view_id) { 162 WebViewLocator locator; 163 locator.type_ = kTypeViewId; 164 locator.locator_.view_id = view_id; 165 return locator; 166 } 167 168 WebViewLocator::WebViewLocator() {} 169 170 WebViewLocator::~WebViewLocator() {} 171 172 void WebViewLocator::UpdateDictionary( 173 DictionaryValue* dict, const std::string& view_id_key) const { 174 if (type_ == kTypeIndexPair) { 175 dict->SetInteger("windex", locator_.index_pair.browser_index); 176 dict->SetInteger("tab_index", locator_.index_pair.tab_index); 177 } else if (type_ == kTypeViewId) { 178 dict->Set(view_id_key, locator_.view_id.ToValue()); 179 } 180 } 181 182 int WebViewLocator::browser_index() const { 183 return locator_.index_pair.browser_index; 184 } 185 186 int WebViewLocator::tab_index() const { 187 return locator_.index_pair.tab_index; 188 } 189 190 WebViewLocator::Locator::Locator() {} 191 192 WebViewLocator::Locator::~Locator() {} 193 194 WebViewInfo::WebViewInfo(const WebViewId& view_id, 195 const std::string& extension_id) 196 : view_id(view_id), 197 extension_id(extension_id) {} 198 199 WebViewInfo::~WebViewInfo() {} 200 201 bool SendAutomationJSONRequest(AutomationMessageSender* sender, 202 const std::string& request, 203 int timeout_ms, 204 std::string* reply, 205 bool* success) { 206 return sender->Send(new AutomationMsg_SendJSONRequest( 207 -1, request, reply, success), timeout_ms); 208 } 209 210 bool SendAutomationJSONRequestWithDefaultTimeout( 211 AutomationMessageSender* sender, 212 const std::string& request, 213 std::string* reply, 214 bool* success) { 215 return sender->Send(new AutomationMsg_SendJSONRequest( 216 -1, request, reply, success)); 217 } 218 219 bool SendGetIndicesFromTabIdJSONRequest( 220 AutomationMessageSender* sender, 221 int tab_id, 222 int* browser_index, 223 int* tab_index, 224 Error* error) { 225 DictionaryValue request_dict; 226 request_dict.SetString("command", "GetIndicesFromTab"); 227 request_dict.SetInteger("tab_id", tab_id); 228 DictionaryValue reply_dict; 229 if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict, error)) 230 return false; 231 if (!reply_dict.GetInteger("windex", browser_index)) 232 return false; 233 if (!reply_dict.GetInteger("tab_index", tab_index)) 234 return false; 235 return true; 236 } 237 238 bool SendGetIndicesFromTabHandleJSONRequest( 239 AutomationMessageSender* sender, 240 int tab_handle, 241 int* browser_index, 242 int* tab_index, 243 Error* error) { 244 DictionaryValue request_dict; 245 request_dict.SetString("command", "GetIndicesFromTab"); 246 request_dict.SetInteger("tab_handle", tab_handle); 247 DictionaryValue reply_dict; 248 if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict, error)) 249 return false; 250 if (!reply_dict.GetInteger("windex", browser_index)) 251 return false; 252 if (!reply_dict.GetInteger("tab_index", tab_index)) 253 return false; 254 return true; 255 } 256 257 bool SendNavigateToURLJSONRequest( 258 AutomationMessageSender* sender, 259 const WebViewLocator& locator, 260 const std::string& url, 261 int navigation_count, 262 AutomationMsg_NavigationResponseValues* nav_response, 263 Error* error) { 264 DictionaryValue dict; 265 dict.SetString("command", "NavigateToURL"); 266 locator.UpdateDictionary(&dict, "auto_id"); 267 dict.SetString("url", url); 268 dict.SetInteger("navigation_count", navigation_count); 269 DictionaryValue reply_dict; 270 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 271 return false; 272 // We don't expect a navigation result for asynchronous navigations. 273 if (navigation_count == 0) 274 return true; 275 int response = 0; 276 if (!reply_dict.GetInteger("result", &response)) 277 return false; 278 *nav_response = static_cast<AutomationMsg_NavigationResponseValues>(response); 279 return true; 280 } 281 282 bool SendExecuteJavascriptJSONRequest( 283 AutomationMessageSender* sender, 284 const WebViewLocator& locator, 285 const std::string& frame_xpath, 286 const std::string& javascript, 287 scoped_ptr<Value>* result, 288 Error* error) { 289 DictionaryValue dict; 290 dict.SetString("command", "ExecuteJavascript"); 291 locator.UpdateDictionary(&dict, "auto_id"); 292 dict.SetString("frame_xpath", frame_xpath); 293 dict.SetString("javascript", javascript); 294 DictionaryValue reply_dict; 295 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 296 return false; 297 298 std::string json; 299 if (!reply_dict.GetString("result", &json)) { 300 LOG(ERROR) << "Executed javascript but received no 'result'"; 301 return false; 302 } 303 // Wrap |json| in an array before deserializing because valid JSON has an 304 // array or an object as the root. 305 json.insert(0, "["); 306 json.append("]"); 307 308 JSONStringValueSerializer deserializer(json); 309 Value* value = deserializer.Deserialize(NULL, NULL); 310 if (!value || !value->IsType(Value::TYPE_LIST)) { 311 LOG(ERROR) << "Unable to deserialize returned JSON"; 312 return false; 313 } 314 scoped_ptr<ListValue> list(static_cast<ListValue*>(value)); 315 return list->Remove(0, result); 316 } 317 318 bool SendGoForwardJSONRequest( 319 AutomationMessageSender* sender, 320 const WebViewLocator& locator, 321 Error* error) { 322 DictionaryValue dict; 323 dict.SetString("command", "GoForward"); 324 locator.UpdateDictionary(&dict, "auto_id"); 325 DictionaryValue reply_dict; 326 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 327 } 328 329 bool SendGoBackJSONRequest( 330 AutomationMessageSender* sender, 331 const WebViewLocator& locator, 332 Error* error) { 333 DictionaryValue dict; 334 dict.SetString("command", "GoBack"); 335 locator.UpdateDictionary(&dict, "auto_id"); 336 DictionaryValue reply_dict; 337 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 338 } 339 340 bool SendReloadJSONRequest( 341 AutomationMessageSender* sender, 342 const WebViewLocator& locator, 343 Error* error) { 344 DictionaryValue dict; 345 dict.SetString("command", "Reload"); 346 locator.UpdateDictionary(&dict, "auto_id"); 347 DictionaryValue reply_dict; 348 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 349 } 350 351 bool SendCaptureEntirePageJSONRequestDeprecated( 352 AutomationMessageSender* sender, 353 const WebViewLocator& locator, 354 const base::FilePath& path, 355 Error* error) { 356 DictionaryValue dict; 357 dict.SetString("command", "CaptureEntirePage"); 358 locator.UpdateDictionary(&dict, "auto_id"); 359 dict.SetString("path", path.value()); 360 DictionaryValue reply_dict; 361 362 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 363 } 364 365 #if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS)) 366 bool SendHeapProfilerDumpJSONRequestDeprecated( 367 AutomationMessageSender* sender, 368 const WebViewLocator& locator, 369 const std::string& reason, 370 Error* error) { 371 DictionaryValue dict; 372 dict.SetString("command", "HeapProfilerDump"); 373 dict.SetString("process_type", "renderer"); 374 dict.SetString("reason", reason); 375 locator.UpdateDictionary(&dict, "auto_id"); 376 DictionaryValue reply_dict; 377 378 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 379 } 380 #endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS)) 381 382 bool SendGetCookiesJSONRequest( 383 AutomationMessageSender* sender, 384 const std::string& url, 385 scoped_ptr<ListValue>* cookies, 386 Error* error) { 387 DictionaryValue dict; 388 dict.SetString("command", "GetCookies"); 389 dict.SetString("url", url); 390 DictionaryValue reply_dict; 391 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 392 return false; 393 scoped_ptr<Value> cookies_value; 394 if (!reply_dict.Remove("cookies", &cookies_value)) 395 return false; 396 if (!cookies_value->IsType(Value::TYPE_LIST)) 397 return false; 398 cookies->reset(static_cast<ListValue*>(cookies_value.release())); 399 return true; 400 } 401 402 bool SendDeleteCookieJSONRequest( 403 AutomationMessageSender* sender, 404 const std::string& url, 405 const std::string& cookie_name, 406 Error* error) { 407 DictionaryValue dict; 408 dict.SetString("command", "DeleteCookie"); 409 dict.SetString("url", url); 410 dict.SetString("name", cookie_name); 411 DictionaryValue reply_dict; 412 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 413 } 414 415 bool SendSetCookieJSONRequest( 416 AutomationMessageSender* sender, 417 const std::string& url, 418 DictionaryValue* cookie_dict, 419 Error* error) { 420 DictionaryValue dict; 421 dict.SetString("command", "SetCookie"); 422 dict.SetString("url", url); 423 dict.Set("cookie", cookie_dict->DeepCopy()); 424 DictionaryValue reply_dict; 425 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 426 } 427 428 bool SendGetTabIdsJSONRequest( 429 AutomationMessageSender* sender, 430 std::vector<WebViewInfo>* views, 431 Error* error) { 432 DictionaryValue dict; 433 dict.SetString("command", "GetTabIds"); 434 DictionaryValue reply_dict; 435 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 436 return false; 437 ListValue* id_list; 438 if (reply_dict.GetList("ids", &id_list)) { 439 for (size_t i = 0; i < id_list->GetSize(); ++i) { 440 int id; 441 if (!id_list->GetInteger(i, &id)) { 442 *error = Error("Returned id in 'tab_ids' is not an integer"); 443 return false; 444 } 445 views->push_back(WebViewInfo( 446 WebViewId::ForOldStyleTab(id), std::string())); 447 } 448 } 449 return true; 450 } 451 452 bool SendGetWebViewsJSONRequest( 453 AutomationMessageSender* sender, 454 std::vector<WebViewInfo>* views, 455 Error* error) { 456 DictionaryValue dict; 457 dict.SetString("command", "GetViews"); 458 DictionaryValue reply_dict; 459 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 460 return false; 461 ListValue* views_list; 462 if (!reply_dict.GetList("views", &views_list)) { 463 *error = Error("Returned 'views' key is missing or invalid"); 464 return false; 465 } 466 for (size_t i = 0; i < views_list->GetSize(); ++i) { 467 DictionaryValue* view_dict; 468 if (!views_list->GetDictionary(i, &view_dict)) { 469 *error = Error("Returned 'views' key contains non-dictionary values"); 470 return false; 471 } 472 AutomationId view_id; 473 std::string error_msg; 474 if (!AutomationId::FromValueInDictionary( 475 view_dict, "auto_id", &view_id, &error_msg)) { 476 *error = Error(error_msg); 477 return false; 478 } 479 std::string extension_id; 480 view_dict->GetString("extension_id", &extension_id); 481 views->push_back(WebViewInfo( 482 WebViewId::ForView(view_id), extension_id)); 483 } 484 return true; 485 } 486 487 bool SendIsTabIdValidJSONRequest( 488 AutomationMessageSender* sender, 489 const WebViewId& view_id, 490 bool* is_valid, 491 Error* error) { 492 DictionaryValue dict; 493 dict.SetString("command", "IsTabIdValid"); 494 view_id.UpdateDictionary(&dict, "tab_id"); 495 DictionaryValue reply_dict; 496 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 497 return false; 498 return reply_dict.GetBoolean("is_valid", is_valid); 499 } 500 501 bool SendDoesAutomationObjectExistJSONRequest( 502 AutomationMessageSender* sender, 503 const WebViewId& view_id, 504 bool* does_exist, 505 Error* error) { 506 DictionaryValue dict; 507 dict.SetString("command", "DoesAutomationObjectExist"); 508 view_id.UpdateDictionary(&dict, "auto_id"); 509 DictionaryValue reply_dict; 510 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 511 return false; 512 return reply_dict.GetBoolean("does_exist", does_exist); 513 } 514 515 bool SendCloseViewJSONRequest( 516 AutomationMessageSender* sender, 517 const WebViewLocator& locator, 518 Error* error) { 519 DictionaryValue dict; 520 dict.SetString("command", "CloseTab"); 521 locator.UpdateDictionary(&dict, "auto_id"); 522 DictionaryValue reply_dict; 523 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 524 } 525 526 bool SendMouseMoveJSONRequestDeprecated( 527 AutomationMessageSender* sender, 528 const WebViewLocator& locator, 529 int x, 530 int y, 531 Error* error) { 532 DictionaryValue dict; 533 dict.SetString("command", "WebkitMouseMove"); 534 locator.UpdateDictionary(&dict, "auto_id"); 535 dict.SetInteger("x", x); 536 dict.SetInteger("y", y); 537 DictionaryValue reply_dict; 538 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 539 } 540 541 bool SendMouseClickJSONRequestDeprecated( 542 AutomationMessageSender* sender, 543 const WebViewLocator& locator, 544 automation::MouseButton button, 545 int x, 546 int y, 547 Error* error) { 548 DictionaryValue dict; 549 dict.SetString("command", "WebkitMouseClick"); 550 locator.UpdateDictionary(&dict, "auto_id"); 551 dict.SetInteger("button", button); 552 dict.SetInteger("x", x); 553 dict.SetInteger("y", y); 554 DictionaryValue reply_dict; 555 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 556 } 557 558 bool SendMouseDragJSONRequestDeprecated( 559 AutomationMessageSender* sender, 560 const WebViewLocator& locator, 561 int start_x, 562 int start_y, 563 int end_x, 564 int end_y, 565 Error* error) { 566 DictionaryValue dict; 567 dict.SetString("command", "WebkitMouseDrag"); 568 locator.UpdateDictionary(&dict, "auto_id"); 569 dict.SetInteger("start_x", start_x); 570 dict.SetInteger("start_y", start_y); 571 dict.SetInteger("end_x", end_x); 572 dict.SetInteger("end_y", end_y); 573 DictionaryValue reply_dict; 574 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 575 } 576 577 bool SendMouseButtonDownJSONRequestDeprecated( 578 AutomationMessageSender* sender, 579 const WebViewLocator& locator, 580 int x, 581 int y, 582 Error* error) { 583 DictionaryValue dict; 584 dict.SetString("command", "WebkitMouseButtonDown"); 585 locator.UpdateDictionary(&dict, "auto_id"); 586 dict.SetInteger("x", x); 587 dict.SetInteger("y", y); 588 DictionaryValue reply_dict; 589 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 590 } 591 592 bool SendMouseButtonUpJSONRequestDeprecated( 593 AutomationMessageSender* sender, 594 const WebViewLocator& locator, 595 int x, 596 int y, 597 Error* error) { 598 DictionaryValue dict; 599 dict.SetString("command", "WebkitMouseButtonUp"); 600 locator.UpdateDictionary(&dict, "auto_id"); 601 dict.SetInteger("x", x); 602 dict.SetInteger("y", y); 603 DictionaryValue reply_dict; 604 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 605 } 606 607 bool SendMouseDoubleClickJSONRequestDeprecated( 608 AutomationMessageSender* sender, 609 const WebViewLocator& locator, 610 int x, 611 int y, 612 Error* error) { 613 DictionaryValue dict; 614 dict.SetString("command", "WebkitMouseDoubleClick"); 615 locator.UpdateDictionary(&dict, "auto_id"); 616 dict.SetInteger("x", x); 617 dict.SetInteger("y", y); 618 DictionaryValue reply_dict; 619 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 620 } 621 622 bool SendWebKeyEventJSONRequest( 623 AutomationMessageSender* sender, 624 const WebViewLocator& locator, 625 const WebKeyEvent& key_event, 626 Error* error) { 627 DictionaryValue dict; 628 dict.SetString("command", "SendWebkitKeyEvent"); 629 locator.UpdateDictionary(&dict, "auto_id"); 630 dict.SetInteger("type", key_event.type); 631 dict.SetInteger("nativeKeyCode", key_event.key_code); 632 dict.SetInteger("windowsKeyCode", key_event.key_code); 633 dict.SetString("unmodifiedText", key_event.unmodified_text); 634 dict.SetString("text", key_event.modified_text); 635 dict.SetInteger("modifiers", key_event.modifiers); 636 dict.SetBoolean("isSystemKey", false); 637 DictionaryValue reply_dict; 638 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 639 } 640 641 bool SendNativeKeyEventJSONRequest( 642 AutomationMessageSender* sender, 643 const WebViewLocator& locator, 644 ui::KeyboardCode key_code, 645 int modifiers, 646 Error* error) { 647 DictionaryValue dict; 648 dict.SetString("command", "SendOSLevelKeyEventToTab"); 649 locator.UpdateDictionary(&dict, "auto_id"); 650 dict.SetInteger("keyCode", key_code); 651 dict.SetInteger("modifiers", modifiers); 652 DictionaryValue reply_dict; 653 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 654 } 655 656 bool SendWebMouseEventJSONRequestDeprecated( 657 AutomationMessageSender* sender, 658 const WebViewLocator& locator, 659 const WebMouseEvent& mouse_event, 660 automation::Error* error) { 661 DictionaryValue dict; 662 dict.SetString("command", "ProcessWebMouseEvent"); 663 locator.UpdateDictionary(&dict, "auto_id"); 664 dict.SetInteger("type", mouse_event.type); 665 dict.SetInteger("button", mouse_event.button); 666 dict.SetInteger("x", mouse_event.x); 667 dict.SetInteger("y", mouse_event.y); 668 dict.SetInteger("click_count", mouse_event.click_count); 669 dict.SetInteger("modifiers", mouse_event.modifiers); 670 DictionaryValue reply_dict; 671 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 672 } 673 674 bool SendDragAndDropFilePathsJSONRequest( 675 AutomationMessageSender* sender, 676 const WebViewLocator& locator, 677 int x, 678 int y, 679 const std::vector<base::FilePath::StringType>& paths, 680 Error* error) { 681 DictionaryValue dict; 682 dict.SetString("command", "DragAndDropFilePaths"); 683 locator.UpdateDictionary(&dict, "auto_id"); 684 dict.SetInteger("x", x); 685 dict.SetInteger("y", y); 686 687 ListValue* list_value = new ListValue(); 688 for (size_t path_index = 0; path_index < paths.size(); ++path_index) { 689 list_value->Append(new base::StringValue(paths[path_index])); 690 } 691 dict.Set("paths", list_value); 692 693 DictionaryValue reply_dict; 694 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 695 } 696 697 bool SendSetViewBoundsJSONRequest( 698 AutomationMessageSender* sender, 699 const WebViewId& id, 700 int x, 701 int y, 702 int width, 703 int height, 704 automation::Error* error) { 705 DictionaryValue dict; 706 dict.SetString("command", "SetViewBounds"); 707 id.UpdateDictionary(&dict, "auto_id"); 708 dict.SetInteger("bounds.x", x); 709 dict.SetInteger("bounds.y", y); 710 dict.SetInteger("bounds.width", width); 711 dict.SetInteger("bounds.height", height); 712 713 DictionaryValue reply_dict; 714 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 715 } 716 717 bool SendMaximizeJSONRequest( 718 AutomationMessageSender* sender, 719 const WebViewId& id, 720 automation::Error* error) { 721 DictionaryValue dict; 722 dict.SetString("command", "MaximizeView"); 723 id.UpdateDictionary(&dict, "auto_id"); 724 725 DictionaryValue reply_dict; 726 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 727 } 728 729 bool SendGetAppModalDialogMessageJSONRequest( 730 AutomationMessageSender* sender, 731 std::string* message, 732 Error* error) { 733 DictionaryValue dict; 734 dict.SetString("command", "GetAppModalDialogMessage"); 735 DictionaryValue reply_dict; 736 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 737 return false; 738 return reply_dict.GetString("message", message); 739 } 740 741 bool SendAcceptOrDismissAppModalDialogJSONRequest( 742 AutomationMessageSender* sender, 743 bool accept, 744 Error* error) { 745 DictionaryValue dict; 746 dict.SetString("command", "AcceptOrDismissAppModalDialog"); 747 dict.SetBoolean("accept", accept); 748 DictionaryValue reply_dict; 749 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 750 } 751 752 bool SendAcceptPromptAppModalDialogJSONRequest( 753 AutomationMessageSender* sender, 754 const std::string& prompt_text, 755 Error* error) { 756 DictionaryValue dict; 757 dict.SetString("command", "AcceptOrDismissAppModalDialog"); 758 dict.SetBoolean("accept", true); 759 dict.SetString("prompt_text", prompt_text); 760 DictionaryValue reply_dict; 761 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 762 } 763 764 bool SendWaitForAllViewsToStopLoadingJSONRequestDeprecated( 765 AutomationMessageSender* sender, 766 Error* error) { 767 DictionaryValue dict; 768 dict.SetString("command", "WaitForAllTabsToStopLoading"); 769 DictionaryValue reply_dict; 770 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 771 } 772 773 bool SendGetChromeDriverAutomationVersion( 774 AutomationMessageSender* sender, 775 int* version, 776 Error* error) { 777 DictionaryValue dict; 778 dict.SetString("command", "GetChromeDriverAutomationVersion"); 779 DictionaryValue reply_dict; 780 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 781 return false; 782 return reply_dict.GetInteger("version", version); 783 } 784 785 bool SendInstallExtensionJSONRequest( 786 AutomationMessageSender* sender, 787 const base::FilePath& path, 788 bool with_ui, 789 std::string* extension_id, 790 Error* error) { 791 DictionaryValue dict; 792 dict.SetString("command", "InstallExtension"); 793 dict.SetString("path", path.value()); 794 dict.SetBoolean("with_ui", with_ui); 795 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 796 dict.SetInteger("windex", 0); 797 dict.SetInteger("tab_index", 0); 798 DictionaryValue reply_dict; 799 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 800 return false; 801 if (!reply_dict.GetString("id", extension_id)) { 802 *error = Error("Missing or invalid 'id'"); 803 return false; 804 } 805 return true; 806 } 807 808 bool SendGetExtensionsInfoJSONRequest( 809 AutomationMessageSender* sender, 810 ListValue* extensions_list, 811 Error* error) { 812 DictionaryValue dict; 813 dict.SetString("command", "GetExtensionsInfo"); 814 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 815 dict.SetInteger("windex", 0); 816 DictionaryValue reply_dict; 817 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 818 return false; 819 ListValue* extensions_list_swap; 820 if (!reply_dict.GetList("extensions", &extensions_list_swap)) { 821 *error = Error("Missing or invalid 'extensions'"); 822 return false; 823 } 824 extensions_list->Swap(extensions_list_swap); 825 return true; 826 } 827 828 bool SendIsPageActionVisibleJSONRequest( 829 AutomationMessageSender* sender, 830 const WebViewId& tab_id, 831 const std::string& extension_id, 832 bool* is_visible, 833 Error* error) { 834 DictionaryValue dict; 835 dict.SetString("command", "IsPageActionVisible"); 836 tab_id.UpdateDictionary(&dict, "auto_id"); 837 dict.SetString("extension_id", extension_id); 838 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 839 dict.SetInteger("windex", 0); 840 DictionaryValue reply_dict; 841 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 842 return false; 843 if (!reply_dict.GetBoolean("is_visible", is_visible)) { 844 *error = Error("Missing or invalid 'is_visible'"); 845 return false; 846 } 847 return true; 848 } 849 850 bool SendSetExtensionStateJSONRequest( 851 AutomationMessageSender* sender, 852 const std::string& extension_id, 853 bool enable, 854 bool allow_in_incognito, 855 Error* error) { 856 DictionaryValue dict; 857 dict.SetString("command", "SetExtensionStateById"); 858 dict.SetString("id", extension_id); 859 dict.SetBoolean("enable", enable); 860 dict.SetBoolean("allow_in_incognito", allow_in_incognito); 861 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 862 dict.SetInteger("windex", 0); 863 DictionaryValue reply_dict; 864 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 865 } 866 867 bool SendClickExtensionButtonJSONRequest( 868 AutomationMessageSender* sender, 869 const std::string& extension_id, 870 bool browser_action, 871 Error* error) { 872 DictionaryValue dict; 873 if (browser_action) 874 dict.SetString("command", "TriggerBrowserActionById"); 875 else 876 dict.SetString("command", "TriggerPageActionById"); 877 dict.SetString("id", extension_id); 878 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 879 dict.SetInteger("windex", 0); 880 dict.SetInteger("tab_index", 0); 881 DictionaryValue reply_dict; 882 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 883 } 884 885 bool SendUninstallExtensionJSONRequest( 886 AutomationMessageSender* sender, 887 const std::string& extension_id, 888 Error* error) { 889 DictionaryValue dict; 890 dict.SetString("command", "UninstallExtensionById"); 891 dict.SetString("id", extension_id); 892 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 893 dict.SetInteger("windex", 0); 894 DictionaryValue reply_dict; 895 if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error)) 896 return false; 897 bool success; 898 if (!reply_dict.GetBoolean("success", &success)) { 899 *error = Error("Missing or invalid 'success'"); 900 return false; 901 } 902 if (!success) { 903 *error = Error("Extension uninstall not permitted"); 904 return false; 905 } 906 return true; 907 } 908 909 bool SendSetLocalStatePreferenceJSONRequest( 910 AutomationMessageSender* sender, 911 const std::string& pref, 912 base::Value* value, 913 Error* error) { 914 DictionaryValue dict; 915 dict.SetString("command", "SetLocalStatePrefs"); 916 dict.SetString("path", pref); 917 dict.Set("value", value); 918 DictionaryValue reply_dict; 919 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 920 } 921 922 bool SendSetPreferenceJSONRequest( 923 AutomationMessageSender* sender, 924 const std::string& pref, 925 base::Value* value, 926 Error* error) { 927 DictionaryValue dict; 928 dict.SetString("command", "SetPrefs"); 929 // TODO(kkania): Set correct auto_id instead of hardcoding windex. 930 dict.SetInteger("windex", 0); 931 dict.SetString("path", pref); 932 dict.Set("value", value); 933 DictionaryValue reply_dict; 934 return SendAutomationJSONRequest(sender, dict, &reply_dict, error); 935 } 936 937 bool SendOverrideGeolocationJSONRequest( 938 AutomationMessageSender* sender, 939 const base::DictionaryValue* geolocation, 940 Error* error) { 941 scoped_ptr<DictionaryValue> dict(geolocation->DeepCopy()); 942 dict->SetString("command", "OverrideGeoposition"); 943 DictionaryValue reply_dict; 944 return SendAutomationJSONRequest(sender, *dict.get(), &reply_dict, error); 945 } 946