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.
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"
23 PyUITestSuiteBase::PyUITestSuiteBase(int argc
, char** argv
)
24 : UITestSuite(argc
, argv
) {
27 PyUITestSuiteBase::~PyUITestSuiteBase() {
28 #if defined(OS_MACOSX)
34 void PyUITestSuiteBase::InitializeWithPath(const base::FilePath
& browser_dir
) {
35 SetBrowserDirectory(browser_dir
);
36 UITestSuite::Initialize();
39 void PyUITestSuiteBase::SetCrSourceRoot(const base::FilePath
& path
) {
40 PathService::Override(base::DIR_SOURCE_ROOT
, path
);
44 PyUITestBase::PyUITestBase(bool clear_profile
, std::wstring homepage
)
46 set_clear_profile(clear_profile
);
47 set_homepage(WideToASCII(homepage
));
48 // We add this so that pyauto can execute javascript in the renderer and
50 dom_automation_enabled_
= true;
51 message_loop_
= GetSharedMessageLoop(base::MessageLoop::TYPE_DEFAULT
);
54 PyUITestBase::~PyUITestBase() {
57 // static, refer .h for why it needs to be static
58 base::MessageLoop
* PyUITestBase::message_loop_
= NULL
;
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
);
68 void PyUITestBase::Initialize(const base::FilePath
& browser_dir
) {
69 UITestBase::SetBrowserDirectory(browser_dir
);
72 ProxyLauncher
* PyUITestBase::CreateProxyLauncher() {
73 if (named_channel_id_
.empty())
74 return new AnonymousProxyLauncher(false);
75 return new NamedProxyLauncher(named_channel_id_
, false, false);
78 void PyUITestBase::SetUp() {
82 void PyUITestBase::TearDown() {
83 UITestBase::TearDown();
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_
);
92 UITestBase::SetLaunchSwitches();
94 // However, we *do* want the --homepage switch.
95 std::swap(homepage_original
, homepage_
);
96 launch_arguments_
.AppendSwitchASCII(switches::kHomePage
, homepage_
);
99 AutomationProxy
* PyUITestBase::automation() const {
100 AutomationProxy
* automation_proxy
= UITestBase::automation();
101 if (!automation_proxy
) {
102 LOG(FATAL
) << "The automation proxy is NULL.";
104 return automation_proxy
;
107 std::string
PyUITestBase::_SendJSONRequest(int window_index
,
108 const std::string
& request
,
110 std::string response
;
112 AutomationProxy
* automation_sender
= automation();
113 base::TimeTicks time
= base::TimeTicks::Now();
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
,
124 RequestFailureResponse(request
, base::TimeTicks::Now() - time
,
125 base::TimeDelta::FromMilliseconds(timeout
),
131 void PyUITestBase::ErrorResponse(
132 const std::string
& error_string
,
133 const std::string
& request
,
135 std::string
* response
) {
136 base::DictionaryValue error_dict
;
137 std::string error_msg
= base::StringPrintf("%s for %s", error_string
.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
);
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
) {
154 base::StringPrintf("Chrome automation timed out after %d seconds",
155 static_cast<int>(duration
.InSeconds())),
156 request
, true, response
);
158 // TODO(craigdh): Determine specific cause.
160 "Chrome automation failed prior to timing out, did chrome crash?",
161 request
, false, response
);