diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_provider_json.cc | 65 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_json.h | 32 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.cc | 25 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.h | 18 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 491 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 181 | ||||
-rw-r--r-- | chrome/common/automation_constants.h | 6 | ||||
-rw-r--r-- | chrome/test/automation/automation_json_requests.cc | 328 | ||||
-rw-r--r-- | chrome/test/automation/automation_json_requests.h | 157 | ||||
-rw-r--r-- | chrome/test/webdriver/automation.cc | 294 | ||||
-rw-r--r-- | chrome/test/webdriver/automation.h | 40 | ||||
-rw-r--r-- | chrome/test/webdriver/commands/mouse_commands.cc | 5 | ||||
-rw-r--r-- | chrome/test/webdriver/session.cc | 38 | ||||
-rw-r--r-- | chrome/test/webdriver/session.h | 7 | ||||
-rw-r--r-- | chrome/test/webdriver/webdriver_key_converter.cc | 1 | ||||
-rw-r--r-- | chrome/test/webdriver/webdriver_key_converter_unittest.cc | 2 |
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" |