summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider_json.cc65
-rw-r--r--chrome/browser/automation/automation_provider_json.h32
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc25
-rw-r--r--chrome/browser/automation/automation_provider_observers.h18
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc491
-rw-r--r--chrome/browser/automation/testing_automation_provider.h181
-rw-r--r--chrome/common/automation_constants.h6
-rw-r--r--chrome/test/automation/automation_json_requests.cc328
-rw-r--r--chrome/test/automation/automation_json_requests.h157
-rw-r--r--chrome/test/webdriver/automation.cc294
-rw-r--r--chrome/test/webdriver/automation.h40
-rw-r--r--chrome/test/webdriver/commands/mouse_commands.cc5
-rw-r--r--chrome/test/webdriver/session.cc38
-rw-r--r--chrome/test/webdriver/session.h7
-rw-r--r--chrome/test/webdriver/webdriver_key_converter.cc1
-rw-r--r--chrome/test/webdriver/webdriver_key_converter_unittest.cc2
16 files changed, 1334 insertions, 356 deletions
diff --git a/chrome/browser/automation/automation_provider_json.cc b/chrome/browser/automation/automation_provider_json.cc
index 16fd8d4..2c99580 100644
--- a/chrome/browser/automation/automation_provider_json.cc
+++ b/chrome/browser/automation/automation_provider_json.cc
@@ -6,8 +6,11 @@
#include "base/json/json_writer.h"
#include "base/json/string_escape.h"
+#include "base/values.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/automation/automation_provider.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/automation_messages.h"
namespace {
@@ -23,6 +26,21 @@ std::string JSONErrorString(const std::string& err) {
return prefix + no_quote_err + suffix;
}
+Browser* GetBrowserAt(int index) {
+ if (index < 0 || index >= static_cast<int>(BrowserList::size()))
+ return NULL;
+ return *(BrowserList::begin() + index);
+}
+
+TabContents* GetTabContentsAt(int browser_index, int tab_index) {
+ if (tab_index < 0)
+ return NULL;
+ Browser* browser = GetBrowserAt(browser_index);
+ if (!browser || tab_index >= browser->tab_count())
+ return NULL;
+ return browser->GetTabContentsAt(tab_index);
+}
+
} // namespace
AutomationJSONReply::AutomationJSONReply(AutomationProvider* provider,
@@ -54,3 +72,50 @@ void AutomationJSONReply::SendError(const std::string& error_message) {
provider_->Send(message_);
message_ = NULL;
}
+
+bool GetBrowserFromJSONArgs(
+ DictionaryValue* args,
+ Browser** browser,
+ std::string* error) {
+ int browser_index;
+ if (!args->GetInteger("windex", &browser_index)) {
+ *error = "'windex' missing or invalid";
+ return false;
+ }
+ *browser = GetBrowserAt(browser_index);
+ if (!*browser) {
+ *error = "Cannot locate browser from given index";
+ return false;
+ }
+ return true;
+}
+
+bool GetTabFromJSONArgs(
+ DictionaryValue* args,
+ TabContents** tab,
+ std::string* error) {
+ int browser_index, tab_index;
+ if (!args->GetInteger("windex", &browser_index)) {
+ *error = "'windex' missing or invalid";
+ return false;
+ }
+ if (!args->GetInteger("tab_index", &tab_index)) {
+ *error = "'tab_index' missing or invalid";
+ return false;
+ }
+ *tab = GetTabContentsAt(browser_index, tab_index);
+ if (!*tab) {
+ *error = "Cannot locate tab from given indices";
+ return false;
+ }
+ return true;
+}
+
+bool GetBrowserAndTabFromJSONArgs(
+ DictionaryValue* args,
+ Browser** browser,
+ TabContents** tab,
+ std::string* error) {
+ return GetBrowserFromJSONArgs(args, browser, error) &&
+ GetTabFromJSONArgs(args, tab, error);
+}
diff --git a/chrome/browser/automation/automation_provider_json.h b/chrome/browser/automation/automation_provider_json.h
index 26b8581..0e23f86 100644
--- a/chrome/browser/automation/automation_provider_json.h
+++ b/chrome/browser/automation/automation_provider_json.h
@@ -10,8 +10,13 @@
#include <string>
-class Value;
+#include "base/compiler_specific.h"
+
class AutomationProvider;
+class Browser;
+class DictionaryValue;
+class TabContents;
+class Value;
namespace IPC {
class Message;
@@ -40,4 +45,29 @@ class AutomationJSONReply {
IPC::Message* message_;
};
+// Gets the browser specified by the given dictionary |args|. |args| should
+// contain a key 'windex' which refers to the index of the browser. Returns
+// true on success and sets |browser|. Otherwise, |error| will be set.
+bool GetBrowserFromJSONArgs(DictionaryValue* args,
+ Browser** browser,
+ std::string* error) WARN_UNUSED_RESULT;
+
+// Gets the tab specified by the given dictionary |args|. |args| should
+// contain a key 'windex' which refers to the index of the parent browser,
+// and a key 'tab_index' which refers to the index of the tab in that browser.
+// Returns true on success and sets |tab|. Otherwise, |error| will be set.
+bool GetTabFromJSONArgs(DictionaryValue* args,
+ TabContents** tab,
+ std::string* error) WARN_UNUSED_RESULT;
+
+// Gets the browser and tab specified by the given dictionary |args|. |args|
+// should contain a key 'windex' which refers to the index of the browser and
+// a key 'tab_index' which refers to the index of the tab in that browser.
+// Returns true on success and sets |browser| and |tab|. Otherwise, |error|
+// will be set.
+bool GetBrowserAndTabFromJSONArgs(DictionaryValue* args,
+ Browser** browser,
+ TabContents** tab,
+ std::string* error) WARN_UNUSED_RESULT;
+
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_JSON_H_
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 9f62d48..9d244f5 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -2009,6 +2009,10 @@ void AllTabsStoppedLoadingObserver::Observe(
}
void AllTabsStoppedLoadingObserver::CheckIfStopped() {
+ if (!automation_) {
+ delete this;
+ return;
+ }
bool done_loading = true;
BrowserList::const_iterator iter = BrowserList::begin();
for (; iter != BrowserList::end(); ++iter) {
@@ -2108,3 +2112,24 @@ void WaitForProcessLauncherThreadToGoIdleObserver::RunOnUIThread() {
automation_->Send(reply_message_.release());
Release();
}
+
+ExecuteJavascriptObserver::ExecuteJavascriptObserver(
+ AutomationProvider* automation,
+ IPC::Message* reply_message)
+ : automation_(automation->AsWeakPtr()),
+ reply_message_(reply_message) {
+}
+
+ExecuteJavascriptObserver::~ExecuteJavascriptObserver() {
+}
+
+void ExecuteJavascriptObserver::OnDomOperationCompleted(
+ const std::string& json) {
+ if (automation_) {
+ DictionaryValue dict;
+ dict.SetString("result", json);
+ AutomationJSONReply(automation_, reply_message_.release())
+ .SendSuccess(&dict);
+ }
+ delete this;
+}
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 6e51d5b..89c1312 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -1152,4 +1152,22 @@ class WaitForProcessLauncherThreadToGoIdleObserver
DISALLOW_COPY_AND_ASSIGN(WaitForProcessLauncherThreadToGoIdleObserver);
};
+// Observes the result of execution of Javascript and sends a JSON reply.
+class ExecuteJavascriptObserver : public DomOperationObserver {
+ public:
+ ExecuteJavascriptObserver(AutomationProvider* automation,
+ IPC::Message* reply_message);
+ virtual ~ExecuteJavascriptObserver();
+
+ private:
+ // Overriden from DomOperationObserver.
+ virtual void OnDomOperationCompleted(const std::string& json);
+
+ base::WeakPtr<AutomationProvider> automation_;
+ scoped_ptr<IPC::Message> reply_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExecuteJavascriptObserver);
+};
+
+
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROVIDER_OBSERVERS_H_
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index aa76685..e36d655 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -152,25 +152,6 @@ class AutomationInterstitialPage : public InterstitialPage {
DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
};
-Browser* GetBrowserAt(int index) {
- if (index < 0)
- return NULL;
- BrowserList::const_iterator iter = BrowserList::begin();
- for (; (iter != BrowserList::end()) && (index > 0); ++iter, --index) {}
- if (iter == BrowserList::end())
- return NULL;
- return *iter;
-}
-
-TabContents* GetTabContentsAt(int browser_index, int tab_index) {
- if (tab_index < 0)
- return NULL;
- Browser* browser = GetBrowserAt(browser_index);
- if (!browser || tab_index >= browser->tab_count())
- return NULL;
- return browser->GetTabContentsAt(tab_index);
-}
-
} // namespace
TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
@@ -776,9 +757,8 @@ void TestingAutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
void TestingAutomationProvider::GetBrowserWindow(int index, int* handle) {
*handle = 0;
- Browser* browser = GetBrowserAt(index);
- if (browser)
- *handle = browser_tracker_->Add(browser);
+ if (index >= 0 && index < static_cast<int>(BrowserList::size()))
+ *handle = browser_tracker_->Add(*(BrowserList::begin() + index));
}
void TestingAutomationProvider::FindNormalBrowserWindow(int* handle) {
@@ -914,11 +894,16 @@ void TestingAutomationProvider::WindowSimulateKeyPress(
ui::EF_COMMAND_DOWN));
}
-void TestingAutomationProvider::WebkitMouseClick(Browser* browser,
- DictionaryValue* args,
+void TestingAutomationProvider::WebkitMouseClick(DictionaryValue* args,
IPC::Message* reply_message) {
- WebKit::WebMouseEvent mouse_event;
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+ WebKit::WebMouseEvent mouse_event;
if (!args->GetInteger("x", &mouse_event.x) ||
!args->GetInteger("y", &mouse_event.y)) {
AutomationJSONReply(this, reply_message)
@@ -926,18 +911,17 @@ void TestingAutomationProvider::WebkitMouseClick(Browser* browser,
return;
}
- int button_flags;
- if (!args->GetInteger("button_flags", &button_flags)) {
+ int button;
+ if (!args->GetInteger("button", &button)) {
AutomationJSONReply(this, reply_message)
.SendError("Mouse button missing or invalid");
return;
}
-
- if (button_flags == ui::EF_LEFT_BUTTON_DOWN) {
+ if (button == automation::kLeftButton) {
mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
- } else if (button_flags == ui::EF_RIGHT_BUTTON_DOWN) {
+ } else if (button == automation::kRightButton) {
mouse_event.button = WebKit::WebMouseEvent::ButtonRight;
- } else if (button_flags == ui::EF_MIDDLE_BUTTON_DOWN) {
+ } else if (button == automation::kMiddleButton) {
mouse_event.button = WebKit::WebMouseEvent::ButtonMiddle;
} else {
AutomationJSONReply(this, reply_message)
@@ -945,7 +929,6 @@ void TestingAutomationProvider::WebkitMouseClick(Browser* browser,
return;
}
- TabContents* tab_contents = browser->GetSelectedTabContents();
mouse_event.type = WebKit::WebInputEvent::MouseDown;
mouse_event.clickCount = 1;
@@ -956,11 +939,16 @@ void TestingAutomationProvider::WebkitMouseClick(Browser* browser,
tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
}
-void TestingAutomationProvider::WebkitMouseMove(Browser* browser,
- DictionaryValue* args,
- IPC::Message* reply_message) {
- WebKit::WebMouseEvent mouse_event;
+void TestingAutomationProvider::WebkitMouseMove(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+ WebKit::WebMouseEvent mouse_event;
if (!args->GetInteger("x", &mouse_event.x) ||
!args->GetInteger("y", &mouse_event.y)) {
AutomationJSONReply(this, reply_message)
@@ -968,18 +956,22 @@ void TestingAutomationProvider::WebkitMouseMove(Browser* browser,
return;
}
- TabContents* tab_contents = browser->GetSelectedTabContents();
mouse_event.type = WebKit::WebInputEvent::MouseMove;
new InputEventAckNotificationObserver(this, reply_message, mouse_event.type);
tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
}
-void TestingAutomationProvider::WebkitMouseDrag(Browser* browser,
- DictionaryValue* args,
+void TestingAutomationProvider::WebkitMouseDrag(DictionaryValue* args,
IPC::Message* reply_message) {
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+
WebKit::WebMouseEvent mouse_event;
int start_x, start_y, end_x, end_y;
-
if (!args->GetInteger("start_x", &start_x) ||
!args->GetInteger("start_y", &start_y) ||
!args->GetInteger("end_x", &end_x) ||
@@ -990,7 +982,6 @@ void TestingAutomationProvider::WebkitMouseDrag(Browser* browser,
}
mouse_event.type = WebKit::WebInputEvent::MouseMove;
- TabContents* tab_contents = browser->GetSelectedTabContents();
// Step 1- Move the mouse to the start position.
mouse_event.x = start_x;
mouse_event.y = start_y;
@@ -2119,6 +2110,40 @@ void TestingAutomationProvider::SendJSONRequest(int handle,
&TestingAutomationProvider::GetIndicesFromTab;
handler_map["NavigateToURL"] =
&TestingAutomationProvider::NavigateToURL;
+ handler_map["ExecuteJavascript"] =
+ &TestingAutomationProvider::ExecuteJavascriptJSON;
+ handler_map["GoForward"] =
+ &TestingAutomationProvider::GoForward;
+ handler_map["GoBack"] =
+ &TestingAutomationProvider::GoBack;
+ handler_map["Reload"] =
+ &TestingAutomationProvider::ReloadJSON;
+ handler_map["GetTabURL"] =
+ &TestingAutomationProvider::GetTabURLJSON;
+ handler_map["GetTabTitle"] =
+ &TestingAutomationProvider::GetTabTitleJSON;
+ handler_map["GetCookies"] =
+ &TestingAutomationProvider::GetCookiesJSON;
+ handler_map["DeleteCookie"] =
+ &TestingAutomationProvider::DeleteCookieJSON;
+ handler_map["SetCookie"] =
+ &TestingAutomationProvider::SetCookieJSON;
+ handler_map["GetTabIds"] =
+ &TestingAutomationProvider::GetTabIds;
+ handler_map["IsTabIdValid"] =
+ &TestingAutomationProvider::IsTabIdValid;
+ handler_map["CloseTab"] =
+ &TestingAutomationProvider::CloseTabJSON;
+ handler_map["WebkitMouseMove"] =
+ &TestingAutomationProvider::WebkitMouseMove;
+ handler_map["WebkitMouseClick"] =
+ &TestingAutomationProvider::WebkitMouseClick;
+ handler_map["WebkitMouseDrag"] =
+ &TestingAutomationProvider::WebkitMouseDrag;
+ handler_map["SendWebkitKeyEvent"] =
+ &TestingAutomationProvider::SendWebkitKeyEvent;
+ handler_map["ActivateTab"] =
+ &TestingAutomationProvider::ActivateTabJSON;
#if defined(OS_CHROMEOS)
handler_map["LoginAsGuest"] = &TestingAutomationProvider::LoginAsGuest;
handler_map["Login"] = &TestingAutomationProvider::Login;
@@ -2261,9 +2286,6 @@ void TestingAutomationProvider::SendJSONRequest(int handle,
browser_handler_map["KillRendererProcess"] =
&TestingAutomationProvider::KillRendererProcess;
- browser_handler_map["SendKeyEventToActiveTab"] =
- &TestingAutomationProvider::SendKeyEventToActiveTab;
-
browser_handler_map["GetNTPThumbnailMode"] =
&TestingAutomationProvider::GetNTPThumbnailMode;
browser_handler_map["SetNTPThumbnailMode"] =
@@ -2273,13 +2295,6 @@ void TestingAutomationProvider::SendJSONRequest(int handle,
browser_handler_map["SetNTPMenuMode"] =
&TestingAutomationProvider::SetNTPMenuMode;
- browser_handler_map["WebkitMouseMove"] =
- &TestingAutomationProvider::WebkitMouseMove;
- browser_handler_map["WebkitMouseClick"] =
- &TestingAutomationProvider::WebkitMouseClick;
- browser_handler_map["WebkitMouseDrag"] =
- &TestingAutomationProvider::WebkitMouseDrag;
-
if (handler_map.find(std::string(command)) != handler_map.end()) {
(this->*handler_map[command])(dict_value, reply_message);
} else if (browser_handler_map.find(std::string(command)) !=
@@ -4568,10 +4583,16 @@ void TestingAutomationProvider::KillRendererProcess(
base::CloseProcessHandle(process);
}
-void TestingAutomationProvider::SendKeyEventToActiveTab(
- Browser* browser,
+void TestingAutomationProvider::SendWebkitKeyEvent(
DictionaryValue* args,
IPC::Message* reply_message) {
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+
int type, modifiers;
bool is_system_key;
string16 unmodified_text, text;
@@ -4657,8 +4678,7 @@ void TestingAutomationProvider::SendKeyEventToActiveTab(
event.timeStampSeconds = base::Time::Now().ToDoubleT();
event.skip_in_browser = true;
new InputEventAckNotificationObserver(this, reply_message, event.type);
- browser->GetSelectedTabContents()->render_view_host()->
- ForwardKeyboardEvent(event);
+ tab_contents->render_view_host()->ForwardKeyboardEvent(event);
}
// Sample JSON input: { "command": "GetNTPThumbnailMode" }
@@ -4802,19 +4822,36 @@ void TestingAutomationProvider::GetIndicesFromTab(
DictionaryValue* args,
IPC::Message* reply_message) {
AutomationJSONReply reply(this, reply_message);
- int tab_handle = 0;
- if (!args->GetInteger("tab_handle", &tab_handle) ||
- !tab_tracker_->ContainsHandle(tab_handle)) {
- reply.SendError("'tab_handle' missing or invalid");
+ int id_or_handle = 0;
+ bool has_id = args->HasKey("tab_id");
+ bool has_handle = args->HasKey("tab_handle");
+ if (has_id && has_handle) {
+ reply.SendError(
+ "Both 'tab_id' and 'tab_handle' were specified. Only one is allowed");
+ return;
+ } else if (!has_id && !has_handle) {
+ reply.SendError("Either 'tab_id' or 'tab_handle' must be specified");
return;
}
- NavigationController* controller = tab_tracker_->GetResource(tab_handle);
+ if (has_id && !args->GetInteger("tab_id", &id_or_handle)) {
+ reply.SendError("'tab_id' is invalid");
+ return;
+ }
+ if (has_handle && (!args->GetInteger("tab_handle", &id_or_handle) ||
+ !tab_tracker_->ContainsHandle(id_or_handle))) {
+ reply.SendError("'tab_handle' is invalid");
+ return;
+ }
+ int id = id_or_handle;
+ if (has_handle)
+ id = tab_tracker_->GetResource(id_or_handle)->session_id().id();
BrowserList::const_iterator iter = BrowserList::begin();
int browser_index = 0;
for (; iter != BrowserList::end(); ++iter, ++browser_index) {
Browser* browser = *iter;
for (int tab_index = 0; tab_index < browser->tab_count(); ++tab_index) {
- if (browser->GetTabContentsAt(tab_index) == controller->tab_contents()) {
+ TabContents* tab = browser->GetTabContentsAt(tab_index);
+ if (tab->controller().session_id().id() == id) {
DictionaryValue dict;
dict.SetInteger("windex", browser_index);
dict.SetInteger("tab_index", tab_index);
@@ -4829,16 +4866,12 @@ void TestingAutomationProvider::GetIndicesFromTab(
void TestingAutomationProvider::NavigateToURL(
DictionaryValue* args,
IPC::Message* reply_message) {
- int browser_index = 0, tab_index = 0, navigation_count = 0;
- std::string url;
- if (!args->GetInteger("windex", &browser_index)) {
- AutomationJSONReply(this, reply_message)
- .SendError("'windex' missing or invalid");
- return;
- }
- if (!args->GetInteger("tab_index", &tab_index)) {
- AutomationJSONReply(this, reply_message)
- .SendError("'tab_index' missing or invalid");
+ int navigation_count;
+ std::string url, error;
+ Browser* browser;
+ TabContents* tab_contents;
+ if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
return;
}
if (!args->GetString("url", &url)) {
@@ -4851,13 +4884,6 @@ void TestingAutomationProvider::NavigateToURL(
.SendError("'navigation_count' missing or invalid");
return;
}
- Browser* browser = GetBrowserAt(browser_index);
- TabContents* tab_contents = GetTabContentsAt(browser_index, tab_index);
- if (!browser || !tab_contents) {
- AutomationJSONReply(this, reply_message)
- .SendError("Cannot locate tab or browser to navigate");
- return;
- }
new NavigationNotificationObserver(
&tab_contents->controller(), this, reply_message,
navigation_count, false, true);
@@ -4865,6 +4891,315 @@ void TestingAutomationProvider::NavigateToURL(
tab_contents, GURL(url), GURL(), CURRENT_TAB, PageTransition::TYPED);
}
+void TestingAutomationProvider::ExecuteJavascriptJSON(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ string16 frame_xpath, javascript;
+ std::string error;
+ TabContents* tab_contents;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+ if (!args->GetString("frame_xpath", &frame_xpath)) {
+ AutomationJSONReply(this, reply_message)
+ .SendError("'frame_xpath' missing or invalid");
+ return;
+ }
+ if (!args->GetString("javascript", &javascript)) {
+ AutomationJSONReply(this, reply_message)
+ .SendError("'javascript' missing or invalid");
+ return;
+ }
+
+ // Set the routing id of this message with the controller.
+ // This routing id needs to be remembered for the reverse
+ // communication while sending back the response of
+ // this javascript execution.
+ std::string set_automation_id;
+ base::SStringPrintf(&set_automation_id,
+ "window.domAutomationController.setAutomationId(%d);",
+ reply_message->routing_id());
+
+ new ExecuteJavascriptObserver(this, reply_message);
+ tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
+ frame_xpath, UTF8ToUTF16(set_automation_id));
+ tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
+ frame_xpath, javascript);
+}
+
+void TestingAutomationProvider::GoForward(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+ NavigationController& controller = tab_contents->controller();
+ if (!controller.CanGoForward()) {
+ DictionaryValue dict;
+ dict.SetBoolean("did_go_forward", false);
+ AutomationJSONReply(this, reply_message).SendSuccess(&dict);
+ return;
+ }
+ new NavigationNotificationObserver(&controller, this, reply_message,
+ 1, false, true);
+ controller.GoForward();
+}
+
+void TestingAutomationProvider::GoBack(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+ NavigationController& controller = tab_contents->controller();
+ if (!controller.CanGoBack()) {
+ DictionaryValue dict;
+ dict.SetBoolean("did_go_back", false);
+ AutomationJSONReply(this, reply_message).SendSuccess(&dict);
+ return;
+ }
+ new NavigationNotificationObserver(&controller, this, reply_message,
+ 1, false, true);
+ controller.GoBack();
+}
+
+void TestingAutomationProvider::ReloadJSON(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ AutomationJSONReply(this, reply_message).SendError(error);
+ return;
+ }
+ NavigationController& controller = tab_contents->controller();
+ new NavigationNotificationObserver(&controller, this, reply_message,
+ 1, false, true);
+ controller.Reload(false);
+}
+
+void TestingAutomationProvider::GetTabURLJSON(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ DictionaryValue dict;
+ dict.SetString("url", tab_contents->GetURL().possibly_invalid_spec());
+ reply.SendSuccess(&dict);
+}
+
+void TestingAutomationProvider::GetTabTitleJSON(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ DictionaryValue dict;
+ dict.SetString("title", tab_contents->GetTitle());
+ reply.SendSuccess(&dict);
+}
+
+void TestingAutomationProvider::GetCookiesJSON(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ Browser* browser;
+ std::string error;
+ if (!GetBrowserFromJSONArgs(args, &browser, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ std::string url;
+ if (!args->GetString("url", &url)) {
+ reply.SendError("'url' missing or invalid");
+ return;
+ }
+
+ // Since we are running on the UI thread don't call GetURLRequestContext().
+ scoped_refptr<URLRequestContextGetter> context_getter =
+ browser->profile()->GetRequestContext();
+
+ std::string cookies;
+ base::WaitableEvent event(true /* manual reset */,
+ false /* not initially signaled */);
+ Task* task = NewRunnableFunction(
+ &GetCookiesOnIOThread,
+ GURL(url), context_getter, &event, &cookies);
+ if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) {
+ reply.SendError("Couldn't post task to get the cookies");
+ return;
+ }
+ event.Wait();
+
+ DictionaryValue dict;
+ dict.SetString("cookies", cookies);
+ reply.SendSuccess(&dict);
+}
+
+void TestingAutomationProvider::DeleteCookieJSON(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ Browser* browser;
+ std::string error;
+ if (!GetBrowserFromJSONArgs(args, &browser, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ std::string url, name;
+ if (!args->GetString("url", &url)) {
+ reply.SendError("'url' missing or invalid");
+ return;
+ }
+ if (!args->GetString("name", &name)) {
+ reply.SendError("'name' missing or invalid");
+ return;
+ }
+
+ // Since we are running on the UI thread don't call GetURLRequestContext().
+ scoped_refptr<URLRequestContextGetter> context_getter =
+ browser->profile()->GetRequestContext();
+
+ base::WaitableEvent event(true /* manual reset */,
+ false /* not initially signaled */);
+ Task* task = NewRunnableFunction(
+ &DeleteCookieOnIOThread,
+ GURL(url), name, context_getter, &event);
+ if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) {
+ reply.SendError("Couldn't post task to delete the cookie");
+ return;
+ }
+ event.Wait();
+ reply.SendSuccess(NULL);
+}
+
+void TestingAutomationProvider::SetCookieJSON(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ Browser* browser;
+ std::string error;
+ if (!GetBrowserFromJSONArgs(args, &browser, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ std::string url, cookie;
+ if (!args->GetString("url", &url)) {
+ reply.SendError("'url' missing or invalid");
+ return;
+ }
+ if (!args->GetString("cookie", &cookie)) {
+ reply.SendError("'cookie' missing or invalid");
+ return;
+ }
+
+ // Since we are running on the UI thread don't call GetURLRequestContext().
+ scoped_refptr<URLRequestContextGetter> context_getter =
+ browser->profile()->GetRequestContext();
+
+ base::WaitableEvent event(true /* manual reset */,
+ false /* not initially signaled */);
+ bool success = false;
+ Task* task = NewRunnableFunction(
+ &SetCookieOnIOThread,
+ GURL(url), cookie, context_getter, &event, &success);
+ if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task)) {
+ reply.SendError("Couldn't post task to set the cookie");
+ return;
+ }
+ event.Wait();
+
+ if (!success) {
+ reply.SendError("Could not set the cookie");
+ return;
+ }
+ reply.SendSuccess(NULL);
+}
+
+void TestingAutomationProvider::GetTabIds(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ ListValue* id_list = new ListValue();
+ BrowserList::const_iterator iter = BrowserList::begin();
+ for (; iter != BrowserList::end(); ++iter) {
+ Browser* browser = *iter;
+ for (int i = 0; i < browser->tab_count(); ++i) {
+ int id = browser->GetTabContentsAt(i)->controller().session_id().id();
+ id_list->Append(Value::CreateIntegerValue(id));
+ }
+ }
+ DictionaryValue dict;
+ dict.Set("ids", id_list);
+ AutomationJSONReply(this, reply_message).SendSuccess(&dict);
+}
+
+void TestingAutomationProvider::IsTabIdValid(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ int id;
+ if (!args->GetInteger("id", &id)) {
+ reply.SendError("'id' missing or invalid");
+ return;
+ }
+ bool is_valid = false;
+ BrowserList::const_iterator iter = BrowserList::begin();
+ for (; iter != BrowserList::end(); ++iter) {
+ Browser* browser = *iter;
+ for (int i = 0; i < browser->tab_count(); ++i) {
+ TabContents* tab = browser->GetTabContentsAt(i);
+ if (tab->controller().session_id().id() == id) {
+ is_valid = true;
+ break;
+ }
+ }
+ }
+ DictionaryValue dict;
+ dict.SetBoolean("is_valid", is_valid);
+ reply.SendSuccess(&dict);
+}
+
+void TestingAutomationProvider::CloseTabJSON(
+ DictionaryValue* args, IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ Browser* browser;
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ browser->CloseTabContents(tab_contents);
+ reply.SendSuccess(NULL);
+}
+
+void TestingAutomationProvider::ActivateTabJSON(
+ DictionaryValue* args,
+ IPC::Message* reply_message) {
+ AutomationJSONReply reply(this, reply_message);
+ Browser* browser;
+ TabContents* tab_contents;
+ std::string error;
+ if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
+ reply.SendError(error);
+ return;
+ }
+ browser->SelectTabContentsAt(
+ browser->GetIndexOfController(&tab_contents->controller()), true);
+ reply.SendSuccess(NULL);
+}
+
void TestingAutomationProvider::WaitForTabCountToBecome(
int browser_handle,
int target_tab_count,
diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h
index 8233eb9..9794810 100644
--- a/chrome/browser/automation/testing_automation_provider.h
+++ b/chrome/browser/automation/testing_automation_provider.h
@@ -118,17 +118,6 @@ class TestingAutomationProvider : public AutomationProvider,
void WindowSimulateMouseMove(const IPC::Message& message,
int handle,
const gfx::Point& location);
- // The Webkit mouse functions below work on the currently selected
- // tab.
- void WebkitMouseClick(Browser* browser,
- DictionaryValue* args,
- IPC::Message* message);
- void WebkitMouseMove(Browser* browser,
- DictionaryValue* args,
- IPC::Message* message);
- void WebkitMouseDrag(Browser* browser,
- DictionaryValue* args,
- IPC::Message* message);
void WindowSimulateKeyPress(const IPC::Message& message,
int handle,
int key,
@@ -799,14 +788,19 @@ class TestingAutomationProvider : public AutomationProvider,
IPC::Message* reply_message);
// Gets the browser and tab index of the given tab. Uses the JSON interface.
+ // Either "tab_id" or "tab_handle" must be specified, but not both. "tab_id"
+ // refers to the ID from the |NavigationController|, while "tab_handle" is
+ // the handle number assigned by the automation system.
// Example:
- // input: { "tab_handle": 3 }
- // output: { "browser_index": 1, "tab_index": 5 }
+ // input: { "tab_id": 1, // optional
+ // "tab_handle": 3 // optional
+ // }
+ // output: { "windex": 1, "tab_index": 5 }
void GetIndicesFromTab(DictionaryValue* args, IPC::Message* reply_message);
// Navigates to the given URL. Uses the JSON interface.
// Example:
- // input: { "browser_index": 1,
+ // input: { "windex": 1,
// "tab_index": 3,
// "url": "http://www.google.com",
// "navigation_count": 1 // number of navigations to wait for
@@ -814,6 +808,165 @@ class TestingAutomationProvider : public AutomationProvider,
// output: { "result": AUTOMATION_MSG_NAVIGATION_SUCCESS }
void NavigateToURL(DictionaryValue* args, IPC::Message* reply_message);
+ // Executes javascript in the specified frame. Uses the JSON interface.
+ // Waits for a result from the |DOMAutomationController|. The javascript
+ // must send a string.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "frame_xpath": "//frames[1]",
+ // "javascript":
+ // "window.domAutomationController.send(window.name)",
+ // }
+ // output: { "result": "My Window Name" }
+ // This and some following methods have a suffix of JSON to distingush them
+ // from already existing methods which perform the same function, but use
+ // custom IPC messages instead of the JSON IPC message. These functions will
+ // eventually be replaced with the JSON ones and the JSON suffix will be
+ // dropped.
+ // TODO(kkania): Replace the non-JSON counterparts and drop the JSON suffix.
+ void ExecuteJavascriptJSON(
+ DictionaryValue* args, IPC::Message* reply_message);
+
+ // Goes forward in the specified tab. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1 }
+ // output: { "did_go_forward": true, // optional
+ // "result": AUTOMATION_MSG_NAVIGATION_SUCCESS // optional
+ // }
+ void GoForward(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Goes back in the specified tab. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1 }
+ // output: { "did_go_back": true, // optional
+ // "result": AUTOMATION_MSG_NAVIGATION_SUCCESS // optional
+ // }
+ void GoBack(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Reload the specified tab. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1 }
+ // output: { "result": AUTOMATION_MSG_NAVIGATION_SUCCESS // optional }
+ void ReloadJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Get the current url of the specified tab. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1 }
+ // output: { "url": "http://www.google.com" }
+ void GetTabURLJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Get the current url of the specified tab. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1 }
+ // output: { "title": "Google" }
+ void GetTabTitleJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Gets the cookies for the given URL. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1, "url": "http://www.google.com" }
+ // output: { "cookies": "PREF=12012" }
+ void GetCookiesJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Deletes the cookie with the given name for the URL. Uses the JSON
+ // interface.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "url": "http://www.google.com",
+ // "name": "my_cookie"
+ // }
+ // output: none
+ void DeleteCookieJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Sets a cookie for the given URL. Uses the JSON interface.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "url": "http://www.google.com",
+ // "cookie": "PREF=21321"
+ // }
+ // output: none
+ void SetCookieJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Gets the ID for every open tab. This ID is unique per session.
+ // Example:
+ // input: none
+ // output: { "ids": [4124, 213, 1] }
+ void GetTabIds(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Checks if the given tab ID refers to an open tab.
+ // Example:
+ // input: { "id": 41 }
+ // output: { "is_valid": false }
+ void IsTabIdValid(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Closes the specified tab.
+ // Example:
+ // input: { "windex": 1, "tab_index": 1 }
+ // output: none
+ void CloseTabJSON(DictionaryValue* args, IPC::Message* reply_message);
+
+ // Sends the WebKit events for a mouse click at a given coordinate.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "button": automation::kLeftButton,
+ // "x": 100,
+ // "y": 100
+ // }
+ // output: none
+ void WebkitMouseClick(DictionaryValue* args,
+ IPC::Message* message);
+
+ // Sends the WebKit event for a mouse move to a given coordinate.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "x": 100,
+ // "y": 100
+ // }
+ // output: none
+ void WebkitMouseMove(DictionaryValue* args,
+ IPC::Message* message);
+
+ // Sends the WebKit events for a mouse drag between two coordinates.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "start_x": 100,
+ // "start_y": 100,
+ // "end_x": 100,
+ // "end_y": 100
+ // }
+ // output: none
+ void WebkitMouseDrag(DictionaryValue* args,
+ IPC::Message* message);
+
+ // Sends the WebKit key event with the specified properties.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // "type": automation::kRawKeyDownType,
+ // "nativeKeyCode": ui::VKEY_X,
+ // "windowsKeyCode": ui::VKEY_X,
+ // "unmodifiedText": "x",
+ // "text": "X",
+ // "modifiers": automation::kShiftKeyMask,
+ // "isSystemKey": false
+ // }
+ // output: none
+ void SendWebkitKeyEvent(DictionaryValue* args,
+ IPC::Message* message);
+
+ // Activates the given tab.
+ // Example:
+ // input: { "windex": 1,
+ // "tab_index": 1,
+ // }
+ // output: none
+ void ActivateTabJSON(DictionaryValue* args, IPC::Message* message);
+
#if defined(OS_CHROMEOS)
void LoginAsGuest(DictionaryValue* args, IPC::Message* reply_message);
diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h
index c4aa683..cddd589 100644
--- a/chrome/common/automation_constants.h
+++ b/chrome/common/automation_constants.h
@@ -44,6 +44,12 @@ enum KeyModifierMasks {
kMetaKeyMask = 1 << 3,
};
+enum MouseButton {
+ kLeftButton = 0,
+ kMiddleButton,
+ kRightButton,
+};
+
} // namespace automation
// Used by AutomationProxy, declared here so that other headers don't need
diff --git a/chrome/test/automation/automation_json_requests.cc b/chrome/test/automation/automation_json_requests.cc
index c523b47..7ac9369 100644
--- a/chrome/test/automation/automation_json_requests.cc
+++ b/chrome/test/automation/automation_json_requests.cc
@@ -9,6 +9,7 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "chrome/common/automation_messages.h"
+#include "chrome/common/json_value_serializer.h"
#include "chrome/test/automation/automation_proxy.h"
namespace {
@@ -21,21 +22,39 @@ bool SendAutomationJSONRequest(AutomationMessageSender* sender,
bool success = false;
if (!SendAutomationJSONRequest(sender, request, &reply, &success))
return false;
- if (!success) {
+ scoped_ptr<Value> value(base::JSONReader::Read(reply, true));
+ if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) {
std::string command;
request_dict.GetString("command", &command);
- LOG(ERROR) << "JSON request failed: " << command;
+ LOG(ERROR) << "JSON request did not return dict: " << command << "\n";
return false;
}
- scoped_ptr<Value> value(base::JSONReader::Read(reply, true));
- if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY))
+ DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
+ if (!success) {
+ std::string command, error;
+ request_dict.GetString("command", &command);
+ dict->GetString("error", &error);
+ LOG(ERROR) << "JSON request failed: " << command << "\n"
+ << " with error: " << error;
return false;
- reply_dict->MergeDictionary(static_cast<DictionaryValue*>(value.get()));
+ }
+ reply_dict->MergeDictionary(dict);
return true;
}
} // namespace
+WebKeyEvent::WebKeyEvent(automation::KeyEventTypes type,
+ ui::KeyboardCode key_code,
+ const std::string& unmodified_text,
+ const std::string& modified_text,
+ int modifiers)
+ : type(type),
+ key_code(key_code),
+ unmodified_text(unmodified_text),
+ modified_text(modified_text),
+ modifiers(modifiers) {}
+
bool SendAutomationJSONRequest(AutomationMessageSender* sender,
const std::string& request,
std::string* reply,
@@ -44,14 +63,32 @@ bool SendAutomationJSONRequest(AutomationMessageSender* sender,
-1, request, reply, success));
}
-bool SendGetIndicesFromTabJSONRequest(
+bool SendGetIndicesFromTabIdJSONRequest(
+ AutomationMessageSender* sender,
+ int tab_id,
+ int* browser_index,
+ int* tab_index) {
+ DictionaryValue request_dict;
+ request_dict.SetString("command", "GetIndicesFromTab");
+ request_dict.SetInteger("tab_id", tab_id);
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict))
+ return false;
+ if (!reply_dict.GetInteger("windex", browser_index))
+ return false;
+ if (!reply_dict.GetInteger("tab_index", tab_index))
+ return false;
+ return true;
+}
+
+bool SendGetIndicesFromTabHandleJSONRequest(
AutomationMessageSender* sender,
- int handle,
+ int tab_handle,
int* browser_index,
int* tab_index) {
DictionaryValue request_dict;
request_dict.SetString("command", "GetIndicesFromTab");
- request_dict.SetInteger("tab_handle", handle);
+ request_dict.SetInteger("tab_handle", tab_handle);
DictionaryValue reply_dict;
if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict))
return false;
@@ -84,3 +121,278 @@ bool SendNavigateToURLJSONRequest(
*nav_response = static_cast<AutomationMsg_NavigationResponseValues>(response);
return true;
}
+
+bool SendExecuteJavascriptJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ const std::string& frame_xpath,
+ const std::string& javascript,
+ Value** result) {
+ DictionaryValue dict;
+ dict.SetString("command", "ExecuteJavascript");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ dict.SetString("frame_xpath", frame_xpath);
+ dict.SetString("javascript", javascript);
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict))
+ return false;
+
+ std::string json;
+ if (!reply_dict.GetString("result", &json)) {
+ LOG(ERROR) << "Executed javascript but received no 'result'";
+ return false;
+ }
+ // Wrap |json| in an array before deserializing because valid JSON has an
+ // array or an object as the root.
+ json.insert(0, "[");
+ json.append("]");
+
+ JSONStringValueSerializer deserializer(json);
+ Value* value = deserializer.Deserialize(NULL, NULL);
+ if (!value || !value->IsType(Value::TYPE_LIST)) {
+ LOG(ERROR) << "Unable to deserialize returned JSON";
+ return false;
+ }
+ scoped_ptr<ListValue> list(static_cast<ListValue*>(value));
+ return list->Remove(0, result);
+}
+
+bool SendGoForwardJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) {
+ DictionaryValue dict;
+ dict.SetString("command", "GoForward");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendGoBackJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) {
+ DictionaryValue dict;
+ dict.SetString("command", "GoBack");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendReloadJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) {
+ DictionaryValue dict;
+ dict.SetString("command", "Reload");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendGetTabURLJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ std::string* url) {
+ DictionaryValue dict;
+ dict.SetString("command", "GetTabURL");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict))
+ return false;
+ return reply_dict.GetString("url", url);
+}
+
+bool SendGetTabTitleJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ std::string* tab_title) {
+ DictionaryValue dict;
+ dict.SetString("command", "GetTabTitle");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict))
+ return false;
+ return reply_dict.GetString("title", tab_title);
+}
+
+bool SendGetCookiesJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ const std::string& url,
+ std::string* cookies) {
+ DictionaryValue dict;
+ dict.SetString("command", "GetCookies");
+ dict.SetInteger("windex", browser_index);
+ dict.SetString("url", url);
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict))
+ return false;
+ return reply_dict.GetString("cookies", cookies);
+}
+
+bool SendDeleteCookieJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ const std::string& url,
+ const std::string& cookie_name) {
+ DictionaryValue dict;
+ dict.SetString("command", "DeleteCookie");
+ dict.SetInteger("windex", browser_index);
+ dict.SetString("url", url);
+ dict.SetString("name", cookie_name);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendSetCookieJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ const std::string& url,
+ const std::string& cookie) {
+ DictionaryValue dict;
+ dict.SetString("command", "SetCookie");
+ dict.SetInteger("windex", browser_index);
+ dict.SetString("url", url);
+ dict.SetString("cookie", cookie);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendGetTabIdsJSONRequest(
+ AutomationMessageSender* sender, std::vector<int>* tab_ids) {
+ DictionaryValue dict;
+ dict.SetString("command", "GetTabIds");
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict))
+ return false;
+ ListValue* id_list;
+ if (!reply_dict.GetList("ids", &id_list)) {
+ LOG(ERROR) << "Returned 'ids' key is missing or invalid";
+ return false;
+ }
+ std::vector<int> temp_ids;
+ for (size_t i = 0; i < id_list->GetSize(); ++i) {
+ int id;
+ if (!id_list->GetInteger(i, &id)) {
+ LOG(ERROR) << "Returned 'ids' key contains non-integer values";
+ return false;
+ }
+ temp_ids.push_back(id);
+ }
+ *tab_ids = temp_ids;
+ return true;
+}
+
+bool SendIsTabIdValidJSONRequest(
+ AutomationMessageSender* sender, int tab_id, bool* is_valid) {
+ DictionaryValue dict;
+ dict.SetString("command", "IsTabIdValid");
+ dict.SetInteger("id", tab_id);
+ DictionaryValue reply_dict;
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict))
+ return false;
+ return reply_dict.GetBoolean("is_valid", is_valid);
+}
+
+bool SendCloseTabJSONRequest(
+ AutomationMessageSender* sender, int browser_index, int tab_index) {
+ DictionaryValue dict;
+ dict.SetString("command", "CloseTab");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendMouseMoveJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ int x,
+ int y) {
+ DictionaryValue dict;
+ dict.SetString("command", "WebkitMouseMove");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ dict.SetInteger("x", x);
+ dict.SetInteger("y", y);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendMouseClickJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ automation::MouseButton button,
+ int x,
+ int y) {
+ // TODO get rid of the evil flags.
+ DictionaryValue dict;
+ dict.SetString("command", "WebkitMouseClick");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ dict.SetInteger("button", button);
+ dict.SetInteger("x", x);
+ dict.SetInteger("y", y);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendMouseDragJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ int start_x,
+ int start_y,
+ int end_x,
+ int end_y) {
+ DictionaryValue dict;
+ dict.SetString("command", "WebkitMouseDrag");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ dict.SetInteger("start_x", start_x);
+ dict.SetInteger("start_y", start_y);
+ dict.SetInteger("end_x", end_x);
+ dict.SetInteger("end_y", end_y);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendWebKeyEventJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ const WebKeyEvent& key_event) {
+ DictionaryValue dict;
+ dict.SetString("command", "SendWebkitKeyEvent");
+ dict.SetInteger("windex", browser_index);
+ dict.SetInteger("tab_index", tab_index);
+ dict.SetInteger("type", key_event.type);
+ dict.SetInteger("nativeKeyCode", key_event.key_code);
+ dict.SetInteger("windowsKeyCode", key_event.key_code);
+ dict.SetString("unmodifiedText", key_event.unmodified_text);
+ dict.SetString("text", key_event.modified_text);
+ dict.SetInteger("modifiers", key_event.modifiers);
+ dict.SetBoolean("isSystemKey", false);
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
+
+bool SendWaitForAllTabsToStopLoadingJSONRequest(
+ AutomationMessageSender* sender) {
+ DictionaryValue dict;
+ dict.SetString("command", "WaitForAllTabsToStopLoading");
+ DictionaryValue reply_dict;
+ return SendAutomationJSONRequest(sender, dict, &reply_dict);
+}
diff --git a/chrome/test/automation/automation_json_requests.h b/chrome/test/automation/automation_json_requests.h
index 667c6af..99f9c08 100644
--- a/chrome/test/automation/automation_json_requests.h
+++ b/chrome/test/automation/automation_json_requests.h
@@ -7,12 +7,29 @@
#pragma once
#include <string>
+#include <vector>
#include "base/compiler_specific.h"
#include "chrome/common/automation_constants.h"
+#include "ui/base/keycodes/keyboard_codes.h"
class AutomationMessageSender;
class GURL;
+class Value;
+
+struct WebKeyEvent {
+ WebKeyEvent(automation::KeyEventTypes type,
+ ui::KeyboardCode key_code,
+ const std::string& unmodified_text,
+ const std::string& modified_text,
+ int modifiers);
+
+ automation::KeyEventTypes type;
+ ui::KeyboardCode key_code;
+ std::string unmodified_text;
+ std::string modified_text;
+ int modifiers;
+};
// Sends a JSON request to the chrome automation provider. Returns true
// if the JSON request was successfully sent and the reply was received.
@@ -23,11 +40,19 @@ bool SendAutomationJSONRequest(AutomationMessageSender* sender,
std::string* reply,
bool* success) WARN_UNUSED_RESULT;
+// Requests the current browser and tab indices for the given tab ID.
+// Returns true on success.
+bool SendGetIndicesFromTabIdJSONRequest(
+ AutomationMessageSender* sender,
+ int tab_id,
+ int* browser_index,
+ int* tab_index) WARN_UNUSED_RESULT;
+
// Requests the current browser and tab indices for the given |TabProxy|
// handle. Returns true on success.
-bool SendGetIndicesFromTabJSONRequest(
+bool SendGetIndicesFromTabHandleJSONRequest(
AutomationMessageSender* sender,
- int handle,
+ int tab_proxy_handle,
int* browser_index,
int* tab_index) WARN_UNUSED_RESULT;
@@ -41,4 +66,132 @@ bool SendNavigateToURLJSONRequest(
int navigation_count,
AutomationMsg_NavigationResponseValues* nav_response) WARN_UNUSED_RESULT;
+// Requests the given javascript to be executed in the frame specified by the
+// given xpath. Returns true on success. If true, |result| will be set to the
+// result of the execution and ownership will be given to the caller.
+bool SendExecuteJavascriptJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ const std::string& frame_xpath,
+ const std::string& javascript,
+ Value** result) WARN_UNUSED_RESULT;
+
+// Requests the specified tab to go forward. Waits for the load to complete.
+// Returns true on success.
+bool SendGoForwardJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) WARN_UNUSED_RESULT;
+
+// Requests the specified tab to go back. Waits for the load to complete.
+// Returns true on success.
+bool SendGoBackJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) WARN_UNUSED_RESULT;
+
+// Requests the specified tab to reload. Waits for the load to complete.
+// Returns true on success.
+bool SendReloadJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) WARN_UNUSED_RESULT;
+
+// Requests the url of the specified tab. Returns true on success.
+bool SendGetTabURLJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ std::string* url) WARN_UNUSED_RESULT;
+
+// Requests the title of the specified tab. Returns true on success.
+bool SendGetTabTitleJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ std::string* tab_title) WARN_UNUSED_RESULT;
+
+// Requests all the cookies for the given URL. Returns true on success.
+bool SendGetCookiesJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ const std::string& url,
+ std::string* cookies) WARN_UNUSED_RESULT;
+
+// Requests deletion of the cookie with the given name and URL. Returns true
+// on success.
+bool SendDeleteCookieJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ const std::string& url,
+ const std::string& cookie_name) WARN_UNUSED_RESULT;
+
+// Requests setting the given cookie for the given URL. Returns true on
+// success.
+bool SendSetCookieJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ const std::string& url,
+ const std::string& cookie) WARN_UNUSED_RESULT;
+
+// Requests the IDs for all open tabs. Returns true on success.
+bool SendGetTabIdsJSONRequest(
+ AutomationMessageSender* sender,
+ std::vector<int>* tab_ids) WARN_UNUSED_RESULT;
+
+// Requests whether the given tab ID is valid. Returns true on success.
+bool SendIsTabIdValidJSONRequest(
+ AutomationMessageSender* sender,
+ int tab_id,
+ bool* is_valid) WARN_UNUSED_RESULT;
+
+// Requests to close the given tab. Returns true on success.
+bool SendCloseTabJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index) WARN_UNUSED_RESULT;
+
+// Requests to send the WebKit event for a mouse move to the given
+// coordinate in the specified tab. Returns true on success.
+bool SendMouseMoveJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ int x,
+ int y) WARN_UNUSED_RESULT;
+
+// Requests to send the WebKit events for a mouse click at the given
+// coordinate in the specified tab. Returns true on success.
+bool SendMouseClickJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ automation::MouseButton button,
+ int x,
+ int y) WARN_UNUSED_RESULT;
+
+// Requests to send the WebKit events for a mouse drag from the start to end
+// coordinates given in the specified tab. Returns true on success.
+bool SendMouseDragJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ int start_x,
+ int start_y,
+ int end_x,
+ int end_y) WARN_UNUSED_RESULT;
+
+// Requests to send the WebKit event for the given |WebKeyEvent| in a
+// specified tab. Returns true on success.
+bool SendWebKeyEventJSONRequest(
+ AutomationMessageSender* sender,
+ int browser_index,
+ int tab_index,
+ const WebKeyEvent& key_event) WARN_UNUSED_RESULT;
+
+// Requests to wait for all tabs to stop loading. Returns true on success.
+bool SendWaitForAllTabsToStopLoadingJSONRequest(
+ AutomationMessageSender* sender) WARN_UNUSED_RESULT;
+
#endif // CHROME_TEST_AUTOMATION_AUTOMATION_JSON_REQUESTS_H_
diff --git a/chrome/test/webdriver/automation.cc b/chrome/test/webdriver/automation.cc
index 6f56f93..74046b9 100644
--- a/chrome/test/webdriver/automation.cc
+++ b/chrome/test/webdriver/automation.cc
@@ -24,9 +24,7 @@
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/automation/automation_proxy.h"
-#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/proxy_launcher.h"
-#include "chrome/test/automation/tab_proxy.h"
#include "googleurl/src/gurl.h"
#include "ui/gfx/point.h"
@@ -117,17 +115,6 @@ bool GetDefaultChromeExeDir(FilePath* browser_directory) {
namespace webdriver {
-WebKeyEvent::WebKeyEvent(automation::KeyEventTypes type,
- ui::KeyboardCode key_code,
- const std::string& unmodified_text,
- const std::string& modified_text,
- int modifiers)
- : type(type),
- key_code(key_code),
- unmodified_text(unmodified_text),
- modified_text(modified_text),
- modifiers(modifiers) {}
-
Automation::Automation() {}
Automation::~Automation() {}
@@ -173,92 +160,74 @@ void Automation::ExecuteScript(int tab_id,
const std::string& script,
std::string* result,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- std::wstring wide_xpath = UTF8ToWide(frame_xpath);
- std::wstring wide_script = UTF8ToWide(script);
- std::wstring wide_result;
- *success = tab->ExecuteAndExtractString(
- wide_xpath, wide_script, &wide_result);
- if (*success)
- *result = WideToUTF8(wide_result);
+
+ Value* unscoped_value;
+ if (!SendExecuteJavascriptJSONRequest(
+ automation(), windex, tab_index, frame_xpath, script, &unscoped_value)) {
+ *success = false;
+ return;
+ }
+ scoped_ptr<Value> value(unscoped_value);
+ *success = value->GetAsString(result);
}
void Automation::MouseMove(int tab_id,
const gfx::Point& p,
bool* success) {
- std::string reply;
- DictionaryValue dict;
-
- dict.SetString("command", "WebkitMouseMove");
- dict.SetInteger("x", p.x());
- dict.SetInteger("y", p.y());
-
- *success = SendJSONRequest(tab_id, dict, &reply);
- if (!*success) {
- LOG(ERROR) << "Could not send mouse event. Reply: " << reply;
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ *success = false;
+ return;
}
+
+ *success = SendMouseMoveJSONRequest(
+ automation(), windex, tab_index, p.x(), p.y());
}
void Automation::MouseClick(int tab_id,
const gfx::Point& p,
- int flag,
+ automation::MouseButton button,
bool* success) {
- std::string reply;
- DictionaryValue dict;
-
- dict.SetString("command", "WebkitMouseClick");
- dict.SetInteger("button_flags", flag);
- dict.SetInteger("x", p.x());
- dict.SetInteger("y", p.y());
-
- *success = SendJSONRequest(tab_id, dict, &reply);
- if (!*success) {
- LOG(ERROR) << "Could not send mouse event. Reply: " << reply;
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ *success = false;
+ return;
}
+
+ *success = SendMouseClickJSONRequest(
+ automation(), windex, tab_index, button, p.x(), p.y());
}
void Automation::MouseDrag(int tab_id,
const gfx::Point& start,
const gfx::Point& end,
bool* success) {
- std::string reply;
- DictionaryValue dict;
-
- dict.SetString("command", "WebkitMouseDrag");
- dict.SetInteger("start_x", start.x());
- dict.SetInteger("start_y", start.y());
- dict.SetInteger("end_x", end.x());
- dict.SetInteger("end_y", end.y());
-
- *success = SendJSONRequest(tab_id, dict, &reply);
- if (!*success) {
- LOG(ERROR) << "Could not send mouse event. Reply: " << reply;
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ *success = false;
+ return;
}
+
+ *success = SendMouseDragJSONRequest(
+ automation(), windex, tab_index, start.x(), start.y(), end.x(), end.y());
}
void Automation::SendWebKeyEvent(int tab_id,
const WebKeyEvent& key_event,
bool* success) {
- std::string reply;
- DictionaryValue dict;
-
- dict.SetString("command", "SendKeyEventToActiveTab");
- dict.SetInteger("type", key_event.type);
- dict.SetInteger("nativeKeyCode", key_event.key_code);
- dict.SetInteger("windowsKeyCode", key_event.key_code);
- dict.SetString("unmodifiedText", key_event.unmodified_text);
- dict.SetString("text", key_event.modified_text);
- dict.SetInteger("modifiers", key_event.modifiers);
- dict.SetBoolean("isSystemKey", false);
-
- *success = SendJSONRequest(tab_id, dict, &reply);
- if (!*success) {
- LOG(ERROR) << "Could not send web key event. Reply: " << reply;
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ *success = false;
+ return;
}
+
+ *success = SendWebKeyEventJSONRequest(
+ automation(), windex, tab_index, key_event);
}
void Automation::NavigateToURL(int tab_id,
@@ -280,163 +249,134 @@ void Automation::NavigateToURL(int tab_id,
}
void Automation::GoForward(int tab_id, bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->GoForward();
+
+ *success = SendGoForwardJSONRequest(automation(), windex, tab_index);
}
void Automation::GoBack(int tab_id, bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->GoBack();
+
+ *success = SendGoBackJSONRequest(automation(), windex, tab_index);
}
void Automation::Reload(int tab_id, bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->Reload();
+
+ *success = SendReloadJSONRequest(automation(), windex, tab_index);
}
void Automation::GetURL(int tab_id,
std::string* url,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- GURL gurl;
- *success = tab->GetCurrentURL(&gurl);
- if (*success)
- *url = gurl.possibly_invalid_spec();
+
+ *success = SendGetTabURLJSONRequest(automation(), windex, tab_index, url);
}
void Automation::GetGURL(int tab_id,
GURL* gurl,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
- *success = false;
- return;
- }
- *success = tab->GetCurrentURL(gurl);
+ std::string url;
+ GetURL(tab_id, &url, success);
+ if (*success)
+ *gurl = GURL(url);
}
void Automation::GetTabTitle(int tab_id,
std::string* tab_title,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- std::wstring wide_title;
- *success = tab->GetTabTitle(&wide_title);
- if (*success)
- *tab_title = WideToUTF8(wide_title);
+
+ *success = SendGetTabTitleJSONRequest(
+ automation(), windex, tab_index, tab_title);
}
void Automation::GetCookies(int tab_id,
const GURL& gurl,
std::string* cookies,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->GetCookies(gurl, cookies);
-}
-void Automation::GetCookieByName(int tab_id,
- const GURL& gurl,
- const std::string& cookie_name,
- std::string* cookie,
- bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
- *success = false;
- return;
- }
- *success = tab->GetCookieByName(gurl, cookie_name, cookie);
+ *success = SendGetCookiesJSONRequest(
+ automation(), windex, gurl.possibly_invalid_spec(), cookies);
}
void Automation::DeleteCookie(int tab_id,
const GURL& gurl,
const std::string& cookie_name,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->DeleteCookie(gurl, cookie_name);
+
+ *success = SendDeleteCookieJSONRequest(
+ automation(),
+ windex,
+ gurl.possibly_invalid_spec(),
+ cookie_name);
}
void Automation::SetCookie(int tab_id,
const GURL& gurl,
const std::string& cookie,
bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->SetCookie(gurl, cookie);
+
+ *success = SendSetCookieJSONRequest(
+ automation(),
+ windex,
+ gurl.possibly_invalid_spec(),
+ cookie);
}
void Automation::GetTabIds(std::vector<int>* tab_ids,
bool* success) {
- *success = false;
- int browser_count = 0;
- if (!automation()->GetBrowserWindowCount(&browser_count)) {
- LOG(ERROR) << "Failed to get browser window count";
- return;
- }
- TabIdMap tab_id_map;
- for (int browser_index = 0; browser_index < browser_count; ++browser_index) {
- scoped_refptr<BrowserProxy> browser =
- automation()->GetBrowserWindow(browser_index);
- if (!browser.get())
- continue;
- int tab_count = 0;
- if (!browser->GetTabCount(&tab_count))
- continue;
-
- for (int tab_index = 0; tab_index < tab_count; ++tab_index) {
- scoped_refptr<TabProxy> tab = browser->GetTab(tab_index);
- if (!tab.get())
- continue;
- tab_ids->push_back(tab->handle());
- tab_id_map.insert(std::make_pair(tab->handle(), tab));
- }
- }
-
- tab_id_map_ = tab_id_map;
- *success = true;
+ *success = SendGetTabIdsJSONRequest(automation(), tab_ids);
}
-void Automation::DoesTabExist(int tab_id, bool* does_exist) {
- TabProxy* tab = GetTabById(tab_id);
- *does_exist = tab && tab->is_valid();
+void Automation::DoesTabExist(int tab_id, bool* does_exist, bool* success) {
+ *success = SendIsTabIdValidJSONRequest(automation(), tab_id, does_exist);
}
void Automation::CloseTab(int tab_id, bool* success) {
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
+ int windex = 0, tab_index = 0;
+ if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
*success = false;
return;
}
- *success = tab->Close(true);
+
+ *success = SendCloseTabJSONRequest(automation(), windex, tab_index);
}
void Automation::GetVersion(std::string* version) {
@@ -444,61 +384,17 @@ void Automation::GetVersion(std::string* version) {
}
void Automation::WaitForAllTabsToStopLoading(bool* success) {
- DictionaryValue dict;
- dict.SetString("command", "WaitForAllTabsToStopLoading");
- std::string request, reply;
- base::JSONWriter::Write(&dict, false, &request);
- *success = automation()->SendJSONRequest(request, &reply);
-}
-
-TabProxy* Automation::GetTabById(int tab_id) {
- TabIdMap::const_iterator iter = tab_id_map_.find(tab_id);
- if (iter != tab_id_map_.end()) {
- return iter->second.get();
- }
- return NULL;
+ *success = SendWaitForAllTabsToStopLoadingJSONRequest(automation());
}
AutomationProxy* Automation::automation() const {
return launcher_->automation();
}
-bool Automation::SendJSONRequest(int tab_id,
- const DictionaryValue& dict,
- std::string* reply) {
- std::string request;
-
- base::JSONWriter::Write(&dict, false, &request);
- TabProxy* tab = GetTabById(tab_id);
- if (!tab) {
- LOG(ERROR) << "No such tab";
- return false;
- }
-
- int tab_index = 0;
- if (!tab->GetTabIndex(&tab_index)) {
- LOG(ERROR) << "Could not get tab index";
- return false;
- }
-
- scoped_refptr<BrowserProxy> browser = tab->GetParentBrowser();
- if (!browser.get()) {
- LOG(ERROR) << "Could not get parent browser of tab";
- return false;
- }
-
- if (!browser->ActivateTab(tab_index)) {
- LOG(ERROR) << "Could not activate tab";
- return false;
- }
-
- return browser->SendJSONRequest(request, reply);
-}
-
bool Automation::GetIndicesForTab(
int tab_id, int* browser_index, int* tab_index) {
- if (!SendGetIndicesFromTabJSONRequest(automation(), tab_id,
- browser_index, tab_index)) {
+ if (!SendGetIndicesFromTabIdJSONRequest(automation(), tab_id,
+ browser_index, tab_index)) {
LOG(ERROR) << "Could not get browser and tab indices for WebDriver tab id";
return false;
}
diff --git a/chrome/test/webdriver/automation.h b/chrome/test/webdriver/automation.h
index b773f4c..62c9d21 100644
--- a/chrome/test/webdriver/automation.h
+++ b/chrome/test/webdriver/automation.h
@@ -20,7 +20,7 @@ class DictionaryValue;
class FilePath;
class GURL;
class ProxyLauncher;
-class TabProxy;
+struct WebKeyEvent;
namespace gfx {
class Point;
@@ -28,20 +28,6 @@ class Point;
namespace webdriver {
-struct WebKeyEvent {
- WebKeyEvent(automation::KeyEventTypes type,
- ui::KeyboardCode key_code,
- const std::string& unmodified_text,
- const std::string& modified_text,
- int modifiers);
-
- automation::KeyEventTypes type;
- ui::KeyboardCode key_code;
- std::string unmodified_text;
- std::string modified_text;
- int modifiers;
-};
-
// Creates and controls the Chrome instance.
// This class should be created and accessed on a single thread.
// Note: All member functions are void because they are invoked
@@ -80,11 +66,6 @@ class Automation {
void GetTabTitle(int tab_id, std::string* tab_title, bool* success);
void GetCookies(
int tab_id, const GURL& gurl, std::string* cookies, bool* success);
- void GetCookieByName(int tab_id,
- const GURL& gurl,
- const std::string& cookie_name,
- std::string* cookie,
- bool* success);
void DeleteCookie(int tab_id,
const GURL& gurl,
const std::string& cookie_name,
@@ -92,7 +73,10 @@ class Automation {
void SetCookie(
int tab_id, const GURL& gurl, const std::string& cookie, bool* success);
void MouseMove(int tab_id, const gfx::Point& p, bool* success);
- void MouseClick(int tab_id, const gfx::Point& p, int flag, bool* success);
+ void MouseClick(int tab_id,
+ const gfx::Point& p,
+ automation::MouseButton button,
+ bool* success);
void MouseDrag(int tab_id,
const gfx::Point& start,
const gfx::Point& end,
@@ -103,7 +87,7 @@ class Automation {
void GetTabIds(std::vector<int>* tab_ids, bool* success);
// Check if the given tab exists currently.
- void DoesTabExist(int tab_id, bool* does_exist);
+ void DoesTabExist(int tab_id, bool* does_exist, bool* success);
void CloseTab(int tab_id, bool* success);
@@ -114,20 +98,10 @@ class Automation {
void WaitForAllTabsToStopLoading(bool* success);
private:
- typedef std::map<int, scoped_refptr<TabProxy> > TabIdMap;
-
- TabProxy* GetTabById(int tab_id);
AutomationProxy* automation() const;
+ bool GetIndicesForTab(int tab_id, int* browser_index, int* tab_index);
scoped_ptr<ProxyLauncher> launcher_;
- // Map from tab ID to |TabProxy|. The tab ID is simply the |AutomationHandle|
- // for the proxy.
- TabIdMap tab_id_map_;
-
- bool SendJSONRequest(
- int tab_id, const DictionaryValue& dict, std::string* reply);
-
- bool GetIndicesForTab(int tab_id, int* browser_index, int* tab_index);
DISALLOW_COPY_AND_ASSIGN(Automation);
};
diff --git a/chrome/test/webdriver/commands/mouse_commands.cc b/chrome/test/webdriver/commands/mouse_commands.cc
index b70c574..626dbfe 100644
--- a/chrome/test/webdriver/commands/mouse_commands.cc
+++ b/chrome/test/webdriver/commands/mouse_commands.cc
@@ -5,11 +5,11 @@
#include "chrome/test/webdriver/commands/mouse_commands.h"
#include "base/values.h"
+#include "chrome/common/automation_constants.h"
#include "chrome/test/webdriver/commands/response.h"
#include "chrome/test/webdriver/error_codes.h"
#include "chrome/test/webdriver/session.h"
#include "chrome/test/webdriver/web_element_id.h"
-#include "ui/base/events.h"
#include "ui/gfx/point.h"
namespace webdriver {
@@ -43,7 +43,7 @@ void MouseCommand::ExecutePost(Response* response) {
switch (cmd_) {
case kClick:
VLOG(1) << "Mouse click at: (" << x << ", " << y << ")" << std::endl;
- session_->MouseClick(gfx::Point(x, y), ui::EF_LEFT_BUTTON_DOWN);
+ session_->MouseClick(gfx::Point(x, y), automation::kLeftButton);
break;
case kHover:
@@ -108,4 +108,3 @@ HoverCommand::HoverCommand(const std::vector<std::string>& path_segments,
HoverCommand::~HoverCommand() {}
} // namespace webdriver
-
diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc
index 400c7eb..4402797 100644
--- a/chrome/test/webdriver/session.cc
+++ b/chrome/test/webdriver/session.cc
@@ -30,6 +30,7 @@
#include "chrome/app/chrome_command_ids.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/test_launcher_utils.h"
#include "chrome/test/webdriver/session_manager.h"
#include "chrome/test/webdriver/utility_functions.h"
@@ -259,14 +260,15 @@ bool Session::GetTabTitle(std::string* tab_title) {
return success;
}
-void Session::MouseClick(const gfx::Point& click, int flags) {
+void Session::MouseClick(const gfx::Point& click,
+ automation::MouseButton button) {
bool success = false;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseClick,
current_window_id_,
click,
- flags,
+ button,
&success));
}
@@ -309,16 +311,20 @@ bool Session::GetCookies(const GURL& url, std::string* cookies) {
bool Session::GetCookieByName(const GURL& url,
const std::string& cookie_name,
std::string* cookie) {
- bool success = false;
- RunSessionTask(NewRunnableMethod(
- automation_.get(),
- &Automation::GetCookieByName,
- current_window_id_,
- url,
- cookie_name,
- cookie,
- &success));
- return success;
+ std::string cookies;
+ if (!GetCookies(url, &cookies))
+ return false;
+
+ std::string namestr = cookie_name + "=";
+ std::string::size_type idx = cookies.find(namestr);
+ if (idx != std::string::npos) {
+ cookies.erase(0, idx + namestr.length());
+ *cookie = cookies.substr(0, cookies.find(";"));
+ } else {
+ cookie->clear();
+ }
+
+ return true;
}
bool Session::DeleteCookie(const GURL& url, const std::string& cookie_name) {
@@ -359,12 +365,18 @@ ErrorCode Session::SwitchToWindow(const std::string& name) {
int switch_to_id = 0;
int name_no = 0;
if (base::StringToInt(name, &name_no)) {
+ bool success = false;
bool does_exist = false;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::DoesTabExist,
name_no,
- &does_exist));
+ &does_exist,
+ &success));
+ if (!success) {
+ LOG(ERROR) << "Unable to determine if window exists";
+ return kUnknownError;
+ }
if (does_exist)
switch_to_id = name_no;
}
diff --git a/chrome/test/webdriver/session.h b/chrome/test/webdriver/session.h
index 222823c..8198f28 100644
--- a/chrome/test/webdriver/session.h
+++ b/chrome/test/webdriver/session.h
@@ -12,6 +12,7 @@
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "base/threading/thread.h"
+#include "chrome/common/automation_constants.h"
#include "chrome/test/webdriver/automation.h"
#include "chrome/test/webdriver/error_codes.h"
@@ -74,10 +75,8 @@ class Session {
// ownership of |element|.
ErrorCode SendKeys(const WebElementId& element, const string16& keys);
- // Click events with the mouse should use the values found in:
- // views/events/event.h. In the Webdriver JSON spec the MouseMove
- // function directly maps to the hover command.
- void MouseClick(const gfx::Point& click, int flags);
+ // Clicks the mouse at the given location using the given button.
+ void MouseClick(const gfx::Point& click, automation::MouseButton button);
bool MouseMove(const gfx::Point& location);
bool MouseDrag(const gfx::Point& start, const gfx::Point& end);
diff --git a/chrome/test/webdriver/webdriver_key_converter.cc b/chrome/test/webdriver/webdriver_key_converter.cc
index 70ca6d8..f8f3db6 100644
--- a/chrome/test/webdriver/webdriver_key_converter.cc
+++ b/chrome/test/webdriver/webdriver_key_converter.cc
@@ -6,6 +6,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/common/automation_constants.h"
+#include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/webdriver/keycode_text_conversion.h"
namespace {
diff --git a/chrome/test/webdriver/webdriver_key_converter_unittest.cc b/chrome/test/webdriver/webdriver_key_converter_unittest.cc
index 9d91b92..cc9c473 100644
--- a/chrome/test/webdriver/webdriver_key_converter_unittest.cc
+++ b/chrome/test/webdriver/webdriver_key_converter_unittest.cc
@@ -7,7 +7,7 @@
#include "base/string16.h"
#include "base/utf_string_conversions.h"
-#include "chrome/test/webdriver/automation.h"
+#include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/webdriver/webdriver_key_converter.h"
#include "testing/gtest/include/gtest/gtest.h"