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 "chrome/test/automation/tab_proxy.h"
9 #include "base/json/json_string_value_serializer.h"
10 #include "base/logging.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/threading/platform_thread.h"
14 #include "chrome/common/automation_constants.h"
15 #include "chrome/common/automation_messages.h"
16 #include "chrome/test/automation/automation_proxy.h"
17 #include "chrome/test/automation/browser_proxy.h"
20 TabProxy::TabProxy(AutomationMessageSender
* sender
,
21 AutomationHandleTracker
* tracker
,
23 : AutomationResourceProxy(tracker
, sender
, handle
) {
26 bool TabProxy::GetTabTitle(std::wstring
* title
) const {
35 int tab_title_size_response
= 0;
37 bool succeeded
= sender_
->Send(
38 new AutomationMsg_TabTitle(handle_
, &tab_title_size_response
, title
));
42 bool TabProxy::GetTabIndex(int* index
) const {
51 return sender_
->Send(new AutomationMsg_TabIndex(handle_
, index
));
54 int TabProxy::FindInPage(const std::wstring
& search_string
,
55 FindInPageDirection forward
,
56 FindInPageCase match_case
,
62 AutomationMsg_Find_Params params
;
63 params
.search_string
= WideToUTF16Hack(search_string
);
64 params
.find_next
= find_next
;
65 params
.match_case
= (match_case
== CASE_SENSITIVE
);
66 params
.forward
= (forward
== FWD
);
70 bool succeeded
= sender_
->Send(new AutomationMsg_Find(handle_
,
81 AutomationMsg_NavigationResponseValues
TabProxy::NavigateToURL(
83 return NavigateToURLBlockUntilNavigationsComplete(url
, 1);
86 AutomationMsg_NavigationResponseValues
87 TabProxy::NavigateToURLBlockUntilNavigationsComplete(
88 const GURL
& url
, int number_of_navigations
) {
90 return AUTOMATION_MSG_NAVIGATION_ERROR
;
92 AutomationMsg_NavigationResponseValues navigate_response
=
93 AUTOMATION_MSG_NAVIGATION_ERROR
;
95 sender_
->Send(new AutomationMsg_NavigateToURLBlockUntilNavigationsComplete(
96 handle_
, url
, number_of_navigations
, &navigate_response
));
98 return navigate_response
;
101 AutomationMsg_NavigationResponseValues
TabProxy::GoBack() {
102 return GoBackBlockUntilNavigationsComplete(1);
105 AutomationMsg_NavigationResponseValues
106 TabProxy::GoBackBlockUntilNavigationsComplete(int number_of_navigations
) {
108 return AUTOMATION_MSG_NAVIGATION_ERROR
;
110 AutomationMsg_NavigationResponseValues navigate_response
=
111 AUTOMATION_MSG_NAVIGATION_ERROR
;
112 sender_
->Send(new AutomationMsg_GoBackBlockUntilNavigationsComplete(
113 handle_
, number_of_navigations
, &navigate_response
));
114 return navigate_response
;
117 AutomationMsg_NavigationResponseValues
TabProxy::GoForward() {
118 return GoForwardBlockUntilNavigationsComplete(1);
121 AutomationMsg_NavigationResponseValues
122 TabProxy::GoForwardBlockUntilNavigationsComplete(
123 int number_of_navigations
) {
125 return AUTOMATION_MSG_NAVIGATION_ERROR
;
127 AutomationMsg_NavigationResponseValues navigate_response
=
128 AUTOMATION_MSG_NAVIGATION_ERROR
;
129 sender_
->Send(new AutomationMsg_GoForwardBlockUntilNavigationsComplete(
130 handle_
, number_of_navigations
, &navigate_response
));
131 return navigate_response
;
134 AutomationMsg_NavigationResponseValues
TabProxy::Reload() {
136 return AUTOMATION_MSG_NAVIGATION_ERROR
;
138 AutomationMsg_NavigationResponseValues navigate_response
=
139 AUTOMATION_MSG_NAVIGATION_ERROR
;
140 sender_
->Send(new AutomationMsg_Reload(handle_
, &navigate_response
));
141 return navigate_response
;
144 bool TabProxy::GetCurrentURL(GURL
* url
) const {
153 bool succeeded
= false;
154 sender_
->Send(new AutomationMsg_TabURL(handle_
, &succeeded
, url
));
158 bool TabProxy::NavigateToURLAsync(const GURL
& url
) {
163 sender_
->Send(new AutomationMsg_NavigationAsync(handle_
,
169 bool TabProxy::ExecuteAndExtractString(const std::wstring
& frame_xpath
,
170 const std::wstring
& jscript
,
171 std::wstring
* string_value
) {
172 scoped_ptr
<Value
> root(ExecuteAndExtractValue(frame_xpath
, jscript
));
176 DCHECK(root
->IsType(Value::TYPE_LIST
));
178 bool succeeded
= static_cast<ListValue
*>(root
.get())->Get(0, &value
);
181 succeeded
= value
->GetAsString(&read_value
);
183 // TODO(viettrungluu): remove conversion. (But should |jscript| be UTF-8?)
184 *string_value
= UTF16ToWideHack(read_value
);
190 bool TabProxy::ExecuteAndExtractBool(const std::wstring
& frame_xpath
,
191 const std::wstring
& jscript
,
193 scoped_ptr
<Value
> root(ExecuteAndExtractValue(frame_xpath
, jscript
));
197 bool read_value
= false;
198 DCHECK(root
->IsType(Value::TYPE_LIST
));
200 bool succeeded
= static_cast<ListValue
*>(root
.get())->Get(0, &value
);
202 succeeded
= value
->GetAsBoolean(&read_value
);
204 *bool_value
= read_value
;
210 bool TabProxy::ExecuteAndExtractInt(const std::wstring
& frame_xpath
,
211 const std::wstring
& jscript
,
213 scoped_ptr
<Value
> root(ExecuteAndExtractValue(frame_xpath
, jscript
));
218 DCHECK(root
->IsType(Value::TYPE_LIST
));
220 bool succeeded
= static_cast<ListValue
*>(root
.get())->Get(0, &value
);
222 succeeded
= value
->GetAsInteger(&read_value
);
224 *int_value
= read_value
;
230 Value
* TabProxy::ExecuteAndExtractValue(const std::wstring
& frame_xpath
,
231 const std::wstring
& jscript
) {
236 if (!sender_
->Send(new AutomationMsg_DomOperation(handle_
, frame_xpath
,
240 // Wrap |json| in an array before deserializing because valid JSON has an
241 // array or an object as the root.
245 JSONStringValueSerializer
deserializer(json
);
246 return deserializer
.Deserialize(NULL
, NULL
);
249 bool TabProxy::GetCookies(const GURL
& url
, std::string
* cookies
) {
254 return sender_
->Send(new AutomationMsg_GetCookies(url
, handle_
, &size
,
258 bool TabProxy::GetCookieByName(const GURL
& url
,
259 const std::string
& name
,
260 std::string
* cookie
) {
262 if (!GetCookies(url
, &cookies
))
265 std::string namestr
= name
+ "=";
266 std::string::size_type idx
= cookies
.find(namestr
);
267 if (idx
!= std::string::npos
) {
268 cookies
.erase(0, idx
+ namestr
.length());
269 *cookie
= cookies
.substr(0, cookies
.find(";"));
277 bool TabProxy::Close() {
281 bool TabProxy::Close(bool wait_until_closed
) {
285 bool succeeded
= false;
286 sender_
->Send(new AutomationMsg_CloseTab(handle_
, wait_until_closed
,
292 bool TabProxy::ProcessUnhandledAccelerator(const MSG
& msg
) {
296 return sender_
->Send(
297 new AutomationMsg_ProcessUnhandledAccelerator(handle_
, msg
));
298 // This message expects no response
301 bool TabProxy::SetInitialFocus(bool reverse
, bool restore_focus_to_view
) {
305 return sender_
->Send(
306 new AutomationMsg_SetInitialFocus(handle_
, reverse
,
307 restore_focus_to_view
));
308 // This message expects no response
311 AutomationMsg_NavigationResponseValues
TabProxy::NavigateInExternalTab(
312 const GURL
& url
, const GURL
& referrer
) {
314 return AUTOMATION_MSG_NAVIGATION_ERROR
;
316 AutomationMsg_NavigationResponseValues rv
= AUTOMATION_MSG_NAVIGATION_ERROR
;
317 sender_
->Send(new AutomationMsg_NavigateInExternalTab(handle_
, url
,
322 AutomationMsg_NavigationResponseValues
TabProxy::NavigateExternalTabAtIndex(
325 return AUTOMATION_MSG_NAVIGATION_ERROR
;
327 AutomationMsg_NavigationResponseValues rv
= AUTOMATION_MSG_NAVIGATION_ERROR
;
328 sender_
->Send(new AutomationMsg_NavigateExternalTabAtIndex(handle_
, index
,
333 void TabProxy::HandleMessageFromExternalHost(const std::string
& message
,
334 const std::string
& origin
,
335 const std::string
& target
) {
340 new AutomationMsg_HandleMessageFromExternalHost(
341 handle_
, message
, origin
, target
));
343 #endif // defined(OS_WIN)
345 bool TabProxy::PrintAsync() {
349 return sender_
->Send(new AutomationMsg_PrintAsync(handle_
));
352 bool TabProxy::WaitForInfoBarCount(size_t target_count
) {
356 bool success
= false;
357 return sender_
->Send(new AutomationMsg_WaitForInfoBarCount(
358 handle_
, target_count
, &success
)) && success
;
361 bool TabProxy::OverrideEncoding(const std::string
& encoding
) {
365 bool succeeded
= false;
366 sender_
->Send(new AutomationMsg_OverrideEncoding(handle_
, encoding
,
372 void TabProxy::Reposition(HWND window
, HWND window_insert_after
, int left
,
373 int top
, int width
, int height
, int flags
,
374 HWND parent_window
) {
375 Reposition_Params params
;
376 params
.window
= window
;
377 params
.window_insert_after
= window_insert_after
;
380 params
.width
= width
;
381 params
.height
= height
;
382 params
.flags
= flags
;
383 params
.set_parent
= (::IsWindow(parent_window
) ? true : false);
384 params
.parent_window
= parent_window
;
385 sender_
->Send(new AutomationMsg_TabReposition(handle_
, params
));
388 void TabProxy::SendContextMenuCommand(int selected_command
) {
389 sender_
->Send(new AutomationMsg_ForwardContextMenuCommandToChrome(
390 handle_
, selected_command
));
393 void TabProxy::OnHostMoved() {
394 sender_
->Send(new AutomationMsg_BrowserMove(handle_
));
396 #endif // defined(OS_WIN)
398 void TabProxy::SelectAll() {
399 sender_
->Send(new AutomationMsg_SelectAll(handle_
));
402 void TabProxy::Cut() {
403 sender_
->Send(new AutomationMsg_Cut(handle_
));
406 void TabProxy::Copy() {
407 sender_
->Send(new AutomationMsg_Copy(handle_
));
410 void TabProxy::Paste() {
411 sender_
->Send(new AutomationMsg_Paste(handle_
));
414 void TabProxy::ReloadAsync() {
415 sender_
->Send(new AutomationMsg_ReloadAsync(handle_
));
418 void TabProxy::StopAsync() {
419 sender_
->Send(new AutomationMsg_StopAsync(handle_
));
422 void TabProxy::SaveAsAsync() {
423 sender_
->Send(new AutomationMsg_SaveAsAsync(handle_
));
426 void TabProxy::JavaScriptStressTestControl(int cmd
, int param
) {
430 sender_
->Send(new AutomationMsg_JavaScriptStressTestControl(
431 handle_
, cmd
, param
));
434 void TabProxy::AddObserver(TabProxyDelegate
* observer
) {
435 base::AutoLock
lock(list_lock_
);
436 observers_list_
.AddObserver(observer
);
439 void TabProxy::RemoveObserver(TabProxyDelegate
* observer
) {
440 base::AutoLock
lock(list_lock_
);
441 observers_list_
.RemoveObserver(observer
);
444 // Called on Channel background thread, if TabMessages filter is installed.
445 bool TabProxy::OnMessageReceived(const IPC::Message
& message
) {
446 base::AutoLock
lock(list_lock_
);
447 FOR_EACH_OBSERVER(TabProxyDelegate
, observers_list_
,
448 OnMessageReceived(this, message
));
452 void TabProxy::OnChannelError() {
453 base::AutoLock
lock(list_lock_
);
454 FOR_EACH_OBSERVER(TabProxyDelegate
, observers_list_
, OnChannelError(this));
457 TabProxy::~TabProxy() {}
459 void TabProxy::FirstObjectAdded() {
463 void TabProxy::LastObjectRemoved() {