| OLD | NEW |
| (Empty) |
| 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 "base/base_paths.h" | |
| 6 #include "base/json/json_writer.h" | |
| 7 #include "base/logging.h" | |
| 8 #include "base/memory/scoped_ptr.h" | |
| 9 #include "base/path_service.h" | |
| 10 #include "base/strings/string_number_conversions.h" | |
| 11 #include "base/strings/string_util.h" | |
| 12 #include "base/strings/utf_string_conversions.h" | |
| 13 #include "base/time/time.h" | |
| 14 #include "base/values.h" | |
| 15 #include "chrome/common/automation_messages.h" | |
| 16 #include "chrome/common/chrome_switches.h" | |
| 17 #include "chrome/test/automation/automation_proxy.h" | |
| 18 #include "chrome/test/automation/tab_proxy.h" | |
| 19 #include "chrome/test/pyautolib/pyautolib.h" | |
| 20 #include "url/gurl.h" | |
| 21 | |
| 22 // PyUITestSuiteBase | |
| 23 PyUITestSuiteBase::PyUITestSuiteBase(int argc, char** argv) | |
| 24 : UITestSuite(argc, argv) { | |
| 25 } | |
| 26 | |
| 27 PyUITestSuiteBase::~PyUITestSuiteBase() { | |
| 28 #if defined(OS_MACOSX) | |
| 29 pool_.Recycle(); | |
| 30 #endif | |
| 31 Shutdown(); | |
| 32 } | |
| 33 | |
| 34 void PyUITestSuiteBase::InitializeWithPath(const base::FilePath& browser_dir) { | |
| 35 SetBrowserDirectory(browser_dir); | |
| 36 UITestSuite::Initialize(); | |
| 37 } | |
| 38 | |
| 39 void PyUITestSuiteBase::SetCrSourceRoot(const base::FilePath& path) { | |
| 40 PathService::Override(base::DIR_SOURCE_ROOT, path); | |
| 41 } | |
| 42 | |
| 43 // PyUITestBase | |
| 44 PyUITestBase::PyUITestBase(bool clear_profile, std::wstring homepage) | |
| 45 : UITestBase() { | |
| 46 set_clear_profile(clear_profile); | |
| 47 set_homepage(base::WideToUTF8(homepage)); | |
| 48 // We add this so that pyauto can execute javascript in the renderer and | |
| 49 // read values back. | |
| 50 dom_automation_enabled_ = true; | |
| 51 message_loop_ = GetSharedMessageLoop(base::MessageLoop::TYPE_DEFAULT); | |
| 52 } | |
| 53 | |
| 54 PyUITestBase::~PyUITestBase() { | |
| 55 } | |
| 56 | |
| 57 // static, refer .h for why it needs to be static | |
| 58 base::MessageLoop* PyUITestBase::message_loop_ = NULL; | |
| 59 | |
| 60 // static | |
| 61 base::MessageLoop* PyUITestBase::GetSharedMessageLoop( | |
| 62 base::MessageLoop::Type msg_loop_type) { | |
| 63 if (!message_loop_) // Create a shared instance of MessageLoop | |
| 64 message_loop_ = new base::MessageLoop(msg_loop_type); | |
| 65 return message_loop_; | |
| 66 } | |
| 67 | |
| 68 void PyUITestBase::Initialize(const base::FilePath& browser_dir) { | |
| 69 UITestBase::SetBrowserDirectory(browser_dir); | |
| 70 } | |
| 71 | |
| 72 ProxyLauncher* PyUITestBase::CreateProxyLauncher() { | |
| 73 if (named_channel_id_.empty()) | |
| 74 return new AnonymousProxyLauncher(false); | |
| 75 return new NamedProxyLauncher(named_channel_id_, false, false); | |
| 76 } | |
| 77 | |
| 78 void PyUITestBase::SetUp() { | |
| 79 UITestBase::SetUp(); | |
| 80 } | |
| 81 | |
| 82 void PyUITestBase::TearDown() { | |
| 83 UITestBase::TearDown(); | |
| 84 } | |
| 85 | |
| 86 void PyUITestBase::SetLaunchSwitches() { | |
| 87 // Clear the homepage because some of the pyauto tests don't work correctly | |
| 88 // if a URL argument is passed. | |
| 89 std::string homepage_original; | |
| 90 std::swap(homepage_original, homepage_); | |
| 91 | |
| 92 UITestBase::SetLaunchSwitches(); | |
| 93 | |
| 94 // However, we *do* want the --homepage switch. | |
| 95 std::swap(homepage_original, homepage_); | |
| 96 launch_arguments_.AppendSwitchASCII(switches::kHomePage, homepage_); | |
| 97 } | |
| 98 | |
| 99 AutomationProxy* PyUITestBase::automation() const { | |
| 100 AutomationProxy* automation_proxy = UITestBase::automation(); | |
| 101 if (!automation_proxy) { | |
| 102 LOG(FATAL) << "The automation proxy is NULL."; | |
| 103 } | |
| 104 return automation_proxy; | |
| 105 } | |
| 106 | |
| 107 std::string PyUITestBase::_SendJSONRequest(int window_index, | |
| 108 const std::string& request, | |
| 109 int timeout) { | |
| 110 std::string response; | |
| 111 bool success; | |
| 112 AutomationProxy* automation_sender = automation(); | |
| 113 base::TimeTicks time = base::TimeTicks::Now(); | |
| 114 | |
| 115 if (!automation_sender) { | |
| 116 ErrorResponse("Automation proxy does not exist", request, false, &response); | |
| 117 } else if (!automation_sender->channel()) { | |
| 118 ErrorResponse("Chrome automation IPC channel was found already broken", | |
| 119 request, false, &response); | |
| 120 } else if (!automation_sender->Send( | |
| 121 new AutomationMsg_SendJSONRequest(window_index, request, &response, | |
| 122 &success), | |
| 123 timeout)) { | |
| 124 RequestFailureResponse(request, base::TimeTicks::Now() - time, | |
| 125 base::TimeDelta::FromMilliseconds(timeout), | |
| 126 &response); | |
| 127 } | |
| 128 return response; | |
| 129 } | |
| 130 | |
| 131 void PyUITestBase::ErrorResponse( | |
| 132 const std::string& error_string, | |
| 133 const std::string& request, | |
| 134 bool is_timeout, | |
| 135 std::string* response) { | |
| 136 base::DictionaryValue error_dict; | |
| 137 std::string error_msg = base::StringPrintf("%s for %s", error_string.c_str(), | |
| 138 request.c_str()); | |
| 139 LOG(ERROR) << "Error during automation: " << error_msg; | |
| 140 error_dict.SetString("error", error_msg); | |
| 141 error_dict.SetBoolean("is_interface_error", true); | |
| 142 error_dict.SetBoolean("is_interface_timeout", is_timeout); | |
| 143 base::JSONWriter::Write(&error_dict, response); | |
| 144 } | |
| 145 | |
| 146 void PyUITestBase::RequestFailureResponse( | |
| 147 const std::string& request, | |
| 148 const base::TimeDelta& duration, | |
| 149 const base::TimeDelta& timeout, | |
| 150 std::string* response) { | |
| 151 // TODO(craigdh): Determine timeout directly from IPC's Send(). | |
| 152 if (duration >= timeout) { | |
| 153 ErrorResponse( | |
| 154 base::StringPrintf("Chrome automation timed out after %d seconds", | |
| 155 static_cast<int>(duration.InSeconds())), | |
| 156 request, true, response); | |
| 157 } else { | |
| 158 // TODO(craigdh): Determine specific cause. | |
| 159 ErrorResponse( | |
| 160 "Chrome automation failed prior to timing out, did chrome crash?", | |
| 161 request, false, response); | |
| 162 } | |
| 163 } | |
| OLD | NEW |