summaryrefslogtreecommitdiffstats
path: root/chrome/test/webdriver
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/test/webdriver')
-rw-r--r--chrome/test/webdriver/automation.cc337
-rw-r--r--chrome/test/webdriver/automation.h60
-rw-r--r--chrome/test/webdriver/commands/alert_commands.cc27
-rw-r--r--chrome/test/webdriver/commands/cookie_commands.cc123
-rw-r--r--chrome/test/webdriver/commands/create_session.cc41
-rw-r--r--chrome/test/webdriver/commands/create_session.h4
-rw-r--r--chrome/test/webdriver/commands/execute_async_script_command.cc18
-rw-r--r--chrome/test/webdriver/commands/execute_command.cc30
-rw-r--r--chrome/test/webdriver/commands/execute_command.h5
-rw-r--r--chrome/test/webdriver/commands/find_element_commands.cc34
-rw-r--r--chrome/test/webdriver/commands/find_element_commands.h2
-rw-r--r--chrome/test/webdriver/commands/mouse_commands.cc169
-rw-r--r--chrome/test/webdriver/commands/mouse_commands.h14
-rw-r--r--chrome/test/webdriver/commands/navigate_commands.cc43
-rw-r--r--chrome/test/webdriver/commands/navigate_commands.h9
-rw-r--r--chrome/test/webdriver/commands/response.cc46
-rw-r--r--chrome/test/webdriver/commands/response.h34
-rw-r--r--chrome/test/webdriver/commands/screenshot_command.cc14
-rw-r--r--chrome/test/webdriver/commands/session_with_id.cc7
-rw-r--r--chrome/test/webdriver/commands/session_with_id.h5
-rw-r--r--chrome/test/webdriver/commands/set_timeout_commands.cc16
-rw-r--r--chrome/test/webdriver/commands/set_timeout_commands_unittest.cc2
-rw-r--r--chrome/test/webdriver/commands/source_command.cc11
-rw-r--r--chrome/test/webdriver/commands/speed_command.cc108
-rw-r--r--chrome/test/webdriver/commands/speed_command.h46
-rw-r--r--chrome/test/webdriver/commands/target_locator_commands.cc65
-rw-r--r--chrome/test/webdriver/commands/title_command.cc16
-rw-r--r--chrome/test/webdriver/commands/title_command.h5
-rw-r--r--chrome/test/webdriver/commands/url_command.cc27
-rw-r--r--chrome/test/webdriver/commands/url_command.h5
-rw-r--r--chrome/test/webdriver/commands/webdriver_command.cc32
-rw-r--r--chrome/test/webdriver/commands/webdriver_command.h9
-rw-r--r--chrome/test/webdriver/commands/webelement_commands.cc219
-rw-r--r--chrome/test/webdriver/dispatch.cc6
-rw-r--r--chrome/test/webdriver/error_codes.h42
-rw-r--r--chrome/test/webdriver/server.cc3
-rw-r--r--chrome/test/webdriver/session.cc794
-rw-r--r--chrome/test/webdriver/session.h194
-rw-r--r--chrome/test/webdriver/webdriver_error.cc98
-rw-r--r--chrome/test/webdriver/webdriver_error.h69
40 files changed, 1316 insertions, 1473 deletions
diff --git a/chrome/test/webdriver/automation.cc b/chrome/test/webdriver/automation.cc
index 8e53342..1a0f9d2 100644
--- a/chrome/test/webdriver/automation.cc
+++ b/chrome/test/webdriver/automation.cc
@@ -16,6 +16,7 @@
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/path_service.h"
+#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/automation_constants.h"
@@ -26,6 +27,7 @@
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/proxy_launcher.h"
#include "chrome/test/webdriver/frame_path.h"
+#include "chrome/test/webdriver/webdriver_error.h"
#include "googleurl/src/gurl.h"
#include "ui/gfx/point.h"
@@ -119,21 +121,24 @@ Automation::Automation() {}
Automation::~Automation() {}
void Automation::Init(const CommandLine& options,
- ErrorCode* code) {
+ Error** error) {
FilePath browser_exe;
if (!GetDefaultChromeExe(&browser_exe)) {
- *code = kBrowserCouldNotBeFound;
+ *error = new Error(kUnknownError, "Could not find default Chrome binary");
return;
}
- InitWithBrowserPath(browser_exe, options, code);
+ InitWithBrowserPath(browser_exe, options, error);
}
void Automation::InitWithBrowserPath(const FilePath& browser_exe,
const CommandLine& options,
- ErrorCode* code) {
+ Error** error) {
if (!file_util::PathExists(browser_exe)) {
- *code = kBrowserCouldNotBeFound;
+ std::string message = base::StringPrintf(
+ "Could not find Chrome binary at: %" PRFilePath,
+ browser_exe.value().c_str());
+ *error = new Error(kUnknownError, message);
return;
}
@@ -160,17 +165,26 @@ void Automation::InitWithBrowserPath(const FilePath& browser_exe,
};
if (!launcher_->LaunchBrowserAndServer(launch_props, true)) {
- *code = kBrowserFailedToStart;
+ *error = new Error(
+ kUnknownError,
+ "Unable to either launch or connect to Chrome. Please check that "
+ "ChromeDriver is up-to-date");
return;
}
int version = 0;
- if (!SendGetChromeDriverAutomationVersion(automation(), &version) ||
- version > automation::kChromeDriverAutomationVersion) {
- *code = kIncompatibleBrowserVersion;
+ std::string error_msg;
+ if (!SendGetChromeDriverAutomationVersion(
+ automation(), &version, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ return;
+ }
+ if (version > automation::kChromeDriverAutomationVersion) {
+ *error = new Error(
+ kUnknownError,
+ "ChromeDriver is not compatible with this version of Chrome.");
return;
}
- *code = kSuccess;
}
void Automation::Terminate() {
@@ -183,194 +197,225 @@ void Automation::ExecuteScript(int tab_id,
const FramePath& frame_path,
const std::string& script,
std::string* result,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
Value* unscoped_value;
+ std::string error_msg;
if (!SendExecuteJavascriptJSONRequest(automation(), windex, tab_index,
frame_path.value(), script,
- &unscoped_value)) {
- *success = false;
+ &unscoped_value, &error_msg)) {
+ *error = CreateChromeError(error_msg);
return;
}
scoped_ptr<Value> value(unscoped_value);
- *success = value->GetAsString(result);
+ if (!value->GetAsString(result))
+ *error = CreateChromeError("Execute script did not return string");
}
void Automation::MouseMove(int tab_id,
const gfx::Point& p,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendMouseMoveJSONRequest(
- automation(), windex, tab_index, p.x(), p.y());
+ std::string error_msg;
+ if (!SendMouseMoveJSONRequest(
+ automation(), windex, tab_index, p.x(), p.y(), &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::MouseClick(int tab_id,
const gfx::Point& p,
automation::MouseButton button,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendMouseClickJSONRequest(
- automation(), windex, tab_index, button, p.x(), p.y());
+ std::string error_msg;
+ if (!SendMouseClickJSONRequest(
+ automation(), windex, tab_index, button, p.x(), p.y(), &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::MouseDrag(int tab_id,
const gfx::Point& start,
const gfx::Point& end,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendMouseDragJSONRequest(
- automation(), windex, tab_index, start.x(), start.y(), end.x(), end.y());
+ std::string error_msg;
+ if (!SendMouseDragJSONRequest(automation(), windex, tab_index, start.x(),
+ start.y(), end.x(), end.y(), &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::MouseButtonUp(int tab_id,
const gfx::Point& p,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendMouseButtonUpJSONRequest(
- automation(), windex, tab_index, p.x(), p.y());
+ std::string error_msg;
+ if (!SendMouseButtonUpJSONRequest(
+ automation(), windex, tab_index, p.x(), p.y(), &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::MouseButtonDown(int tab_id,
const gfx::Point& p,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendMouseButtonDownJSONRequest(
- automation(), windex, tab_index, p.x(), p.y());
+ std::string error_msg;
+ if (!SendMouseButtonDownJSONRequest(
+ automation(), windex, tab_index, p.x(), p.y(), &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::MouseDoubleClick(int tab_id,
const gfx::Point& p,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendMouseDoubleClickJSONRequest(
- automation(), windex, tab_index, p.x(), p.y());
+ std::string error_msg;
+ if (!SendMouseDoubleClickJSONRequest(
+ automation(), windex, tab_index, p.x(), p.y(), &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::SendWebKeyEvent(int tab_id,
const WebKeyEvent& key_event,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
+
+ std::string error_msg;
+ if (!SendWebKeyEventJSONRequest(
+ automation(), windex, tab_index, key_event, &error_msg)) {
+ *error = CreateChromeError(error_msg);
}
- *success = SendWebKeyEventJSONRequest(
- automation(), windex, tab_index, key_event);
}
void Automation::SendNativeKeyEvent(int tab_id,
ui::KeyboardCode key_code,
int modifiers,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
+
+ std::string error_msg;
+ if (!SendNativeKeyEventJSONRequest(
+ automation(), windex, tab_index, key_code, modifiers, &error_msg)) {
+ *error = CreateChromeError(error_msg);
}
- *success = SendNativeKeyEventJSONRequest(
- automation(), windex, tab_index, key_code, modifiers);
}
void Automation::CaptureEntirePageAsPNG(int tab_id,
const FilePath& path,
- bool* success) {
+ Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendCaptureEntirePageJSONRequest(
- automation(), windex, tab_index, path);
+ std::string error_msg;
+ if (!SendCaptureEntirePageJSONRequest(
+ automation(), windex, tab_index, path, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::NavigateToURL(int tab_id,
const std::string& url,
- bool* success) {
- int browser_index = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &browser_index, &tab_index)) {
- *success = false;
+ Error** error) {
+ int windex = 0, tab_index = 0;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
AutomationMsg_NavigationResponseValues navigate_response;
- if (!SendNavigateToURLJSONRequest(automation(), browser_index, tab_index,
- GURL(url), 1, &navigate_response)) {
- *success = false;
+ std::string error_msg;
+ if (!SendNavigateToURLJSONRequest(automation(), windex, tab_index,
+ GURL(url), 1, &navigate_response,
+ &error_msg)) {
+ *error = CreateChromeError(error_msg);
return;
}
- *success = navigate_response != AUTOMATION_MSG_NAVIGATION_ERROR;
+ // TODO(kkania): Do not rely on this enum.
+ if (navigate_response == AUTOMATION_MSG_NAVIGATION_ERROR)
+ *error = new Error(kUnknownError, "Navigation error occurred");
}
-void Automation::GoForward(int tab_id, bool* success) {
+void Automation::GoForward(int tab_id, Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendGoForwardJSONRequest(automation(), windex, tab_index);
+ std::string error_msg;
+ if (!SendGoForwardJSONRequest(
+ automation(), windex, tab_index, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
-void Automation::GoBack(int tab_id, bool* success) {
+void Automation::GoBack(int tab_id, Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendGoBackJSONRequest(automation(), windex, tab_index);
+ std::string error_msg;
+ if (!SendGoBackJSONRequest(automation(), windex, tab_index, &error_msg))
+ *error = CreateChromeError(error_msg);
}
-void Automation::Reload(int tab_id, bool* success) {
+void Automation::Reload(int tab_id, Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendReloadJSONRequest(automation(), windex, tab_index);
+ std::string error_msg;
+ if (!SendReloadJSONRequest(automation(), windex, tab_index, &error_msg))
+ *error = CreateChromeError(error_msg);
}
void Automation::GetCookies(const std::string& url,
ListValue** cookies,
- bool* success) {
- *success = SendGetCookiesJSONRequest(automation(), url, cookies);
+ Error** error) {
+ std::string error_msg;
+ if (!SendGetCookiesJSONRequest(automation(), url, cookies, &error_msg))
+ *error = CreateChromeError(error_msg);
}
void Automation::GetCookiesDeprecated(int tab_id,
@@ -378,7 +423,8 @@ void Automation::GetCookiesDeprecated(int tab_id,
std::string* cookies,
bool* success) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ scoped_ptr<Error> error(GetIndicesForTab(tab_id, &windex, &tab_index));
+ if (error.get()) {
*success = false;
return;
}
@@ -389,8 +435,12 @@ void Automation::GetCookiesDeprecated(int tab_id,
void Automation::DeleteCookie(const std::string& url,
const std::string& cookie_name,
- bool* success) {
- *success = SendDeleteCookieJSONRequest(automation(), url, cookie_name);
+ Error** error) {
+ std::string error_msg;
+ if (!SendDeleteCookieJSONRequest(
+ automation(), url, cookie_name, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::DeleteCookieDeprecated(int tab_id,
@@ -398,7 +448,8 @@ void Automation::DeleteCookieDeprecated(int tab_id,
const std::string& cookie_name,
bool* success) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ scoped_ptr<Error> error(GetIndicesForTab(tab_id, &windex, &tab_index));
+ if (error.get()) {
*success = false;
return;
}
@@ -412,8 +463,10 @@ void Automation::DeleteCookieDeprecated(int tab_id,
void Automation::SetCookie(const std::string& url,
DictionaryValue* cookie_dict,
- bool* success) {
- *success = SendSetCookieJSONRequest(automation(), url, cookie_dict);
+ Error** error) {
+ std::string error_msg;
+ if (!SendSetCookieJSONRequest(automation(), url, cookie_dict, &error_msg))
+ *error = CreateChromeError(error_msg);
}
void Automation::SetCookieDeprecated(int tab_id,
@@ -421,7 +474,8 @@ void Automation::SetCookieDeprecated(int tab_id,
const std::string& cookie,
bool* success) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
+ scoped_ptr<Error> error(GetIndicesForTab(tab_id, &windex, &tab_index));
+ if (error.get()) {
*success = false;
return;
}
@@ -434,63 +488,88 @@ void Automation::SetCookieDeprecated(int tab_id,
}
void Automation::GetTabIds(std::vector<int>* tab_ids,
- bool* success) {
- *success = SendGetTabIdsJSONRequest(automation(), tab_ids);
+ Error** error) {
+ std::string error_msg;
+ if (!SendGetTabIdsJSONRequest(automation(), tab_ids, &error_msg))
+ *error = CreateChromeError(error_msg);
}
-void Automation::DoesTabExist(int tab_id, bool* does_exist, bool* success) {
- *success = SendIsTabIdValidJSONRequest(automation(), tab_id, does_exist);
+void Automation::DoesTabExist(int tab_id, bool* does_exist, Error** error) {
+ std::string error_msg;
+ if (!SendIsTabIdValidJSONRequest(
+ automation(), tab_id, does_exist, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
-void Automation::CloseTab(int tab_id, bool* success) {
+void Automation::CloseTab(int tab_id, Error** error) {
int windex = 0, tab_index = 0;
- if (!GetIndicesForTab(tab_id, &windex, &tab_index)) {
- *success = false;
+ *error = GetIndicesForTab(tab_id, &windex, &tab_index);
+ if (*error)
return;
- }
- *success = SendCloseTabJSONRequest(automation(), windex, tab_index);
+ std::string error_msg;
+ if (!SendCloseTabJSONRequest(automation(), windex, tab_index, &error_msg))
+ *error = CreateChromeError(error_msg);
}
-void Automation::GetAppModalDialogMessage(std::string* message, bool* success) {
- *success = SendGetAppModalDialogMessageJSONRequest(automation(), message);
+void Automation::GetAppModalDialogMessage(std::string* message, Error** error) {
+ std::string error_msg;
+ if (!SendGetAppModalDialogMessageJSONRequest(
+ automation(), message, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
-void Automation::AcceptOrDismissAppModalDialog(bool accept, bool* success) {
- *success = SendAcceptOrDismissAppModalDialogJSONRequest(
- automation(), accept);
+void Automation::AcceptOrDismissAppModalDialog(bool accept, Error** error) {
+ std::string error_msg;
+ if (!SendAcceptOrDismissAppModalDialogJSONRequest(
+ automation(), accept, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::AcceptPromptAppModalDialog(const std::string& prompt_text,
- bool* success) {
- *success = SendAcceptPromptAppModalDialogJSONRequest(
- automation(), prompt_text);
+ Error** error) {
+ std::string error_msg;
+ if (!SendAcceptPromptAppModalDialogJSONRequest(
+ automation(), prompt_text, &error_msg)) {
+ *error = CreateChromeError(error_msg);
+ }
}
void Automation::GetBrowserVersion(std::string* version) {
*version = automation()->server_version();
}
-void Automation::GetChromeDriverAutomationVersion(int* version, bool* success) {
- *success = SendGetChromeDriverAutomationVersion(automation(), version);
+void Automation::GetChromeDriverAutomationVersion(int* version, Error** error) {
+ std::string error_msg;
+ if (!SendGetChromeDriverAutomationVersion(automation(), version, &error_msg))
+ *error = CreateChromeError(error_msg);
}
-void Automation::WaitForAllTabsToStopLoading(bool* success) {
- *success = SendWaitForAllTabsToStopLoadingJSONRequest(automation());
+void Automation::WaitForAllTabsToStopLoading(Error** error) {
+ std::string error_msg;
+ if (!SendWaitForAllTabsToStopLoadingJSONRequest(automation(), &error_msg))
+ *error = CreateChromeError(error_msg);
}
AutomationProxy* Automation::automation() const {
return launcher_->automation();
}
-bool Automation::GetIndicesForTab(
+Error* Automation::GetIndicesForTab(
int tab_id, int* browser_index, int* 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;
+ std::string error_msg;
+ if (!SendGetIndicesFromTabIdJSONRequest(
+ automation(), tab_id, browser_index, tab_index, &error_msg)) {
+ return CreateChromeError(error_msg);
}
- return true;
+ return NULL;
+}
+
+Error* Automation::CreateChromeError(const std::string& message) {
+ return new Error(kUnknownError, "Internal Chrome error: " + message);
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/automation.h b/chrome/test/webdriver/automation.h
index 6b70f63..37d46fd 100644
--- a/chrome/test/webdriver/automation.h
+++ b/chrome/test/webdriver/automation.h
@@ -13,7 +13,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/task.h"
#include "chrome/common/automation_constants.h"
-#include "chrome/test/webdriver/error_codes.h"
#include "ui/base/keycodes/keyboard_codes.h"
class AutomationProxy;
@@ -31,6 +30,7 @@ class Point;
namespace webdriver {
+class Error;
class FramePath;
// Creates and controls the Chrome instance.
@@ -45,11 +45,10 @@ class Automation {
// Creates a browser, using the specified |browser_exe|.
void InitWithBrowserPath(const FilePath& browser_exe,
const CommandLine& options,
- ErrorCode* code);
+ Error** error);
// Start the system's default Chrome binary.
- void Init(const CommandLine& options,
- ErrorCode* code);
+ void Init(const CommandLine& options, Error** error);
// Terminates this session and disconnects its automation proxy. After
// invoking this method, the Automation can safely be deleted.
@@ -61,92 +60,93 @@ class Automation {
const FramePath& frame_path,
const std::string& script,
std::string* result,
- bool* success);
+ Error** error);
// Sends a webkit key event to the current browser. Waits until the key has
// been processed by the web page.
void SendWebKeyEvent(int tab_id,
const WebKeyEvent& key_event,
- bool* success);
+ Error** error);
// Sends an OS level key event to the current browser. Waits until the key
// has been processed by the browser.
void SendNativeKeyEvent(int tab_id,
ui::KeyboardCode key_code,
int modifiers,
- bool* success);
+ Error** error);
// Captures a snapshot of the tab to the specified path. The PNG will
// contain the entire page, including what is not in the current view
// on the screen.
- void CaptureEntirePageAsPNG(int tab_id, const FilePath& path, bool* success);
+ void CaptureEntirePageAsPNG(int tab_id, const FilePath& path, Error** error);
- void NavigateToURL(int tab_id, const std::string& url, bool* success);
- void GoForward(int tab_id, bool* success);
- void GoBack(int tab_id, bool* success);
- void Reload(int tab_id, bool* success);
+ void NavigateToURL(int tab_id, const std::string& url, Error** error);
+ void GoForward(int tab_id, Error** error);
+ void GoBack(int tab_id, Error** error);
+ void Reload(int tab_id, Error** error);
- void GetCookies(const std::string& url, ListValue** cookies, bool* success);
+ void GetCookies(const std::string& url, ListValue** cookies, Error** error);
void GetCookiesDeprecated(
int tab_id, const GURL& gurl, std::string* cookies, bool* success);
void DeleteCookie(const std::string& url,
const std::string& cookie_name,
- bool* success);
+ Error** error);
void DeleteCookieDeprecated(int tab_id,
const GURL& gurl,
const std::string& cookie_name,
bool* success);
void SetCookie(
- const std::string& url, DictionaryValue* cookie_dict, bool* success);
+ const std::string& url, DictionaryValue* cookie_dict, Error** error);
void SetCookieDeprecated(
int tab_id, const GURL& gurl, const std::string& cookie, bool* success);
- void MouseMove(int tab_id, const gfx::Point& p, bool* success);
+ void MouseMove(int tab_id, const gfx::Point& p, Error** error);
void MouseClick(int tab_id,
const gfx::Point& p,
automation::MouseButton button,
- bool* success);
+ Error** error);
void MouseDrag(int tab_id,
const gfx::Point& start,
const gfx::Point& end,
- bool* success);
- void MouseButtonDown(int tab_id, const gfx::Point& p, bool* success);
- void MouseButtonUp(int tab_id, const gfx::Point& p, bool* success);
- void MouseDoubleClick(int tab_id, const gfx::Point& p, bool* success);
+ Error** error);
+ void MouseButtonDown(int tab_id, const gfx::Point& p, Error** error);
+ void MouseButtonUp(int tab_id, const gfx::Point& p, Error** error);
+ void MouseDoubleClick(int tab_id, const gfx::Point& p, Error** error);
// Get persistent IDs for all the tabs currently open. These IDs can be used
// to identify the tab as long as the tab exists.
- void GetTabIds(std::vector<int>* tab_ids, bool* success);
+ void GetTabIds(std::vector<int>* tab_ids, Error** error);
// Check if the given tab exists currently.
- void DoesTabExist(int tab_id, bool* does_exist, bool* success);
+ void DoesTabExist(int tab_id, bool* does_exist, Error** error);
- void CloseTab(int tab_id, bool* success);
+ void CloseTab(int tab_id, Error** error);
// Gets the active JavaScript modal dialog's message.
- void GetAppModalDialogMessage(std::string* message, bool* success);
+ void GetAppModalDialogMessage(std::string* message, Error** error);
// Accepts or dismisses the active JavaScript modal dialog.
- void AcceptOrDismissAppModalDialog(bool accept, bool* success);
+ void AcceptOrDismissAppModalDialog(bool accept, Error** error);
// Accepts an active prompt JavaScript modal dialog, using the given
// prompt text as the result of the prompt.
void AcceptPromptAppModalDialog(const std::string& prompt_text,
- bool* success);
+ Error** error);
// Gets the version of the runing browser.
void GetBrowserVersion(std::string* version);
// Gets the ChromeDriver automation version supported by the automation
// server.
- void GetChromeDriverAutomationVersion(int* version, bool* success);
+ void GetChromeDriverAutomationVersion(int* version, Error** error);
// Waits for all tabs to stop loading.
- void WaitForAllTabsToStopLoading(bool* success);
+ void WaitForAllTabsToStopLoading(Error** error);
private:
AutomationProxy* automation() const;
- bool GetIndicesForTab(int tab_id, int* browser_index, int* tab_index);
+ Error* GetIndicesForTab(int tab_id, int* browser_index, int* tab_index);
+ Error* CreateChromeError(const std::string& message);
scoped_ptr<ProxyLauncher> launcher_;
diff --git a/chrome/test/webdriver/commands/alert_commands.cc b/chrome/test/webdriver/commands/alert_commands.cc
index 9fb7464..5b0df47 100644
--- a/chrome/test/webdriver/commands/alert_commands.cc
+++ b/chrome/test/webdriver/commands/alert_commands.cc
@@ -6,8 +6,8 @@
#include "base/values.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/webdriver_error.h"
namespace webdriver {
@@ -30,19 +30,24 @@ bool AlertTextCommand::DoesPost() {
void AlertTextCommand::ExecuteGet(Response* const response) {
std::string text;
- ErrorCode code = session_->GetAlertMessage(&text);
- if (code == kSuccess)
- response->SetValue(Value::CreateStringValue(text));
- response->SetStatus(code);
+ Error* error = session_->GetAlertMessage(&text);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
+ response->SetValue(Value::CreateStringValue(text));
}
void AlertTextCommand::ExecutePost(Response* const response) {
std::string text;
if (!GetStringParameter("text", &text)) {
- SET_WEBDRIVER_ERROR(response, "'text' is missing or invalid", kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "'text' is missing or invalid"));
return;
}
- response->SetStatus(session_->SetAlertPromptText(text));
+ Error* error = session_->SetAlertPromptText(text);
+ if (error)
+ response->SetError(error);
}
AcceptAlertCommand::AcceptAlertCommand(
@@ -59,7 +64,9 @@ bool AcceptAlertCommand::DoesPost() {
}
void AcceptAlertCommand::ExecutePost(Response* const response) {
- response->SetStatus(session_->AcceptOrDismissAlert(true));
+ Error* error = session_->AcceptOrDismissAlert(true);
+ if (error)
+ response->SetError(error);
}
DismissAlertCommand::DismissAlertCommand(
@@ -76,7 +83,9 @@ bool DismissAlertCommand::DoesPost() {
}
void DismissAlertCommand::ExecutePost(Response* const response) {
- response->SetStatus(session_->AcceptOrDismissAlert(false));
+ Error* error = session_->AcceptOrDismissAlert(false);
+ if (error)
+ response->SetError(error);
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/cookie_commands.cc b/chrome/test/webdriver/commands/cookie_commands.cc
index 3b6c725..657cd9f 100644
--- a/chrome/test/webdriver/commands/cookie_commands.cc
+++ b/chrome/test/webdriver/commands/cookie_commands.cc
@@ -33,16 +33,16 @@ CookieCommand::~CookieCommand() {}
bool CookieCommand::Init(Response* const response) {
if (!WebDriverCommand::Init(response))
return false;
- if (!session_->CompareBrowserVersion(kNewInterfaceBuildNo, 0,
- &uses_new_interface_)) {
- SET_WEBDRIVER_ERROR(response, "Failed to check Chrome version number",
- kUnknownError);
+
+ Error* error = session_->CompareBrowserVersion(
+ kNewInterfaceBuildNo, 0, &uses_new_interface_);
+ if (error) {
+ response->SetError(error);
return false;
}
- ErrorCode code = session_->GetURL(&current_url_);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to query current page URL",
- code);
+ error = session_->GetURL(&current_url_);
+ if (error) {
+ response->SetError(error);
return false;
}
return true;
@@ -63,9 +63,10 @@ bool CookieCommand::DoesPost() {
void CookieCommand::ExecuteGet(Response* const response) {
if (uses_new_interface_) {
ListValue* cookies;
- if (!session_->GetCookies(current_url_.possibly_invalid_spec(), &cookies)) {
- SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies",
- kUnknownError);
+ Error* error = session_->GetCookies(current_url_.possibly_invalid_spec(),
+ &cookies);
+ if (error) {
+ response->SetError(error);
return;
}
response->SetStatus(kSuccess);
@@ -74,8 +75,7 @@ void CookieCommand::ExecuteGet(Response* const response) {
std::string cookies;
std::vector<std::string> tokens;
if (!session_->GetCookiesDeprecated(current_url_, &cookies)) {
- SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies",
- kUnknownError);
+ response->SetError(new Error(kUnknownError, "Failed to fetch cookies"));
return;
}
// Note that ';' separates cookies while ':' separates name/value pairs.
@@ -87,9 +87,7 @@ void CookieCommand::ExecuteGet(Response* const response) {
if (cookie.valid()) {
cookie_list->Append(cookie.ToDictionary());
} else {
- LOG(ERROR) << "Failed to parse cookie: " << *i;
- SET_WEBDRIVER_ERROR(response, "Could not get all cookies",
- kInternalServerError);
+ response->SetError(new Error(kUnknownError, "Failed to parse cookies"));
return;
}
}
@@ -104,9 +102,7 @@ void CookieCommand::ExecutePost(Response* const response) {
// Check to see if the cookie was passed in as a JSON onject.
if (!GetDictionaryParameter("cookie", &cookie_dict)) {
- // No valid cookie sent.
- SET_WEBDRIVER_ERROR(response, "Cookie key not found",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Cookie key not found"));
return;
}
@@ -116,18 +112,18 @@ void CookieCommand::ExecutePost(Response* const response) {
std::vector<std::string> split_domain;
base::SplitString(domain, ':', &split_domain);
if (split_domain.size() > 2) {
- SET_WEBDRIVER_ERROR(response, "Cookie domain has too many colons",
- kInvalidCookieDomain);
+ response->SetError(new Error(
+ kInvalidCookieDomain, "Cookie domain has too many colons"));
return;
} else if (split_domain.size() == 2) {
// Remove the port number.
cookie_dict->SetString("domain", split_domain[0]);
}
}
- if (!session_->SetCookie(current_url_.possibly_invalid_spec(),
- cookie_dict)) {
- SET_WEBDRIVER_ERROR(response, "Failed to set cookie",
- kUnableToSetCookie);
+ Error* error = session_->SetCookie(
+ current_url_.possibly_invalid_spec(), cookie_dict);
+ if (error) {
+ response->SetError(error);
return;
}
} else {
@@ -135,14 +131,12 @@ void CookieCommand::ExecutePost(Response* const response) {
// Make sure the cookie is formated preoperly.
if (!cookie.valid()) {
- SET_WEBDRIVER_ERROR(response, "Invalid cookie",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Invalid cookie"));
return;
}
if (!session_->SetCookieDeprecated(current_url_, cookie.ToString())) {
- SET_WEBDRIVER_ERROR(response, "Failed to set cookie",
- kUnableToSetCookie);
+ response->SetError(new Error(kUnableToSetCookie, "Failed to set cookie"));
return;
}
response->SetValue(new StringValue(cookie.ToString()));
@@ -153,32 +147,31 @@ void CookieCommand::ExecutePost(Response* const response) {
void CookieCommand::ExecuteDelete(Response* const response) {
if (uses_new_interface_) {
ListValue* unscoped_cookies;
- if (!session_->GetCookies(current_url_.possibly_invalid_spec(),
- &unscoped_cookies)) {
- SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies",
- kUnknownError);
+ Error* error = session_->GetCookies(
+ current_url_.possibly_invalid_spec(), &unscoped_cookies);
+ if (error) {
+ response->SetError(error);
return;
}
scoped_ptr<ListValue> cookies(unscoped_cookies);
for (size_t i = 0; i < cookies->GetSize(); ++i) {
DictionaryValue* cookie_dict;
if (!cookies->GetDictionary(i, &cookie_dict)) {
- SET_WEBDRIVER_ERROR(response, "GetCookies returned non-dict type",
- kUnknownError);
+ response->SetError(new Error(
+ kUnknownError, "GetCookies returned non-dict type"));
return;
}
std::string name;
if (!cookie_dict->GetString("name", &name)) {
- SET_WEBDRIVER_ERROR(
- response,
- "GetCookies returned cookie with missing or invalid 'name'",
- kUnknownError);
+ response->SetError(new Error(
+ kUnknownError,
+ "GetCookies returned cookie with missing or invalid 'name'"));
return;
}
- if (!session_->DeleteCookie(current_url_.possibly_invalid_spec(),
- name)) {
- SET_WEBDRIVER_ERROR(response, "Could not delete all cookies",
- kUnknownError);
+ Error* error = session_->DeleteCookie(
+ current_url_.possibly_invalid_spec(), name);
+ if (error) {
+ response->SetError(error);
return;
}
}
@@ -187,8 +180,8 @@ void CookieCommand::ExecuteDelete(Response* const response) {
std::vector<std::string> tokens;
if (!session_->GetCookiesDeprecated(current_url_, &cookies)) {
- SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies",
- kUnableToSetCookie);
+ response->SetError(new Error(
+ kUnableToSetCookie, "Failed to fetch cookies"));
return;
}
@@ -199,16 +192,12 @@ void CookieCommand::ExecuteDelete(Response* const response) {
if (cookie.valid()) {
if (!session_->DeleteCookie(current_url_.possibly_invalid_spec(),
cookie.name())) {
- VLOG(1) << "Could not delete cookie: " << cookie.name() << "\n"
- << "Contents of cookie: " << cookie.ToString();
- SET_WEBDRIVER_ERROR(response, "Could not delete all cookies",
- kInternalServerError);
+ response->SetError(new Error(
+ kUnknownError, "Could not delete all cookies"));
return;
}
} else {
- LOG(ERROR) << "Failed to parse cookie: " << *i;
- SET_WEBDRIVER_ERROR(response, "Could not delete all cookies",
- kInternalServerError);
+ response->SetError(new Error(kUnknownError, "Failed to parse cookie"));
return;
}
}
@@ -228,17 +217,16 @@ bool NamedCookieCommand::Init(Response* const response) {
if (!WebDriverCommand::Init(response))
return false;
- if (!session_->CompareBrowserVersion(kNewInterfaceBuildNo, 0,
- &uses_new_interface_)) {
- SET_WEBDRIVER_ERROR(response, "Failed to check Chrome version number",
- kUnknownError);
+ Error* error = session_->CompareBrowserVersion(
+ kNewInterfaceBuildNo, 0, &uses_new_interface_);
+ if (error) {
+ response->SetError(error);
return false;
}
- ErrorCode code = session_->GetURL(&current_url_);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to query current page URL",
- code);
+ error = session_->GetURL(&current_url_);
+ if (error) {
+ response->SetError(error);
return false;
}
@@ -246,8 +234,7 @@ bool NamedCookieCommand::Init(Response* const response) {
// /session/:sessionId/cookie/:name
cookie_name_ = GetPathVariable(4);
if (cookie_name_ == "") {
- SET_WEBDRIVER_ERROR(response, "No cookie name specified",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "No cookie name specified"));
return false;
}
@@ -260,17 +247,15 @@ bool NamedCookieCommand::DoesDelete() {
void NamedCookieCommand::ExecuteDelete(Response* const response) {
if (uses_new_interface_) {
- if (!session_->DeleteCookie(current_url_.possibly_invalid_spec(),
- cookie_name_)) {
- SET_WEBDRIVER_ERROR(response,
- "Failed to delete cookie",
- kUnknownError);
+ Error* error = session_->DeleteCookie(
+ current_url_.possibly_invalid_spec(), cookie_name_);
+ if (error) {
+ response->SetError(error);
return;
}
} else {
if (!session_->DeleteCookieDeprecated(current_url_, cookie_name_)) {
- SET_WEBDRIVER_ERROR(response, "Failed to delete cookie",
- kUnknownError);
+ response->SetError(new Error(kUnknownError, "Failed to delete cookie"));
return;
}
}
diff --git a/chrome/test/webdriver/commands/create_session.cc b/chrome/test/webdriver/commands/create_session.cc
index c2f37e2..d6bab1c 100644
--- a/chrome/test/webdriver/commands/create_session.cc
+++ b/chrome/test/webdriver/commands/create_session.cc
@@ -16,12 +16,10 @@
#include "chrome/test/webdriver/commands/response.h"
#include "chrome/test/webdriver/session.h"
#include "chrome/test/webdriver/session_manager.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
-// The minimum supported version of Chrome for this version of ChromeDriver.
-const int kMinSupportedChromeVersion = 12;
-
CreateSession::CreateSession(const std::vector<std::string>& path_segments,
const DictionaryValue* const parameters)
: Command(path_segments, parameters) {}
@@ -46,9 +44,8 @@ void CreateSession::ExecutePost(Response* const response) {
while (i != added_options->end_keys()) {
FilePath::StringType value;
if (!added_options->GetString(*i, &value)) {
- SET_WEBDRIVER_ERROR(response,
- "Invalid format for added options to browser",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "Invalid format for added options to browser"));
return;
} else {
if (!value.empty()) {
@@ -57,7 +54,7 @@ void CreateSession::ExecutePost(Response* const response) {
options.AppendSwitch(*i);
}
}
- ++i;
+ ++i;
}
FilePath::StringType path;
desiredCapabilities->GetString("chrome.binary", &path);
@@ -66,33 +63,9 @@ void CreateSession::ExecutePost(Response* const response) {
// Session manages its own liftime, so do not call delete.
Session* session = new Session();
- ErrorCode code = session->Init(user_browser_exe, options);
-
- if (code == kBrowserCouldNotBeFound) {
- SET_WEBDRIVER_ERROR(response,
- "Chrome could not be found.",
- kUnknownError);
- return;
- } else if (code == kBrowserFailedToStart) {
- std::string error_msg = base::StringPrintf(
- "Chrome could not be started successfully. "
- "Please update ChromeDriver and ensure you are using Chrome %d+.",
- kMinSupportedChromeVersion);
- SET_WEBDRIVER_ERROR(response, error_msg, kUnknownError);
- return;
- } else if (code == kIncompatibleBrowserVersion) {
- std::string error_msg = base::StringPrintf(
- "Version of Chrome is incompatible with version of ChromeDriver. "
- "Please update ChromeDriver and ensure you are using Chrome %d+.",
- kMinSupportedChromeVersion);
- SET_WEBDRIVER_ERROR(response, error_msg, kUnknownError);
- return;
- } else if (code != kSuccess) {
- std::string error_msg = base::StringPrintf(
- "Unknown error while initializing session. "
- "Ensure ChromeDriver is up-to-date and Chrome is version %d+.",
- kMinSupportedChromeVersion);
- SET_WEBDRIVER_ERROR(response, error_msg, kUnknownError);
+ Error* error = session->Init(user_browser_exe, options);
+ if (error) {
+ response->SetError(error);
return;
}
diff --git a/chrome/test/webdriver/commands/create_session.h b/chrome/test/webdriver/commands/create_session.h
index d401a7f..6595ae2 100644
--- a/chrome/test/webdriver/commands/create_session.h
+++ b/chrome/test/webdriver/commands/create_session.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,6 @@
#include <vector>
#include "chrome/test/webdriver/commands/command.h"
-#include "chrome/test/webdriver/commands/webdriver_command.h"
namespace webdriver {
@@ -37,4 +36,3 @@ class CreateSession : public Command {
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_CREATE_SESSION_H_
-
diff --git a/chrome/test/webdriver/commands/execute_async_script_command.cc b/chrome/test/webdriver/commands/execute_async_script_command.cc
index 9d5e370..747640e 100644
--- a/chrome/test/webdriver/commands/execute_async_script_command.cc
+++ b/chrome/test/webdriver/commands/execute_async_script_command.cc
@@ -6,8 +6,8 @@
#include "base/values.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/webdriver_error.h"
namespace webdriver {
@@ -25,24 +25,26 @@ bool ExecuteAsyncScriptCommand::DoesPost() {
void ExecuteAsyncScriptCommand::ExecutePost(Response* const response) {
std::string script;
if (!GetStringParameter("script", &script)) {
- SET_WEBDRIVER_ERROR(response, "No script to execute specified",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "No script to execute specified"));
return;
}
ListValue* args;
if (!GetListParameter("args", &args)) {
- SET_WEBDRIVER_ERROR(response, "No script arguments specified",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "No script arguments specified"));
return;
}
Value* result = NULL;
- ErrorCode status = session_->ExecuteAsyncScript(
+ Error* error = session_->ExecuteAsyncScript(
session_->current_target(), script, args, &result);
- response->SetStatus(status);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
} // namspace webdriver
-
diff --git a/chrome/test/webdriver/commands/execute_command.cc b/chrome/test/webdriver/commands/execute_command.cc
index e22264b..89bec72 100644
--- a/chrome/test/webdriver/commands/execute_command.cc
+++ b/chrome/test/webdriver/commands/execute_command.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,15 +7,12 @@
#include <string>
#include "base/values.h"
-#include "chrome/test/webdriver/error_codes.h"
#include "chrome/test/webdriver/session.h"
#include "chrome/test/webdriver/commands/response.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
-const char kArgs[] = "args";
-const char kScript[] = "script";
-
ExecuteCommand::ExecuteCommand(const std::vector<std::string>& path_segments,
const DictionaryValue* const parameters)
: WebDriverCommand(path_segments, parameters) {}
@@ -28,28 +25,25 @@ bool ExecuteCommand::DoesPost() {
void ExecuteCommand::ExecutePost(Response* const response) {
std::string script;
- if (!GetStringParameter(kScript, &script)) {
- SET_WEBDRIVER_ERROR(response, "No script to execute specified",
- kBadRequest);
+ if (!GetStringParameter("script", &script)) {
+ response->SetError(new Error(kBadRequest, "No script specified"));
return;
}
ListValue* args;
- if (!GetListParameter(kArgs, &args)) {
- SET_WEBDRIVER_ERROR(response, "No script arguments specified",
- kBadRequest);
+ if (!GetListParameter("args", &args)) {
+ response->SetError(new Error(
+ kBadRequest, "No script arguments specified"));
return;
}
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args, &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
-bool ExecuteCommand::RequiresValidTab() {
- return true;
-}
-
} // namspace webdriver
-
diff --git a/chrome/test/webdriver/commands/execute_command.h b/chrome/test/webdriver/commands/execute_command.h
index a9f3fa2..c164b78 100644
--- a/chrome/test/webdriver/commands/execute_command.h
+++ b/chrome/test/webdriver/commands/execute_command.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -30,12 +30,9 @@ class ExecuteCommand : public WebDriverCommand {
virtual void ExecutePost(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(ExecuteCommand);
};
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_EXECUTE_COMMAND_H_
-
diff --git a/chrome/test/webdriver/commands/find_element_commands.cc b/chrome/test/webdriver/commands/find_element_commands.cc
index a40be0b..b0589bd 100644
--- a/chrome/test/webdriver/commands/find_element_commands.cc
+++ b/chrome/test/webdriver/commands/find_element_commands.cc
@@ -6,9 +6,9 @@
#include "base/values.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 "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
@@ -29,12 +29,12 @@ void FindElementCommand::ExecutePost(Response* const response) {
std::string locator, query;
if (!GetStringParameter("using", &locator) ||
!GetStringParameter("value", &query)) {
- SET_WEBDRIVER_ERROR(response,
- "Request is missing required 'using' and/or 'value' data", kBadRequest);
+ response->SetError(new Error(
+ kBadRequest,
+ "Request is missing required 'using' and/or 'value' data"));
return;
}
- // TODO(jmikhail): The findElement(s) atom should handle this conversion.
if (locator == "class name") {
locator = LocatorType::kClassName;
} else if (locator == "css selector") {
@@ -53,25 +53,29 @@ void FindElementCommand::ExecutePost(Response* const response) {
// "/session/$session/element/$id/element(s)"
WebElementId root_element(GetPathVariable(4));
- ErrorCode code = kUnknownError;
if (find_one_element_) {
WebElementId element;
- code = session_->FindElement(
+ Error* error = session_->FindElement(
session_->current_target(), root_element, locator, query, &element);
- if (code == kSuccess)
- response->SetValue(element.ToValue());
+ if (error) {
+ response->SetError(error);
+ return;
+ }
+ response->SetValue(element.ToValue());
} else {
std::vector<WebElementId> elements;
- code = session_->FindElements(
+ Error* error = session_->FindElements(
session_->current_target(), root_element, locator, query, &elements);
- if (code == kSuccess) {
- ListValue* element_list = new ListValue();
- for (size_t i = 0; i < elements.size(); ++i)
- element_list->Append(elements[i].ToValue());
- response->SetValue(element_list);
+ if (error) {
+ response->SetError(error);
+ return;
}
+ ListValue* element_list = new ListValue();
+ for (size_t i = 0; i < elements.size(); ++i)
+ element_list->Append(elements[i].ToValue());
+ response->SetValue(element_list);
}
- response->SetStatus(code);
+ response->SetStatus(kSuccess);
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/find_element_commands.h b/chrome/test/webdriver/commands/find_element_commands.h
index 4cf987e..46dfbae 100644
--- a/chrome/test/webdriver/commands/find_element_commands.h
+++ b/chrome/test/webdriver/commands/find_element_commands.h
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "chrome/test/webdriver/commands/command.h"
#include "chrome/test/webdriver/commands/webdriver_command.h"
namespace webdriver {
@@ -68,4 +67,3 @@ class FindManyElementsCommand : public FindElementCommand {
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_FIND_ELEMENT_COMMANDS_H_
-
diff --git a/chrome/test/webdriver/commands/mouse_commands.cc b/chrome/test/webdriver/commands/mouse_commands.cc
index 34281b1..c331cbc 100644
--- a/chrome/test/webdriver/commands/mouse_commands.cc
+++ b/chrome/test/webdriver/commands/mouse_commands.cc
@@ -7,17 +7,19 @@
#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 "chrome/test/webdriver/webdriver_error.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
namespace {
-static const int kLeftButton = 0;
-static const int kMiddleButton = 1;
-static const int kRightButton = 2;
-}
+
+const int kLeftButton = 0;
+const int kMiddleButton = 1;
+const int kRightButton = 2;
+
+} // namespace
namespace webdriver {
@@ -33,40 +35,32 @@ bool ElementMouseCommand::DoesPost() {
}
void ElementMouseCommand::ExecutePost(Response* response) {
- bool is_displayed;
- ErrorCode code = session_->IsElementDisplayed(
- session_->current_target(), element, &is_displayed);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to determine element visibility",
- code);
- return;
- }
- if (!is_displayed) {
- SET_WEBDRIVER_ERROR(response, "Element must be displayed",
- kElementNotVisible);
+ Error* error = session_->CheckElementPreconditionsForClicking(element);
+ if (error) {
+ response->SetError(error);
return;
}
gfx::Point location;
- code = session_->GetElementLocationInView(element, &location);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to compute element location.",
- code);
+ error = session_->GetElementLocationInView(element, &location);
+ if (error) {
+ response->SetError(error);
return;
}
gfx::Size size;
- code = session_->GetElementSize(session_->current_target(), element, &size);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to compute element size.", code);
+ error = session_->GetElementSize(session_->current_target(), element, &size);
+ if (error) {
+ response->SetError(error);
return;
}
location.Offset(size.width() / 2, size.height() / 2);
- if (!Action(location, response))
+ error = Action(location);
+ if (error) {
+ response->SetError(error);
return;
-
- response->SetStatus(kSuccess);
+ }
}
MoveAndClickCommand::MoveAndClickCommand(
@@ -76,17 +70,8 @@ MoveAndClickCommand::MoveAndClickCommand(
MoveAndClickCommand::~MoveAndClickCommand() {}
-bool MoveAndClickCommand::Action(const gfx::Point& location,
- Response* const response) {
- VLOG(1) << "Mouse click at: (" << location.x() << ", "
- << location.y() << ")" << std::endl;
- if (!session_->MouseMoveAndClick(location, automation::kLeftButton)) {
- SET_WEBDRIVER_ERROR(response, "Performing mouse operation failed",
- kUnknownError);
- return false;
- }
-
- return true;
+Error* MoveAndClickCommand::Action(const gfx::Point& location) {
+ return session_->MouseMoveAndClick(location, automation::kLeftButton);
}
HoverCommand::HoverCommand(const std::vector<std::string>& path_segments,
@@ -95,17 +80,8 @@ HoverCommand::HoverCommand(const std::vector<std::string>& path_segments,
HoverCommand::~HoverCommand() {}
-bool HoverCommand::Action(const gfx::Point& location,
- Response* const response) {
- VLOG(1) << "Mouse hover at: (" << location.x() << ", "
- << location.y() << ")" << std::endl;
- if (!session_->MouseMove(location)) {
- SET_WEBDRIVER_ERROR(response, "Performing mouse operation failed",
- kUnknownError);
- return false;
- }
-
- return true;
+Error* HoverCommand::Action(const gfx::Point& location) {
+ return session_->MouseMove(location);
}
DragCommand::DragCommand(const std::vector<std::string>& path_segments,
@@ -120,37 +96,21 @@ bool DragCommand::Init(Response* const response) {
if (!GetIntegerParameter("x", &drag_x_) ||
!GetIntegerParameter("y", &drag_y_)) {
- SET_WEBDRIVER_ERROR(response,
- "Request is missing the required positional data",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Missing (x,y) coordinates"));
return false;
}
return true;
}
-bool DragCommand::Action(const gfx::Point& location, Response* const response) {
+Error* DragCommand::Action(const gfx::Point& location) {
gfx::Point drag_from(location);
gfx::Point drag_to(drag_from);
drag_to.Offset(drag_x_, drag_y_);
- if (drag_to.x() < 0 || drag_to.y() < 0) {
- SET_WEBDRIVER_ERROR(response, "Invalid pos to drag to", kBadRequest);
- return false;
- }
+ if (drag_to.x() < 0 || drag_to.y() < 0)
+ return new Error(kBadRequest, "Invalid (x,y) coordinates");
- // click on the element
- VLOG(1) << "Dragging mouse from: "
- << "(" << location.x() << ", " << location.y() << ") "
- << "to: (" << drag_to.x() << ", " << drag_to.y() << ")"
- << std::endl;
- if (!session_->MouseDrag(location, drag_to)) {
- SET_WEBDRIVER_ERROR(response,
- "Request is missing the required positional data",
- kBadRequest);
- return false;
- }
-
- return true;
+ return session_->MouseDrag(location, drag_to);
}
AdvancedMouseCommand::AdvancedMouseCommand(
@@ -187,9 +147,8 @@ bool MoveToCommand::Init(Response* const response) {
GetIntegerParameter("yoffset", &y_offset_);
if (!has_element_ && !has_offset_) {
- SET_WEBDRIVER_ERROR(response,
- "Request is missing the required data",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "Invalid command arguments"));
return false;
}
@@ -201,63 +160,45 @@ void MoveToCommand::ExecutePost(Response* const response) {
if (has_element_) {
// If an element is specified, calculate the coordinate.
- bool is_displayed;
- ErrorCode code = session_->IsElementDisplayed(session_->current_target(),
- element_, &is_displayed);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to determine element visibility",
- code);
+ Error* error = session_->CheckElementPreconditionsForClicking(element_);
+ if (error) {
+ response->SetError(error);
return;
}
- if (!is_displayed) {
- SET_WEBDRIVER_ERROR(response, "Element must be displayed",
- kElementNotVisible);
+ error = session_->GetElementLocationInView(element_, &location);
+ if (error) {
+ response->SetError(error);
return;
}
-
- code = session_->GetElementLocationInView(element_, &location);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to compute element location.",
- code);
- return;
- }
-
- VLOG(1) << "An element requested. x:" << location.x() << " y:"
- << location.y();
-
} else {
// If not, use the current mouse position.
- VLOG(1) << "No element requested, using current mouse position";
location = session_->get_mouse_position();
}
if (has_offset_) {
// If an offset is specified, translate by the offset.
location.Offset(x_offset_, y_offset_);
-
- VLOG(1) << "An offset requested. x:" << x_offset_ << " y:" << y_offset_;
-
} else {
DCHECK(has_element_);
// If not, calculate the half of the element size and translate by it.
gfx::Size size;
- ErrorCode code = session_->GetElementSize(session_->current_target(),
- element_, &size);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to compute element size.", code);
+ Error* error = session_->GetElementSize(session_->current_target(),
+ element_, &size);
+ if (error) {
+ response->SetError(error);
return;
}
location.Offset(size.width() / 2, size.height() / 2);
-
- VLOG(1) << "No offset requested. The element size is " << size.width()
- << "x" << size.height();
}
- VLOG(1) << "Mouse moved to: (" << location.x() << ", " << location.y() << ")";
- session_->MouseMove(location);
+ Error* error = session_->MouseMove(location);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
}
ClickCommand::ClickCommand(const std::vector<std::string>& path_segments,
@@ -271,9 +212,7 @@ bool ClickCommand::Init(Response* const response) {
return false;
if (!GetIntegerParameter("button", &button_)) {
- SET_WEBDRIVER_ERROR(response,
- "Request is missing the required button data",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Missing mouse button argument"));
return false;
}
@@ -290,11 +229,15 @@ void ClickCommand::ExecutePost(Response* const response) {
} else if (button_ == kRightButton) {
button = automation::kRightButton;
} else {
- SET_WEBDRIVER_ERROR(response, "Invalid button", kBadRequest);
+ response->SetError(new Error(kBadRequest, "Invalid mouse button"));
return;
}
- session_->MouseClick(button);
+ Error* error = session_->MouseClick(button);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
}
ButtonDownCommand::ButtonDownCommand(
@@ -326,7 +269,11 @@ DoubleClickCommand::DoubleClickCommand(
DoubleClickCommand::~DoubleClickCommand() {}
void DoubleClickCommand::ExecutePost(Response* const response) {
- session_->MouseDoubleClick();
+ Error* error = session_->MouseDoubleClick();
+ if (error) {
+ response->SetError(error);
+ return;
+ }
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/mouse_commands.h b/chrome/test/webdriver/commands/mouse_commands.h
index 4510ccf..cc6f931 100644
--- a/chrome/test/webdriver/commands/mouse_commands.h
+++ b/chrome/test/webdriver/commands/mouse_commands.h
@@ -9,11 +9,17 @@
#include <vector>
#include "chrome/test/webdriver/commands/webelement_commands.h"
+#include "chrome/test/webdriver/web_element_id.h"
class DictionaryValue;
+namespace gfx {
+class Point;
+}
+
namespace webdriver {
+class Error;
class Response;
// Base class for the following API command classes.
@@ -28,7 +34,7 @@ class ElementMouseCommand : public WebElementCommand {
virtual bool DoesPost();
virtual void ExecutePost(Response* const response);
- virtual bool Action(const gfx::Point& location, Response* const response) = 0;
+ virtual Error* Action(const gfx::Point& location) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ElementMouseCommand);
@@ -46,7 +52,7 @@ class MoveAndClickCommand : public ElementMouseCommand {
const DictionaryValue* const parameters);
virtual ~MoveAndClickCommand();
- virtual bool Action(const gfx::Point& location, Response* const response);
+ virtual Error* Action(const gfx::Point& location);
private:
DISALLOW_COPY_AND_ASSIGN(MoveAndClickCommand);
@@ -60,7 +66,7 @@ class HoverCommand : public ElementMouseCommand {
const DictionaryValue* const parameters);
virtual ~HoverCommand();
- virtual bool Action(const gfx::Point& location, Response* const response);
+ virtual Error* Action(const gfx::Point& location);
private:
DISALLOW_COPY_AND_ASSIGN(HoverCommand);
@@ -76,7 +82,7 @@ class DragCommand : public ElementMouseCommand {
virtual ~DragCommand();
virtual bool Init(Response* const response);
- virtual bool Action(const gfx::Point& location, Response* const response);
+ virtual Error* Action(const gfx::Point& location);
private:
int drag_x_, drag_y_;
diff --git a/chrome/test/webdriver/commands/navigate_commands.cc b/chrome/test/webdriver/commands/navigate_commands.cc
index ffc5396..f61ed85 100644
--- a/chrome/test/webdriver/commands/navigate_commands.cc
+++ b/chrome/test/webdriver/commands/navigate_commands.cc
@@ -1,10 +1,12 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/test/webdriver/commands/navigate_commands.h"
#include "chrome/test/webdriver/commands/response.h"
+#include "chrome/test/webdriver/session.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
@@ -19,16 +21,9 @@ bool ForwardCommand::DoesPost() {
}
void ForwardCommand::ExecutePost(Response* const response) {
- if (!session_->GoForward()) {
- SET_WEBDRIVER_ERROR(response, "GoForward failed", kInternalServerError);
- return;
- }
-
- response->SetStatus(kSuccess);
-}
-
-bool ForwardCommand::RequiresValidTab() {
- return true;
+ Error* error = session_->GoForward();
+ if (error)
+ response->SetError(error);
}
BackCommand::BackCommand(const std::vector<std::string>& path_segments,
@@ -42,16 +37,9 @@ bool BackCommand::DoesPost() {
}
void BackCommand::ExecutePost(Response* const response) {
- if (!session_->GoBack()) {
- SET_WEBDRIVER_ERROR(response, "GoBack failed", kInternalServerError);
- return;
- }
-
- response->SetStatus(kSuccess);
-}
-
-bool BackCommand::RequiresValidTab() {
- return true;
+ Error* error = session_->GoBack();
+ if (error)
+ response->SetError(error);
}
RefreshCommand::RefreshCommand(const std::vector<std::string>& path_segments,
@@ -65,16 +53,9 @@ bool RefreshCommand::DoesPost() {
}
void RefreshCommand::ExecutePost(Response* const response) {
- if (!session_->Reload()) {
- SET_WEBDRIVER_ERROR(response, "Reload failed", kInternalServerError);
- return;
- }
-
- response->SetStatus(kSuccess);
-}
-
-bool RefreshCommand::RequiresValidTab() {
- return true;
+ Error* error = session_->Reload();
+ if (error)
+ response->SetError(error);
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/navigate_commands.h b/chrome/test/webdriver/commands/navigate_commands.h
index c4960f9..a5777b22 100644
--- a/chrome/test/webdriver/commands/navigate_commands.h
+++ b/chrome/test/webdriver/commands/navigate_commands.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -26,8 +26,6 @@ class ForwardCommand : public WebDriverCommand {
virtual void ExecutePost(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(ForwardCommand);
};
@@ -43,8 +41,6 @@ class BackCommand : public WebDriverCommand {
virtual void ExecutePost(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(BackCommand);
};
@@ -60,12 +56,9 @@ class RefreshCommand : public WebDriverCommand {
virtual void ExecutePost(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(RefreshCommand);
};
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_NAVIGATE_COMMANDS_H_
-
diff --git a/chrome/test/webdriver/commands/response.cc b/chrome/test/webdriver/commands/response.cc
index bb711efa..0060fa0 100644
--- a/chrome/test/webdriver/commands/response.cc
+++ b/chrome/test/webdriver/commands/response.cc
@@ -57,49 +57,15 @@ void Response::SetValue(Value* value) {
data_.Set(kValueKey, value);
}
-void Response::SetError(ErrorCode error_code, const std::string& message,
- const std::string& file, int line) {
- DictionaryValue* error = new DictionaryValue;
- error->SetString(kMessageKey, message);
-
- DictionaryValue* stack = new DictionaryValue;
- stack->SetString(kStackTraceFileNameKey, file);
- stack->SetString(kStackTraceClassNameKey, "");
- stack->SetString(kStackTraceMethodNameKey, "");
- stack->SetInteger(kStackTraceLineNumberKey, line);
- ListValue* stack_list = new ListValue;
- stack_list->Append(stack);
- error->Set(kStackTraceKey, stack_list);
-
- SetStatus(error_code);
- SetValue(error);
-}
+void Response::SetError(Error* error) {
+ DictionaryValue* error_dict = new DictionaryValue();
+ error_dict->SetString(kMessageKey, error->ToString());
-void Response::SetError(ErrorCode error_code,
- const std::string& message,
- const std::string& file,
- int line,
- const std::string& png) {
- DictionaryValue* error = new DictionaryValue;
-
- error->SetString(kMessageKey, message);
- error->SetString(kStackTraceFileNameKey, file);
- error->SetInteger(kStackTraceLineNumberKey, line);
- std::string base64_png;
-
- // Convert the raw binary data to base 64 encoding for webdriver.
- if (!base::Base64Encode(png, &base64_png)) {
- LOG(ERROR) << "Failed to encode screenshot to base64 "
- << "sending back an empty string instead.";
- } else {
- error->SetString(kScreenKey, base64_png);
- }
-
- SetStatus(error_code);
- SetValue(error);
+ SetStatus(error->code());
+ SetValue(error_dict);
+ delete error;
}
-
void Response::SetField(const std::string& key, Value* value) {
data_.Set(key, value);
}
diff --git a/chrome/test/webdriver/commands/response.h b/chrome/test/webdriver/commands/response.h
index 678851f..9c44e60 100644
--- a/chrome/test/webdriver/commands/response.h
+++ b/chrome/test/webdriver/commands/response.h
@@ -9,23 +9,10 @@
#include <string>
#include "base/values.h"
-#include "chrome/test/webdriver/error_codes.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
-// All errors in webdriver must use this macro in order to send back
-// a proper stack trace to the client.
-#define SET_WEBDRIVER_ERROR(response, msg, err) \
- response->SetError(err, msg, __FILE__, __LINE__); \
- LOG(ERROR) << msg
-
-// Error which need to send back a screenshot should use this macro.
-// |png| needs to be a string which contains the raw binary data of
-// the PNG file.
-#define SET_WEBDRIVER_ERROR_WITH_SCREENSHOT(response, msg, err , png) \
- response->SetError(err, msg, __FILE__, __LINE__, png); \
- LOG(ERROR) << msg
-
// A simple class that encapsulates the information describing the response to
// a |Command|. In Webdriver all responses must be sent back as a JSON value,
// conforming to the spec found at:
@@ -47,21 +34,9 @@ class Response {
// process.
void SetValue(Value* value);
- // Configures this response to report an error. The |file| and |line|
- // parameters, which identify where in the source the error occurred, can be
- // set using the |SET_WEBDRIVER_ERROR| macro above.
- void SetError(ErrorCode error, const std::string& message,
- const std::string& file, int line);
-
- // Configures this response to report an error. The |file| and |line|
- // parameters, which identify where in the source the error occurred, can be
- // set using the |SET_WEBDRIVER_ERROR_WITH_SCREENSHOT| macro above. Includes
- // a screen shot of the tab which caused the error.
- void SetError(ErrorCode error,
- const std::string& message,
- const std::string& file,
- int line,
- const std::string& png);
+ // Configures this response to report the given error. Ownership of the error
+ // is taken from the caller.
+ void SetError(Error* error);
// Sets a JSON field in this response. The |key| may be a "." delimitted
// string to indicate the value should be set in a nested object. Any
@@ -81,4 +56,3 @@ class Response {
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_RESPONSE_H_
-
diff --git a/chrome/test/webdriver/commands/screenshot_command.cc b/chrome/test/webdriver/commands/screenshot_command.cc
index bec6d98..352b062 100644
--- a/chrome/test/webdriver/commands/screenshot_command.cc
+++ b/chrome/test/webdriver/commands/screenshot_command.cc
@@ -10,8 +10,8 @@
#include "base/base64.h"
#include "base/values.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/webdriver_error.h"
namespace webdriver {
@@ -27,23 +27,21 @@ bool ScreenshotCommand::DoesGet() {
void ScreenshotCommand::ExecuteGet(Response* const response) {
std::string raw_bytes;
- if (!session_->GetScreenShot(&raw_bytes)) {
- SET_WEBDRIVER_ERROR(response, "Screenshot of current page failed",
- kInternalServerError);
+ Error* error = session_->GetScreenShot(&raw_bytes);
+ if (error) {
+ response->SetError(error);
return;
}
// Convert the raw binary data to base 64 encoding for webdriver.
std::string base64_screenshot;
if (!base::Base64Encode(raw_bytes, &base64_screenshot)) {
- SET_WEBDRIVER_ERROR(response, "Encoding the PNG to base64 format failed",
- kInternalServerError);
+ response->SetError(new Error(
+ kUnknownError, "Encoding the PNG to base64 format failed"));
return;
}
response->SetValue(new StringValue(base64_screenshot));
- response->SetStatus(kSuccess);
}
} // namespace webdriver
-
diff --git a/chrome/test/webdriver/commands/session_with_id.cc b/chrome/test/webdriver/commands/session_with_id.cc
index 651a1cc..5889be4 100644
--- a/chrome/test/webdriver/commands/session_with_id.cc
+++ b/chrome/test/webdriver/commands/session_with_id.cc
@@ -11,7 +11,6 @@
#include "chrome/app/chrome_command_ids.h"
#include "chrome/common/chrome_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/session_manager.h"
@@ -56,18 +55,12 @@ void SessionWithID::ExecuteGet(Response* const response) {
temp_value->SetString("chrome.automationVersion", chrome::kChromeVersion);
temp_value->SetBoolean("chrome.nativeEvents", session_->use_native_events());
- response->SetStatus(kSuccess);
response->SetValue(temp_value);
}
void SessionWithID::ExecuteDelete(Response* const response) {
// Session manages its own lifetime, so do not call delete.
session_->Terminate();
- response->SetStatus(kSuccess);
-}
-
-bool SessionWithID::RequiresValidTab() {
- return false;
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/session_with_id.h b/chrome/test/webdriver/commands/session_with_id.h
index 4b03cda..e634c65 100644
--- a/chrome/test/webdriver/commands/session_with_id.h
+++ b/chrome/test/webdriver/commands/session_with_id.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -35,12 +35,9 @@ class SessionWithID : public WebDriverCommand {
virtual void ExecuteDelete(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(SessionWithID);
};
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_SESSION_WITH_ID_H_
-
diff --git a/chrome/test/webdriver/commands/set_timeout_commands.cc b/chrome/test/webdriver/commands/set_timeout_commands.cc
index 92f68f5..73d55aa 100644
--- a/chrome/test/webdriver/commands/set_timeout_commands.cc
+++ b/chrome/test/webdriver/commands/set_timeout_commands.cc
@@ -9,8 +9,8 @@
#include "base/stringprintf.h"
#include "base/values.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/webdriver_error.h"
namespace webdriver {
@@ -30,7 +30,7 @@ void SetTimeoutCommand::ExecutePost(Response* const response) {
const char kTimeoutMsKey[] = "ms";
if (!HasParameter(kTimeoutMsKey)) {
- SET_WEBDRIVER_ERROR(response, "Request missing ms parameter", kBadRequest);
+ response->SetError(new Error(kBadRequest, "Request missing ms parameter"));
return;
}
@@ -42,8 +42,8 @@ void SetTimeoutCommand::ExecutePost(Response* const response) {
// we are safe to downcast.
double ms;
if (!GetDoubleParameter(kTimeoutMsKey, &ms)) {
- SET_WEBDRIVER_ERROR(response, "ms parameter is not a number",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "ms parameter is not a number"));
return;
}
ms_to_wait = static_cast<int>(ms);
@@ -51,16 +51,11 @@ void SetTimeoutCommand::ExecutePost(Response* const response) {
// Validate the wait time before setting it to the session.
if (ms_to_wait < 0) {
- SET_WEBDRIVER_ERROR(
- response,
- base::StringPrintf("timeout must be non-negative: %d",
- ms_to_wait),
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Timeout must be non-negative"));
return;
}
SetTimeout(ms_to_wait);
- response->SetStatus(kSuccess);
}
SetAsyncScriptTimeoutCommand::SetAsyncScriptTimeoutCommand(
@@ -86,4 +81,3 @@ void ImplicitWaitCommand::SetTimeout(int timeout_ms) {
}
} // namespace webdriver
-
diff --git a/chrome/test/webdriver/commands/set_timeout_commands_unittest.cc b/chrome/test/webdriver/commands/set_timeout_commands_unittest.cc
index 4df283b..5bc4554 100644
--- a/chrome/test/webdriver/commands/set_timeout_commands_unittest.cc
+++ b/chrome/test/webdriver/commands/set_timeout_commands_unittest.cc
@@ -9,8 +9,8 @@
#include "base/values.h"
#include "chrome/test/webdriver/commands/set_timeout_commands.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/webdriver_error.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace webdriver {
diff --git a/chrome/test/webdriver/commands/source_command.cc b/chrome/test/webdriver/commands/source_command.cc
index 94c5e8e..7030410 100644
--- a/chrome/test/webdriver/commands/source_command.cc
+++ b/chrome/test/webdriver/commands/source_command.cc
@@ -8,8 +8,8 @@
#include "base/values.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/webdriver_error.h"
namespace webdriver {
@@ -30,15 +30,12 @@ bool SourceCommand::DoesGet() {
void SourceCommand::ExecuteGet(Response* const response) {
ListValue args;
Value* result = NULL;
- ErrorCode code = session_->ExecuteScript(kSource, &args, &result);
-
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "ExecuteAndExtractString failed",
- kInternalServerError);
+ Error* error = session_->ExecuteScript(kSource, &args, &result);
+ if (error) {
+ response->SetError(error);
return;
}
response->SetValue(result);
- response->SetStatus(kSuccess);
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/speed_command.cc b/chrome/test/webdriver/commands/speed_command.cc
deleted file mode 100644
index 9755305..0000000
--- a/chrome/test/webdriver/commands/speed_command.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/test/webdriver/commands/speed_command.h"
-
-#include <string>
-
-#include "base/utf_string_conversions.h"
-#include "chrome/test/webdriver/commands/response.h"
-
-namespace webdriver {
-
-SpeedCommand::SpeedCommand(const std::vector<std::string>& path_segments,
- const DictionaryValue* const parameters)
- : WebDriverCommand(path_segments, parameters),
- speed_(Session::kMedium) {
-}
-
-SpeedCommand::~SpeedCommand() {}
-
-bool SpeedCommand::Init(Response* const response) {
- std::string speed;
-
- if (!WebDriverCommand::Init(response)) {
- SET_WEBDRIVER_ERROR(response, "Failure on Init for setting speed",
- kInternalServerError);
- return false;
- }
-
- // The speed parameter must be passed in as SLOW, MEDIUM, or FAST.
- // The command must also be in all upper case letters.
- if (!GetStringASCIIParameter("speed", &speed)) {
- SET_WEBDRIVER_ERROR(response, "Request missing speed parameter",
- kBadRequest);
- return false;
- }
-
- if (speed.compare("SLOW") == 0) {
- LOG(INFO) << "Speed set to slow";
- speed_ = Session::kSlow;
- } else if (speed.compare("MEDIUM") == 0) {
- LOG(INFO) << "Speed set to medium";
- speed_ = Session::kMedium;
- } else if (speed.compare("FAST") == 0) {
- LOG(INFO) << "Speed set to fast" << std::endl;
- speed_ = Session::kFast;
- } else {
- // If the speed is invalid throw and error in the POST response.
- LOG(INFO) << "Requested an unknown speed: " << speed;
- speed_ = Session::kUnknown;
- }
-
- return true;
-}
-
-bool SpeedCommand::DoesGet() {
- return true;
-}
-
-bool SpeedCommand::DoesPost() {
- return true;
-}
-
-void SpeedCommand::ExecuteGet(Response* const response) {
- switch (session_->speed()) {
- case Session::kSlow:
- response->SetValue(new StringValue("SLOW"));
- response->SetStatus(kSuccess);
- break;
-
- case Session::kMedium:
- response->SetValue(new StringValue("MEDIUM"));
- response->SetStatus(kSuccess);
- break;
-
- case Session::kFast:
- response->SetValue(new StringValue("FAST"));
- response->SetStatus(kSuccess);
- break;
-
- default:
- // The speed should have never been set to unknown.
- SET_WEBDRIVER_ERROR(response, "Unknown speed set",
- kInternalServerError);
- NOTREACHED();
- break;
- }
-}
-
-void SpeedCommand::ExecutePost(Response* const response) {
- if (speed_ == Session::kUnknown) {
- SET_WEBDRIVER_ERROR(response, "Invalid speed requested",
- kInternalServerError);
- return;
- }
-
- session_->set_speed(speed_);
- response->SetValue(new StringValue("success"));
- response->SetStatus(kSuccess);
-}
-
-bool SpeedCommand::RequiresValidTab() {
- return true;
-}
-
-} // namespace webdriver
-
diff --git a/chrome/test/webdriver/commands/speed_command.h b/chrome/test/webdriver/commands/speed_command.h
deleted file mode 100644
index 9846fa5..0000000
--- a/chrome/test/webdriver/commands/speed_command.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_TEST_WEBDRIVER_COMMANDS_SPEED_COMMAND_H_
-#define CHROME_TEST_WEBDRIVER_COMMANDS_SPEED_COMMAND_H_
-
-#include <string>
-#include <vector>
-
-#include "chrome/test/webdriver/session.h"
-#include "chrome/test/webdriver/commands/webdriver_command.h"
-
-namespace webdriver {
-
-class Response;
-
-// Controls how fast chrome should simulate user typing and mouse movements.
-// By default the speed is set to medium however webdriver has not defined
-// what this speed means accross browsers. Currently speed is ignored.
-// See: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/speed
-class SpeedCommand : public WebDriverCommand {
- public:
- SpeedCommand(const std::vector<std::string>& path_segments,
- const DictionaryValue* const parameters);
- virtual ~SpeedCommand();
-
- virtual bool Init(Response* const response);
-
- virtual bool DoesGet();
- virtual bool DoesPost();
- virtual void ExecuteGet(Response* const response);
- virtual void ExecutePost(Response* const response);
-
- private:
- virtual bool RequiresValidTab();
-
- Session::Speed speed_;
-
- DISALLOW_COPY_AND_ASSIGN(SpeedCommand);
-};
-
-} // namespace webdriver
-
-#endif // CHROME_TEST_WEBDRIVER_COMMANDS_SPEED_COMMAND_H_
-
diff --git a/chrome/test/webdriver/commands/target_locator_commands.cc b/chrome/test/webdriver/commands/target_locator_commands.cc
index b0b7ff5..d738fe0 100644
--- a/chrome/test/webdriver/commands/target_locator_commands.cc
+++ b/chrome/test/webdriver/commands/target_locator_commands.cc
@@ -7,9 +7,9 @@
#include "base/string_number_conversions.h"
#include "base/values.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 "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
@@ -25,7 +25,6 @@ bool WindowHandleCommand::DoesGet() {
}
void WindowHandleCommand::ExecuteGet(Response* const response) {
- response->SetStatus(kSuccess);
response->SetValue(new StringValue(
base::IntToString(session_->current_target().window_id)));
}
@@ -43,15 +42,14 @@ bool WindowHandlesCommand::DoesGet() {
void WindowHandlesCommand::ExecuteGet(Response* const response) {
std::vector<int> window_ids;
- if (!session_->GetWindowIds(&window_ids)) {
- SET_WEBDRIVER_ERROR(
- response, "Could not get window handles", kInternalServerError);
+ Error* error = session_->GetWindowIds(&window_ids);
+ if (error) {
+ response->SetError(error);
return;
}
ListValue* id_list = new ListValue();
for (size_t i = 0; i < window_ids.size(); ++i)
id_list->Append(new StringValue(base::IntToString(window_ids[i])));
- response->SetStatus(kSuccess);
response->SetValue(id_list);
}
@@ -73,26 +71,20 @@ bool WindowCommand::DoesDelete() {
void WindowCommand::ExecutePost(Response* const response) {
std::string name;
if (!GetStringParameter("name", &name)) {
- SET_WEBDRIVER_ERROR(
- response, "Missing or invalid 'name' parameter", kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "Missing or invalid 'name' parameter"));
return;
}
- ErrorCode code = session_->SwitchToWindow(name);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Could not switch window", code);
- return;
- }
- response->SetStatus(kSuccess);
+ Error* error = session_->SwitchToWindow(name);
+ if (error)
+ response->SetError(error);
}
void WindowCommand::ExecuteDelete(Response* const response) {
- if (!session_->CloseWindow()) {
- SET_WEBDRIVER_ERROR(
- response, "Could not close window", kInternalServerError);
- return;
- }
- response->SetStatus(kSuccess);
+ Error* error = session_->CloseWindow();
+ if (error)
+ response->SetError(error);
}
SwitchFrameCommand::SwitchFrameCommand(
@@ -110,34 +102,22 @@ void SwitchFrameCommand::ExecutePost(Response* const response) {
std::string id;
int index = 0;
WebElementId element;
+ Error* error = NULL;
if (GetStringParameter("id", &id)) {
- ErrorCode code = session_->SwitchToFrameWithNameOrId(id);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Could not switch to frame", code);
- return;
- }
+ error = session_->SwitchToFrameWithNameOrId(id);
} else if (GetIntegerParameter("id", &index)) {
- ErrorCode code = session_->SwitchToFrameWithIndex(index);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Could not switch to frame", code);
- return;
- }
+ error = session_->SwitchToFrameWithIndex(index);
} else if (GetWebElementParameter("id", &element)) {
- ErrorCode code = session_->SwitchToFrameWithElement(element);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Could not switch to frame", code);
- return;
- }
+ error = session_->SwitchToFrameWithElement(element);
} else if (IsNullParameter("id") || !HasParameter("id")) {
// Treat null 'id' and no 'id' as the same.
// See http://code.google.com/p/selenium/issues/detail?id=1479.
session_->SwitchToTopFrame();
} else {
- SET_WEBDRIVER_ERROR(
- response, "Invalid 'id' parameter", kBadRequest);
- return;
+ error = new Error(kBadRequest, "Invalid 'id' parameter");
}
- response->SetStatus(kSuccess);
+ if (error)
+ response->SetError(error);
}
bool SwitchFrameCommand::GetWebElementParameter(const std::string& key,
@@ -168,9 +148,12 @@ bool ActiveElementCommand::DoesPost() {
void ActiveElementCommand::ExecutePost(Response* const response) {
ListValue args;
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(
+ Error* error = session_->ExecuteScript(
"return document.activeElement || document.body", &args, &result);
- response->SetStatus(status);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
diff --git a/chrome/test/webdriver/commands/title_command.cc b/chrome/test/webdriver/commands/title_command.cc
index a6cc20a..4898d5f 100644
--- a/chrome/test/webdriver/commands/title_command.cc
+++ b/chrome/test/webdriver/commands/title_command.cc
@@ -7,6 +7,8 @@
#include <string>
#include "chrome/test/webdriver/commands/response.h"
+#include "chrome/test/webdriver/session.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
@@ -22,14 +24,12 @@ bool TitleCommand::DoesGet() {
void TitleCommand::ExecuteGet(Response* const response) {
std::string title;
- ErrorCode code = session_->GetTitle(&title);
- if (code == kSuccess)
- response->SetValue(new StringValue(title));
- response->SetStatus(code);
-}
-
-bool TitleCommand::RequiresValidTab() {
- return true;
+ Error* error = session_->GetTitle(&title);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
+ response->SetValue(new StringValue(title));
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/title_command.h b/chrome/test/webdriver/commands/title_command.h
index 3ec5fe81..4a4723e 100644
--- a/chrome/test/webdriver/commands/title_command.h
+++ b/chrome/test/webdriver/commands/title_command.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -26,12 +26,9 @@ class TitleCommand : public WebDriverCommand {
virtual void ExecuteGet(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(TitleCommand);
};
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_TITLE_COMMAND_H_
-
diff --git a/chrome/test/webdriver/commands/url_command.cc b/chrome/test/webdriver/commands/url_command.cc
index 22efa1e..7a495d9 100644
--- a/chrome/test/webdriver/commands/url_command.cc
+++ b/chrome/test/webdriver/commands/url_command.cc
@@ -7,6 +7,8 @@
#include <string>
#include "chrome/test/webdriver/commands/response.h"
+#include "chrome/test/webdriver/session.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
@@ -26,32 +28,29 @@ bool URLCommand::DoesPost() {
void URLCommand::ExecuteGet(Response* const response) {
std::string url;
- ErrorCode code = session_->GetURL(&url);
- if (code == kSuccess)
- response->SetValue(new StringValue(url));
- response->SetStatus(code);
+ Error* error = session_->GetURL(&url);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
+ response->SetValue(new StringValue(url));
}
void URLCommand::ExecutePost(Response* const response) {
std::string url;
if (!GetStringASCIIParameter("url", &url)) {
- SET_WEBDRIVER_ERROR(response, "URL field not found", kInternalServerError);
+ response->SetError(new Error(kBadRequest, "Missing 'url' parameter"));
return;
}
- // TODO(jmikhail): sniff for meta-redirects.
- if (!session_->NavigateToURL(url)) {
- SET_WEBDRIVER_ERROR(response, "NavigateToURL failed",
- kInternalServerError);
+
+ Error* error = session_->NavigateToURL(url);
+ if (error) {
+ response->SetError(error);
return;
}
-
response->SetValue(new StringValue(url));
- response->SetStatus(kSuccess);
}
-bool URLCommand::RequiresValidTab() {
- return true;
-}
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/url_command.h b/chrome/test/webdriver/commands/url_command.h
index 0f5c1e8..075a4a8 100644
--- a/chrome/test/webdriver/commands/url_command.h
+++ b/chrome/test/webdriver/commands/url_command.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -29,12 +29,9 @@ class URLCommand : public WebDriverCommand {
virtual void ExecutePost(Response* const response);
private:
- virtual bool RequiresValidTab();
-
DISALLOW_COPY_AND_ASSIGN(URLCommand);
};
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_URL_COMMAND_H_
-
diff --git a/chrome/test/webdriver/commands/webdriver_command.cc b/chrome/test/webdriver/commands/webdriver_command.cc
index 1a30191..133b6a0 100644
--- a/chrome/test/webdriver/commands/webdriver_command.cc
+++ b/chrome/test/webdriver/commands/webdriver_command.cc
@@ -7,33 +7,51 @@
#include <string>
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/values.h"
#include "chrome/test/webdriver/commands/response.h"
+#include "chrome/test/webdriver/session.h"
#include "chrome/test/webdriver/session_manager.h"
-#include "chrome/test/webdriver/error_codes.h"
+#include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
+WebDriverCommand::WebDriverCommand(
+ const std::vector<std::string>& path_segments,
+ const DictionaryValue* const parameters)
+ : Command(path_segments, parameters), session_(NULL) {
+}
+
+WebDriverCommand::~WebDriverCommand() {}
+
bool WebDriverCommand::Init(Response* const response) {
// There should be at least 3 path segments to match "/session/$id".
std::string session_id = GetPathVariable(2);
if (session_id.length() == 0) {
- SET_WEBDRIVER_ERROR(response, "No session ID specified", kBadRequest);
+ response->SetError(
+ new Error(kBadRequest, "No session ID specified"));
return false;
}
VLOG(1) << "Fetching session: " << session_id;
session_ = SessionManager::GetInstance()->GetSession(session_id);
if (session_ == NULL) {
- SET_WEBDRIVER_ERROR(response, "Session not found: " + session_id,
- kSessionNotFound);
+ response->SetError(
+ new Error(kSessionNotFound, "Session not found: " + session_id));
return false;
}
- if (!session_->WaitForAllTabsToStopLoading()) {
- LOG(WARNING) << "Failed to wait for all tabs to stop loading";
+
+ // TODO(kkania): Do not use the standard automation timeout for this,
+ // and throw an error if it does not succeed.
+ scoped_ptr<Error> error(session_->WaitForAllTabsToStopLoading());
+ if (error.get()) {
+ LOG(WARNING) << error->ToString();
+ }
+ error.reset(session_->SwitchToTopFrameIfCurrentFrameInvalid());
+ if (error.get()) {
+ LOG(WARNING) << error->ToString();
}
- session_->SwitchToTopFrameIfCurrentFrameInvalid();
response->SetField("sessionId", Value::CreateStringValue(session_id));
return true;
diff --git a/chrome/test/webdriver/commands/webdriver_command.h b/chrome/test/webdriver/commands/webdriver_command.h
index 633a02d..c4e759d 100644
--- a/chrome/test/webdriver/commands/webdriver_command.h
+++ b/chrome/test/webdriver/commands/webdriver_command.h
@@ -9,13 +9,13 @@
#include <vector>
#include "chrome/test/webdriver/commands/command.h"
-#include "chrome/test/webdriver/session.h"
class DictionaryValue;
namespace webdriver {
class Response;
+class Session;
// All URLs that are found in the document:
// http://code.google.com/p/selenium/wiki/JsonWireProtocol
@@ -25,10 +25,9 @@ class Response;
// directly.
class WebDriverCommand : public Command {
public:
- WebDriverCommand(const std::vector<std::string> path_segments,
- const DictionaryValue* const parameters)
- : Command(path_segments, parameters), session_(NULL) {}
- virtual ~WebDriverCommand() {}
+ WebDriverCommand(const std::vector<std::string>& path_segments,
+ const DictionaryValue* const parameters);
+ virtual ~WebDriverCommand();
// Initializes this webdriver command by fetching the command session.
virtual bool Init(Response* const response);
diff --git a/chrome/test/webdriver/commands/webelement_commands.cc b/chrome/test/webdriver/commands/webelement_commands.cc
index de68aef..dae3e4eb 100644
--- a/chrome/test/webdriver/commands/webelement_commands.cc
+++ b/chrome/test/webdriver/commands/webelement_commands.cc
@@ -9,8 +9,8 @@
#include "base/third_party/icu/icu_utf.h"
#include "base/values.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/webdriver_error.h"
#include "third_party/webdriver/atoms.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
@@ -34,8 +34,7 @@ bool WebElementCommand::Init(Response* const response) {
// There should be at least 5 segments to match
// "/session/$session/element/$id"
if (path_segments_.size() < 5) {
- SET_WEBDRIVER_ERROR(response, "Path segments is less than 5",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Path segments is less than 5"));
return false;
}
@@ -62,21 +61,23 @@ void ElementAttributeCommand::ExecuteGet(Response* const response) {
// There should be at least 7 segments to match
// "/session/$session/element/$id/attribute/$name"
if (path_segments_.size() < 7) {
- SET_WEBDRIVER_ERROR(response, "Path segments is less than 7",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
return;
}
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE);
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
- args->Append(Value::CreateStringValue(path_segments_.at(6)));
+ ListValue args;
+ args.Append(element.ToValue());
+ args.Append(Value::CreateStringValue(path_segments_.at(6)));
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -94,15 +95,18 @@ bool ElementClearCommand::DoesPost() {
}
void ElementClearCommand::ExecutePost(Response* const response) {
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
+ ListValue args;
+ args.Append(element.ToValue());
std::string script = base::StringPrintf(
"(%s).apply(null, arguments);", atoms::CLEAR);
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -123,21 +127,23 @@ void ElementCssCommand::ExecuteGet(Response* const response) {
// There should be at least 7 segments to match
// "/session/$session/element/$id/css/$propertyName"
if (path_segments_.size() < 7) {
- SET_WEBDRIVER_ERROR(response, "Path segments is less than 7",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
return;
}
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::GET_EFFECTIVE_STYLE);
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
- args->Append(Value::CreateStringValue(path_segments_.at(6)));
+ ListValue args;
+ args.Append(element.ToValue());
+ args.Append(Value::CreateStringValue(path_segments_.at(6)));
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -156,11 +162,13 @@ bool ElementDisplayedCommand::DoesGet() {
void ElementDisplayedCommand::ExecuteGet(Response* const response) {
bool is_displayed;
- ErrorCode status = session_->IsElementDisplayed(
+ Error* error = session_->IsElementDisplayed(
session_->current_target(), element, &is_displayed);
- if (status == kSuccess)
- response->SetValue(Value::CreateBooleanValue(is_displayed));
- response->SetStatus(status);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
+ response->SetValue(Value::CreateBooleanValue(is_displayed));
}
///////////////////// ElementEnabledCommand ////////////////////
@@ -177,15 +185,18 @@ bool ElementEnabledCommand::DoesGet() {
}
void ElementEnabledCommand::ExecuteGet(Response* const response) {
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
+ ListValue args;
+ args.Append(element.ToValue());
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::IS_ENABLED);
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -206,22 +217,24 @@ void ElementEqualsCommand::ExecuteGet(Response* const response) {
// There should be at least 7 segments to match
// "/session/$session/element/$id/equals/$other"
if (path_segments_.size() < 7) {
- SET_WEBDRIVER_ERROR(response, "Path segments is less than 7",
- kBadRequest);
+ response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
return;
}
std::string script = "return arguments[0] == arguments[1];";
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
+ ListValue args;
+ args.Append(element.ToValue());
WebElementId other_element(path_segments_.at(6));
- args->Append(other_element.ToValue());
+ args.Append(other_element.ToValue());
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -246,8 +259,11 @@ void ElementLocationCommand::ExecuteGet(Response* const response) {
args.Append(element.ToValue());
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, &args, &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -266,14 +282,15 @@ bool ElementLocationInViewCommand::DoesGet() {
void ElementLocationInViewCommand::ExecuteGet(Response* const response) {
gfx::Point location;
- ErrorCode code = session_->GetElementLocationInView(element, &location);
- response->SetStatus(code);
- if (code == kSuccess) {
- DictionaryValue* coord_dict = new DictionaryValue();
- coord_dict->SetInteger("x", location.x());
- coord_dict->SetInteger("y", location.y());
- response->SetValue(coord_dict);
+ Error* error = session_->GetElementLocationInView(element, &location);
+ if (error) {
+ response->SetError(error);
+ return;
}
+ DictionaryValue* coord_dict = new DictionaryValue();
+ coord_dict->SetInteger("x", location.x());
+ coord_dict->SetInteger("y", location.y());
+ response->SetValue(coord_dict);
}
///////////////////// ElementNameCommand ////////////////////
@@ -290,14 +307,17 @@ bool ElementNameCommand::DoesGet() {
}
void ElementNameCommand::ExecuteGet(Response* const response) {
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
+ ListValue args;
+ args.Append(element.ToValue());
std::string script = "return arguments[0].tagName.toLocaleLowerCase();";
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -319,29 +339,35 @@ bool ElementSelectedCommand::DoesPost() {
}
void ElementSelectedCommand::ExecuteGet(Response* const response) {
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
+ ListValue args;
+ args.Append(element.ToValue());
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::IS_SELECTED);
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
void ElementSelectedCommand::ExecutePost(Response* const response) {
- scoped_ptr<ListValue> args(new ListValue);
- args->Append(element.ToValue());
- args->Append(Value::CreateBooleanValue(true));
+ ListValue args;
+ args.Append(element.ToValue());
+ args.Append(Value::CreateBooleanValue(true));
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::SET_SELECTED);
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, args.get(), &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -360,15 +386,16 @@ bool ElementSizeCommand::DoesGet() {
void ElementSizeCommand::ExecuteGet(Response* const response) {
gfx::Size size;
- ErrorCode status = session_->GetElementSize(
+ Error* error = session_->GetElementSize(
session_->current_target(), element, &size);
- if (status == kSuccess) {
- DictionaryValue* dict = new DictionaryValue();
- dict->SetInteger("width", size.width());
- dict->SetInteger("height", size.height());
- response->SetValue(dict);
+ if (error) {
+ response->SetError(error);
+ return;
}
- response->SetStatus(status);
+ DictionaryValue* dict = new DictionaryValue();
+ dict->SetInteger("width", size.width());
+ dict->SetInteger("height", size.height());
+ response->SetValue(dict);
}
///////////////////// ElementSubmitCommand ////////////////////
@@ -394,8 +421,11 @@ void ElementSubmitCommand::ExecutePost(Response* const response) {
args.Append(element.ToValue());
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, &args, &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -420,8 +450,11 @@ void ElementToggleCommand::ExecutePost(Response* const response) {
args.Append(element.ToValue());
Value* result = NULL;
- ErrorCode status = session_->ExecuteScript(script, &args, &result);
- response->SetStatus(status);
+ Error* error = session_->ExecuteScript(script, &args, &result);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
response->SetValue(result);
}
@@ -447,30 +480,28 @@ void ElementValueCommand::ExecuteGet(Response* const response) {
ListValue args;
std::string script = "return arguments[0]['value']";
args.Append(element.ToValue());
- ErrorCode code =
+
+ Error* error =
session_->ExecuteScript(script, &args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to execute script", code);
+ if (error) {
+ response->SetError(error);
return;
}
if (!result->IsType(Value::TYPE_STRING) &&
!result->IsType(Value::TYPE_NULL)) {
- SET_WEBDRIVER_ERROR(response,
- "Result is not string or null type",
- kInternalServerError);
+ response->SetError(new Error(
+ kUnknownError, "Result is not string or null type"));
return;
}
- response->SetStatus(kSuccess);
response->SetValue(result.release());
}
void ElementValueCommand::ExecutePost(Response* const response) {
ListValue* key_list;
if (!GetListParameter("value", &key_list)) {
- SET_WEBDRIVER_ERROR(response,
- "Missing or invalid 'value' parameter",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "Missing or invalid 'value' parameter"));
return;
}
// Flatten the given array of strings into one.
@@ -480,24 +511,17 @@ void ElementValueCommand::ExecutePost(Response* const response) {
key_list->GetString(i, &keys_list_part);
for (size_t j = 0; j < keys_list_part.size(); ++j) {
if (CBU16_IS_SURROGATE(keys_list_part[j])) {
- SET_WEBDRIVER_ERROR(
- response,
- "ChromeDriver only supports characters in the BMP",
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest, "ChromeDriver only supports characters in the BMP"));
return;
}
}
keys.append(keys_list_part);
}
- ErrorCode code = session_->SendKeys(element, keys);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response,
- "Internal SendKeys error",
- code);
- return;
- }
- response->SetStatus(kSuccess);
+ Error* error = session_->SendKeys(element, keys);
+ if (error)
+ response->SetError(error);
}
///////////////////// ElementTextCommand ////////////////////
@@ -521,20 +545,17 @@ void ElementTextCommand::ExecuteGet(Response* const response) {
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::GET_TEXT);
- ErrorCode code = session_->ExecuteScript(script, &args,
- &unscoped_result);
+ Error* error = session_->ExecuteScript(script, &args,
+ &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess) {
- SET_WEBDRIVER_ERROR(response, "Failed to execute script", code);
+ if (error) {
+ response->SetError(error);
return;
}
if (!result->IsType(Value::TYPE_STRING)) {
- SET_WEBDRIVER_ERROR(response,
- "Result is not string type",
- kInternalServerError);
+ response->SetError(new Error(kUnknownError, "Result is not string type"));
return;
}
- response->SetStatus(kSuccess);
response->SetValue(result.release());
}
diff --git a/chrome/test/webdriver/dispatch.cc b/chrome/test/webdriver/dispatch.cc
index 29176c8..f1bfb77 100644
--- a/chrome/test/webdriver/dispatch.cc
+++ b/chrome/test/webdriver/dispatch.cc
@@ -229,9 +229,9 @@ bool ParseRequestInfo(const struct mg_request_info* const request_info,
std::string json(request_info->post_data, request_info->post_data_len);
std::string error;
if (!ParseJSONDictionary(json, parameters, &error)) {
- SET_WEBDRIVER_ERROR(response,
- "Failed to parse command data: " + error + "\n Data: " + json,
- kBadRequest);
+ response->SetError(new Error(
+ kBadRequest,
+ "Failed to parse command data: " + error + "\n Data: " + json));
return false;
}
}
diff --git a/chrome/test/webdriver/error_codes.h b/chrome/test/webdriver/error_codes.h
deleted file mode 100644
index 78060f8..0000000
--- a/chrome/test/webdriver/error_codes.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_TEST_WEBDRIVER_ERROR_CODES_H_
-#define CHROME_TEST_WEBDRIVER_ERROR_CODES_H_
-
-namespace webdriver {
-// These are the error codes defined in the WebDriver wire protcol. For more
-// information, see:
-// http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes
-enum ErrorCode {
- kSuccess = 0,
- kNoSuchElement = 7,
- kNoSuchFrame = 8,
- kUnknownCommand = 9,
- kStaleElementReference = 10,
- kElementNotVisible = 11,
- kInvalidElementState = 12,
- kUnknownError = 13,
- kElementNotSelectable = 15,
- kXPathLookupError = 19,
- kNoSuchWindow = 23,
- kInvalidCookieDomain = 24,
- kUnableToSetCookie = 25,
-
- // Non-standard error codes.
- kBrowserCouldNotBeFound = 50,
- kBrowserFailedToStart,
- kIncompatibleBrowserVersion,
-
- // HTTP status codes.
- kSeeOther = 303,
- kBadRequest = 400,
- kSessionNotFound = 404,
- kMethodNotAllowed = 405,
- kInternalServerError = 500,
-};
-
-} // namespace webdriver
-
-#endif // CHROME_TEST_WEBDRIVER_ERROR_CODES_H_
diff --git a/chrome/test/webdriver/server.cc b/chrome/test/webdriver/server.cc
index 8c76823..a87bbf6 100644
--- a/chrome/test/webdriver/server.cc
+++ b/chrome/test/webdriver/server.cc
@@ -28,7 +28,6 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/webdriver/dispatch.h"
-#include "chrome/test/webdriver/error_codes.h"
#include "chrome/test/webdriver/session_manager.h"
#include "chrome/test/webdriver/utility_functions.h"
#include "chrome/test/webdriver/commands/alert_commands.h"
@@ -43,7 +42,6 @@
#include "chrome/test/webdriver/commands/session_with_id.h"
#include "chrome/test/webdriver/commands/set_timeout_commands.h"
#include "chrome/test/webdriver/commands/source_command.h"
-#include "chrome/test/webdriver/commands/speed_command.h"
#include "chrome/test/webdriver/commands/target_locator_commands.h"
#include "chrome/test/webdriver/commands/title_command.h"
#include "chrome/test/webdriver/commands/url_command.h"
@@ -138,7 +136,6 @@ void InitCallbacks(struct mg_context* ctx, Dispatcher* dispatcher,
dispatcher->Add<SwitchFrameCommand>( "/session/*/frame");
dispatcher->Add<RefreshCommand>( "/session/*/refresh");
dispatcher->Add<SourceCommand>( "/session/*/source");
- dispatcher->Add<SpeedCommand>( "/session/*/speed");
dispatcher->Add<TitleCommand>( "/session/*/title");
dispatcher->Add<URLCommand>( "/session/*/url");
dispatcher->Add<WindowCommand>( "/session/*/window");
diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc
index c543429..780f970 100644
--- a/chrome/test/webdriver/session.cc
+++ b/chrome/test/webdriver/session.cc
@@ -32,6 +32,7 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_json_requests.h"
+#include "chrome/test/webdriver/webdriver_error.h"
#include "chrome/test/webdriver/session_manager.h"
#include "chrome/test/webdriver/utility_functions.h"
#include "chrome/test/webdriver/webdriver_key_converter.h"
@@ -70,24 +71,23 @@ Session::~Session() {
SessionManager::GetInstance()->Remove(id_);
}
-ErrorCode Session::Init(const FilePath& browser_exe,
- const CommandLine& options) {
+Error* Session::Init(const FilePath& browser_exe,
+ const CommandLine& options) {
if (!thread_.Start()) {
- LOG(ERROR) << "Cannot start session thread";
delete this;
- return kUnknownError;
+ return new Error(kUnknownError, "Cannot start session thread");
}
- ErrorCode code = kUnknownError;
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
this,
&Session::InitOnSessionThread,
browser_exe,
options,
- &code));
- if (code != kSuccess)
+ &error));
+ if (error)
Terminate();
- return code;
+ return error;
}
void Session::Terminate() {
@@ -97,10 +97,10 @@ void Session::Terminate() {
delete this;
}
-ErrorCode Session::ExecuteScript(const FrameId& frame_id,
- const std::string& script,
- const ListValue* const args,
- Value** value) {
+Error* Session::ExecuteScript(const FrameId& frame_id,
+ const std::string& script,
+ const ListValue* const args,
+ Value** value) {
std::string args_as_json;
base::JSONWriter::Write(static_cast<const Value* const>(args),
/*pretty_print=*/false,
@@ -117,16 +117,16 @@ ErrorCode Session::ExecuteScript(const FrameId& frame_id,
return ExecuteScriptAndParseResponse(frame_id, jscript, value);
}
-ErrorCode Session::ExecuteScript(const std::string& script,
- const ListValue* const args,
- Value** value) {
+Error* Session::ExecuteScript(const std::string& script,
+ const ListValue* const args,
+ Value** value) {
return ExecuteScript(current_target_, script, args, value);
}
-ErrorCode Session::ExecuteAsyncScript(const FrameId& frame_id,
- const std::string& script,
- const ListValue* const args,
- Value** value) {
+Error* Session::ExecuteAsyncScript(const FrameId& frame_id,
+ const std::string& script,
+ const ListValue* const args,
+ Value** value) {
std::string args_as_json;
base::JSONWriter::Write(static_cast<const Value* const>(args),
/*pretty_print=*/false,
@@ -148,118 +148,111 @@ ErrorCode Session::ExecuteAsyncScript(const FrameId& frame_id,
return ExecuteScriptAndParseResponse(frame_id, jscript, value);
}
-ErrorCode Session::SendKeys(const WebElementId& element, const string16& keys) {
+Error* Session::SendKeys(const WebElementId& element, const string16& keys) {
bool is_displayed = false;
- ErrorCode code = IsElementDisplayed(current_target_, element, &is_displayed);
- if (code != kSuccess)
- return code;
+ Error* error = IsElementDisplayed(current_target_, element, &is_displayed);
+ if (error)
+ return error;
if (!is_displayed)
- return kElementNotVisible;
+ return new Error(kElementNotVisible);
bool is_enabled = false;
- code = IsElementEnabled(current_target_, element, &is_enabled);
- if (code != kSuccess) {
- LOG(ERROR) << "Failed to determine if element is enabled";
- return code;
- }
+ error = IsElementEnabled(current_target_, element, &is_enabled);
+ if (error)
+ return error;
if (!is_enabled)
- return kInvalidElementState;
+ return new Error(kInvalidElementState);
ListValue args;
args.Append(element.ToValue());
// This method will first check if the element we want to send the keys to is
// already focused, if not it will try to focus on it first.
// TODO(jleyba): Update this to use the correct atom.
- std::string script = "if(document.activeElement!=arguments[0]){"
+ std::string script = "if(document.activeElement != arguments[0]) {"
" if(document.activeElement)"
" document.activeElement.blur();"
" arguments[0].focus();"
"}";
Value* unscoped_result = NULL;
- code = ExecuteScript(script, &args, &unscoped_result);
- if (code != kSuccess) {
- LOG(ERROR) << "Failed to get or set focus element before sending keys";
- return code;
+ error = ExecuteScript(script, &args, &unscoped_result);
+ if (error) {
+ error->AddDetails("Failed to focus element before sending keys");
+ return error;
}
- bool success = false;
+ error = NULL;
RunSessionTask(NewRunnableMethod(
this,
&Session::SendKeysOnSessionThread,
keys,
- &success));
- if (!success)
- return kUnknownError;
- return kSuccess;
+ &error));
+ return error;
}
-bool Session::NavigateToURL(const std::string& url) {
- bool success = false;
+Error* Session::NavigateToURL(const std::string& url) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::NavigateToURL,
current_target_.window_id,
url,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::GoForward() {
- bool success = false;
+Error* Session::GoForward() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::GoForward,
current_target_.window_id,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::GoBack() {
- bool success = false;
+Error* Session::GoBack() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::GoBack,
current_target_.window_id,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::Reload() {
- bool success = false;
+Error* Session::Reload() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::Reload,
current_target_.window_id,
- &success));
- return success;
+ &error));
+ return error;
}
-ErrorCode Session::GetURL(std::string* url) {
+Error* Session::GetURL(std::string* url) {
ListValue no_args;
Value* unscoped_value = NULL;
- ErrorCode code = ExecuteScript(current_target_,
- "return document.URL;",
- &no_args,
- &unscoped_value);
+ Error* error = ExecuteScript(current_target_,
+ "return document.URL;",
+ &no_args,
+ &unscoped_value);
scoped_ptr<Value> value(unscoped_value);
- if (code != kSuccess)
- return code;
- if (!value->GetAsString(url)) {
- LOG(ERROR) << "Script returned non-string type";
- return kUnknownError;
- }
- return kSuccess;
+ if (error)
+ return error;
+ if (!value->GetAsString(url))
+ return new Error(kUnknownError, "GetURL Script returned non-string");
+ return NULL;
}
-ErrorCode Session::GetURL(GURL* url) {
+Error* Session::GetURL(GURL* url) {
std::string url_spec;
- ErrorCode code = GetURL(&url_spec);
- if (code == kSuccess) {
+ Error* error = GetURL(&url_spec);
+ if (!error)
*url = GURL(url_spec);
- }
- return code;
+ return error;
}
-ErrorCode Session::GetTitle(std::string* tab_title) {
+Error* Session::GetTitle(std::string* tab_title) {
std::string script =
"if (document.title)"
" return document.title;"
@@ -268,117 +261,115 @@ ErrorCode Session::GetTitle(std::string* tab_title) {
ListValue no_args;
Value* unscoped_value = NULL;
- ErrorCode code = ExecuteScript(current_target_,
- script,
- &no_args,
- &unscoped_value);
+ Error* error = ExecuteScript(current_target_,
+ script,
+ &no_args,
+ &unscoped_value);
scoped_ptr<Value> value(unscoped_value);
- if (code != kSuccess)
- return code;
- if (!value->GetAsString(tab_title)) {
- LOG(ERROR) << "Script returned non-string type";
- return kUnknownError;
- }
- return kSuccess;
+ if (error)
+ return error;
+ if (!value->GetAsString(tab_title))
+ return new Error(kUnknownError, "GetTitle script returned non-string");
+ return NULL;
}
-bool Session::MouseMoveAndClick(const gfx::Point& location,
- automation::MouseButton button) {
- bool success = false;
+Error* Session::MouseMoveAndClick(const gfx::Point& location,
+ automation::MouseButton button) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseClick,
current_target_.window_id,
location,
button,
- &success));
- if (success)
+ &error));
+ if (!error)
mouse_position_ = location;
- return success;
+ return error;
}
-bool Session::MouseMove(const gfx::Point& location) {
- bool success = false;
+Error* Session::MouseMove(const gfx::Point& location) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseMove,
current_target_.window_id,
location,
- &success));
- if (success)
+ &error));
+ if (!error)
mouse_position_ = location;
- return success;
+ return error;
}
-bool Session::MouseDrag(const gfx::Point& start,
- const gfx::Point& end) {
- bool success = false;
+Error* Session::MouseDrag(const gfx::Point& start,
+ const gfx::Point& end) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseDrag,
current_target_.window_id,
start,
end,
- &success));
- if (success)
+ &error));
+ if (!error)
mouse_position_ = end;
- return success;
+ return error;
}
-bool Session::MouseClick(automation::MouseButton button) {
- bool success = false;
+Error* Session::MouseClick(automation::MouseButton button) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseClick,
current_target_.window_id,
mouse_position_,
button,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::MouseButtonDown() {
- bool success = false;
+Error* Session::MouseButtonDown() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseButtonDown,
current_target_.window_id,
mouse_position_,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::MouseButtonUp() {
- bool success = false;
+Error* Session::MouseButtonUp() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseButtonUp,
current_target_.window_id,
mouse_position_,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::MouseDoubleClick() {
- bool success = false;
+Error* Session::MouseDoubleClick() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::MouseDoubleClick,
current_target_.window_id,
mouse_position_,
- &success));
- return success;
+ &error));
+ return error;
}
-bool Session::GetCookies(const std::string& url, ListValue** cookies) {
- bool success = false;
+Error* Session::GetCookies(const std::string& url, ListValue** cookies) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::GetCookies,
url,
cookies,
- &success));
- return success;
+ &error));
+ return error;
}
bool Session::GetCookiesDeprecated(const GURL& url, std::string* cookies) {
@@ -412,16 +403,16 @@ bool Session::GetCookieByNameDeprecated(const GURL& url,
return true;
}
-bool Session::DeleteCookie(const std::string& url,
+Error* Session::DeleteCookie(const std::string& url,
const std::string& cookie_name) {
- bool success = false;
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::DeleteCookie,
url,
cookie_name,
- &success));
- return success;
+ &error));
+ return error;
}
bool Session::DeleteCookieDeprecated(const GURL& url,
@@ -437,15 +428,16 @@ bool Session::DeleteCookieDeprecated(const GURL& url,
return success;
}
-bool Session::SetCookie(const std::string& url, DictionaryValue* cookie_dict) {
- bool success = false;
+Error* Session::SetCookie(const std::string& url,
+ DictionaryValue* cookie_dict) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::SetCookie,
url,
cookie_dict,
- &success));
- return success;
+ &error));
+ return error;
}
bool Session::SetCookieDeprecated(const GURL& url, const std::string& cookie) {
@@ -460,51 +452,52 @@ bool Session::SetCookieDeprecated(const GURL& url, const std::string& cookie) {
return success;
}
-bool Session::GetWindowIds(std::vector<int>* window_ids) {
- bool success = false;
+Error* Session::GetWindowIds(std::vector<int>* window_ids) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::GetTabIds,
window_ids,
- &success));
- return success;
+ &error));
+ return error;
}
-ErrorCode Session::SwitchToWindow(const std::string& name) {
+Error* Session::SwitchToWindow(const std::string& name) {
int switch_to_id = 0;
int name_no = 0;
if (base::StringToInt(name, &name_no)) {
- bool success = false;
+ Error* error = NULL;
bool does_exist = false;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::DoesTabExist,
name_no,
&does_exist,
- &success));
- if (!success) {
- LOG(ERROR) << "Unable to determine if window exists";
- return kUnknownError;
- }
+ &error));
+ if (error)
+ return error;
if (does_exist)
switch_to_id = name_no;
}
if (!switch_to_id) {
std::vector<int> window_ids;
- GetWindowIds(&window_ids);
+ Error* error = GetWindowIds(&window_ids);
+ if (error)
+ return error;
// See if any of the window names match |name|.
for (size_t i = 0; i < window_ids.size(); ++i) {
ListValue empty_list;
Value* unscoped_name_value;
std::string window_name;
- ErrorCode code = ExecuteScript(FrameId(window_ids[i], FramePath()),
- "return window.name;",
- &empty_list,
- &unscoped_name_value);
+ Error* error = ExecuteScript(FrameId(window_ids[i], FramePath()),
+ "return window.name;",
+ &empty_list,
+ &unscoped_name_value);
scoped_ptr<Value> name_value(unscoped_name_value);
- if (code == kSuccess &&
- name_value->GetAsString(&window_name) &&
+ if (error)
+ return error;
+ if (name_value->GetAsString(&window_name) &&
name == window_name) {
switch_to_id = window_ids[i];
break;
@@ -513,12 +506,12 @@ ErrorCode Session::SwitchToWindow(const std::string& name) {
}
if (!switch_to_id)
- return kNoSuchWindow;
+ return new Error(kNoSuchWindow);
current_target_ = FrameId(switch_to_id, FramePath());
- return kSuccess;
+ return NULL;
}
-ErrorCode Session::SwitchToFrameWithNameOrId(const std::string& name_or_id) {
+Error* Session::SwitchToFrameWithNameOrId(const std::string& name_or_id) {
std::string script =
"var arg = arguments[0];"
"var xpath = '(/html/body//iframe|/html/frameset/frame)';"
@@ -537,7 +530,7 @@ ErrorCode Session::SwitchToFrameWithNameOrId(const std::string& name_or_id) {
return SwitchToFrameWithJavaScriptLocatedFrame(script, &args);
}
-ErrorCode Session::SwitchToFrameWithIndex(int index) {
+Error* Session::SwitchToFrameWithIndex(int index) {
// We cannot simply index into window.frames because we need to know the
// tagName of the frameElement. If child frame N is from another domain, then
// the following will run afoul of the same origin policy:
@@ -562,7 +555,7 @@ ErrorCode Session::SwitchToFrameWithIndex(int index) {
return SwitchToFrameWithJavaScriptLocatedFrame(script, &args);
}
-ErrorCode Session::SwitchToFrameWithElement(const WebElementId& element) {
+Error* Session::SwitchToFrameWithElement(const WebElementId& element) {
// TODO(jleyba): Extract this, and the other frame switch methods to an atom.
std::string script =
"var element = arguments[0];"
@@ -590,12 +583,12 @@ void Session::SwitchToTopFrame() {
current_target_.frame_path = FramePath();
}
-void Session::SwitchToTopFrameIfCurrentFrameInvalid() {
+Error* Session::SwitchToTopFrameIfCurrentFrameInvalid() {
std::vector<std::string> components;
current_target_.frame_path.GetComponents(&components);
if (frame_elements_.size() != components.size()) {
- LOG(ERROR) << "Frame element vector out of sync with frame path";
- return;
+ return new Error(kUnknownError,
+ "Frame element vector out of sync with frame path");
}
FramePath frame_path;
Value* unscoped_value;
@@ -607,31 +600,32 @@ void Session::SwitchToTopFrameIfCurrentFrameInvalid() {
FrameId frame_id(current_target_.window_id, frame_path);
ListValue args;
args.Append(frame_elements_[i].ToValue());
- ErrorCode code = ExecuteScript(
- frame_id, "", &args, &unscoped_value);
+ scoped_ptr<Error> error(ExecuteScript(
+ frame_id, "", &args, &unscoped_value));
scoped_ptr<Value> value(unscoped_value);
- if (code == kStaleElementReference) {
+ if (error.get() && error->code() == kStaleElementReference) {
SwitchToTopFrame();
- } else if (code != kSuccess) {
- LOG(WARNING) << "Unable to determine if target frame should be reset";
- return;
+ } else if (error.get()) {
+ return error.release();
}
frame_path = frame_path.Append(components[i]);
}
+ return NULL;
}
-bool Session::CloseWindow() {
- bool success = false;
+Error* Session::CloseWindow() {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::CloseTab,
current_target_.window_id,
- &success));
+ &error));
- if (success) {
+ if (!error) {
std::vector<int> window_ids;
- if (!GetWindowIds(&window_ids) || window_ids.empty()) {
+ scoped_ptr<Error> error(GetWindowIds(&window_ids));
+ if (error.get() || window_ids.empty()) {
// The automation connection will soon be closed, if not already,
// because we supposedly just closed the last window. Terminate the
// session.
@@ -641,47 +635,47 @@ bool Session::CloseWindow() {
Terminate();
}
}
- return success;
+ return error;
}
-ErrorCode Session::GetAlertMessage(std::string* text) {
- bool success = false;
+Error* Session::GetAlertMessage(std::string* text) {
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::GetAppModalDialogMessage,
text,
- &success));
- return success ? kSuccess : kUnknownError;
+ &error));
+ return error;
}
-ErrorCode Session::SetAlertPromptText(const std::string& alert_prompt_text) {
+Error* Session::SetAlertPromptText(const std::string& alert_prompt_text) {
std::string message_text;
// Only set the alert prompt text if an alert is actually active.
- ErrorCode code = GetAlertMessage(&message_text);
- if (code == kSuccess) {
+ Error* error = GetAlertMessage(&message_text);
+ if (!error) {
has_alert_prompt_text_ = true;
alert_prompt_text_ = alert_prompt_text;
}
- return code;
+ return error;
}
-ErrorCode Session::AcceptOrDismissAlert(bool accept) {
- bool success = false;
+Error* Session::AcceptOrDismissAlert(bool accept) {
+ Error* error = NULL;
if (accept && has_alert_prompt_text_) {
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::AcceptPromptAppModalDialog,
alert_prompt_text_,
- &success));
+ &error));
} else {
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::AcceptOrDismissAppModalDialog,
accept,
- &success));
+ &error));
}
has_alert_prompt_text_ = false;
- return success ? kSuccess : kUnknownError;
+ return error;
}
std::string Session::GetBrowserVersion() {
@@ -693,18 +687,21 @@ std::string Session::GetBrowserVersion() {
return version;
}
-bool Session::CompareBrowserVersion(int client_build_no,
- int client_patch_no,
- bool* is_newer_or_equal) {
+Error* Session::CompareBrowserVersion(int client_build_no,
+ int client_patch_no,
+ bool* is_newer_or_equal) {
std::string version = GetBrowserVersion();
std::vector<std::string> split_version;
base::SplitString(version, '.', &split_version);
- if (split_version.size() != 4)
- return false;
+ if (split_version.size() != 4) {
+ return new Error(
+ kUnknownError, "Browser version has unrecognized format: " + version);
+ }
int build_no, patch_no;
if (!base::StringToInt(split_version[2], &build_no) ||
!base::StringToInt(split_version[3], &patch_no)) {
- return false;
+ return new Error(
+ kUnknownError, "Browser version has unrecognized format: " + version);
}
if (build_no < client_build_no)
*is_newer_or_equal = false;
@@ -712,46 +709,57 @@ bool Session::CompareBrowserVersion(int client_build_no,
*is_newer_or_equal = true;
else
*is_newer_or_equal = patch_no >= client_patch_no;
- return true;
+ return NULL;
}
-ErrorCode Session::FindElement(const FrameId& frame_id,
- const WebElementId& root_element,
- const std::string& locator,
- const std::string& query,
- WebElementId* element) {
+Error* Session::FindElement(const FrameId& frame_id,
+ const WebElementId& root_element,
+ const std::string& locator,
+ const std::string& query,
+ WebElementId* element) {
std::vector<WebElementId> elements;
- ErrorCode code = FindElementsHelper(
+ Error* error = FindElementsHelper(
frame_id, root_element, locator, query, true, &elements);
- if (code == kSuccess)
+ if (!error)
*element = elements[0];
- return code;
+ return error;
}
-ErrorCode Session::FindElements(const FrameId& frame_id,
- const WebElementId& root_element,
- const std::string& locator,
- const std::string& query,
- std::vector<WebElementId>* elements) {
+Error* Session::FindElements(const FrameId& frame_id,
+ const WebElementId& root_element,
+ const std::string& locator,
+ const std::string& query,
+ std::vector<WebElementId>* elements) {
return FindElementsHelper(
frame_id, root_element, locator, query, false, elements);
}
-ErrorCode Session::GetElementLocationInView(
+Error* Session::CheckElementPreconditionsForClicking(
+ const WebElementId& element) {
+ bool is_displayed = false;
+ Error* error = IsElementDisplayed(current_target_, element, &is_displayed);
+ if (error)
+ return error;
+ if (!is_displayed)
+ return new Error(kElementNotVisible, "Element must be displayed");
+ return NULL;
+}
+
+Error* Session::GetElementLocationInView(
const WebElementId& element, gfx::Point* location) {
CHECK(element.is_valid());
gfx::Size elem_size;
- ErrorCode code = GetElementSize(current_target_, element, &elem_size);
- if (code != kSuccess)
- return code;
+ Error* error = GetElementSize(current_target_, element, &elem_size);
+ if (error)
+ return error;
gfx::Point elem_offset(0, 0);
- code = GetLocationInViewHelper(
+ error = GetLocationInViewHelper(
current_target_, element,
gfx::Rect(elem_offset, elem_size), &elem_offset);
- if (code != kSuccess)
- return code;
+ if (error)
+ return error;
for (FramePath frame_path = current_target_.frame_path;
frame_path.IsSubframe();
@@ -759,64 +767,62 @@ ErrorCode Session::GetElementLocationInView(
// Find the frame element for the current frame path.
FrameId frame_id(current_target_.window_id, frame_path.Parent());
WebElementId frame_element;
- code = FindElement(
+ error = FindElement(
frame_id, WebElementId(""),
LocatorType::kXpath, frame_path.BaseName().value(), &frame_element);
- if (code != kSuccess) {
- LOG(ERROR) << "Could not find frame element: "
- << frame_path.BaseName().value()
- << " in frame: " << frame_path.Parent().value();
- return code;
+ if (error) {
+ std::string context = base::StringPrintf(
+ "Could not find frame element (%s) in frame (%s)",
+ frame_path.BaseName().value().c_str(),
+ frame_path.Parent().value().c_str());
+ error->AddDetails(context);
+ return error;
}
// Modify |elem_offset| by the frame's border.
int border_left, border_top;
- code = GetElementBorder(
+ error = GetElementBorder(
frame_id, frame_element, &border_left, &border_top);
- if (code != kSuccess) {
- LOG(ERROR) << "Could not get frame border width";
- return code;
- }
+ if (error)
+ return error;
elem_offset.Offset(border_left, border_top);
- code = GetLocationInViewHelper(
+ error = GetLocationInViewHelper(
frame_id, frame_element,
gfx::Rect(elem_offset, elem_size), &elem_offset);
- if (code != kSuccess)
- return code;
+ if (error)
+ return error;
}
*location = elem_offset;
- return kSuccess;
+ return NULL;
}
-ErrorCode Session::GetElementSize(const FrameId& frame_id,
- const WebElementId& element,
- gfx::Size* size) {
+Error* Session::GetElementSize(const FrameId& frame_id,
+ const WebElementId& element,
+ gfx::Size* size) {
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::GET_SIZE);
ListValue args;
args.Append(element.ToValue());
Value* unscoped_result = NULL;
- ErrorCode code = ExecuteScript(frame_id, script, &args, &unscoped_result);
+ Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess)
- return code;
+ if (error)
+ return error;
if (!result->IsType(Value::TYPE_DICTIONARY)) {
- LOG(ERROR) << "GetSize atom returned non-dict type";
- return kUnknownError;
+ return new Error(kUnknownError, "GetSize atom returned non-dict type");
}
DictionaryValue* dict = static_cast<DictionaryValue*>(result.get());
int width, height;
if (!dict->GetInteger("width", &width) ||
!dict->GetInteger("height", &height)) {
- LOG(ERROR) << "GetSize atom returned dict without width and height keys";
- return kUnknownError;
+ return new Error(kUnknownError, "GetSize atom returned invalid dict");
}
*size = gfx::Size(width, height);
- return kSuccess;
+ return NULL;
}
-ErrorCode Session::GetElementEffectiveStyle(
+Error* Session::GetElementEffectiveStyle(
const FrameId& frame_id,
const WebElementId& element,
const std::string& prop,
@@ -827,88 +833,88 @@ ErrorCode Session::GetElementEffectiveStyle(
args.Append(element.ToValue());
args.Append(Value::CreateStringValue(prop));
Value* unscoped_result = NULL;
- ErrorCode code = ExecuteScript(
+ Error* error = ExecuteScript(
frame_id, script, &args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess) {
- LOG(ERROR) << "GetEffectiveStyle atom failed for property: " << prop;
- return code;
+ if (error) {
+ error->AddDetails(base::StringPrintf(
+ "GetEffectiveStyle atom failed for property (%s)", prop.c_str()));
+ return error;
}
if (!result->GetAsString(value)) {
- LOG(ERROR) << "GetEffectiveStyle atom returned non-string type for "
- << "property: " << prop;
- return kUnknownError;
+ std::string context = base::StringPrintf(
+ "GetEffectiveStyle atom returned non-string type for property (%s)",
+ prop.c_str());
+ return new Error(kUnknownError, context);
}
- return kSuccess;
+ return NULL;
}
-ErrorCode Session::GetElementBorder(const FrameId& frame_id,
- const WebElementId& element,
- int* border_left,
- int* border_top) {
+Error* Session::GetElementBorder(const FrameId& frame_id,
+ const WebElementId& element,
+ int* border_left,
+ int* border_top) {
std::string border_left_str, border_top_str;
- ErrorCode code_left = GetElementEffectiveStyle(
+ Error* error = GetElementEffectiveStyle(
frame_id, element, "border-left-width", &border_left_str);
- ErrorCode code_top = GetElementEffectiveStyle(
+ if (error)
+ return error;
+ error = GetElementEffectiveStyle(
frame_id, element, "border-top-width", &border_top_str);
- if (code_left != kSuccess || code_top != kSuccess)
- return code_left;
+ if (error)
+ return error;
base::StringToInt(border_left_str, border_left);
base::StringToInt(border_top_str, border_top);
- return kSuccess;
+ return NULL;
}
-ErrorCode Session::IsElementDisplayed(const FrameId& frame_id,
- const WebElementId& element,
- bool* is_displayed) {
+Error* Session::IsElementDisplayed(const FrameId& frame_id,
+ const WebElementId& element,
+ bool* is_displayed) {
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::IS_DISPLAYED);
ListValue args;
args.Append(element.ToValue());
Value* unscoped_result = NULL;
- ErrorCode code = ExecuteScript(frame_id, script, &args, &unscoped_result);
+ Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess)
- return code;
- if (!result->GetAsBoolean(is_displayed)) {
- LOG(ERROR) << "IsDisplayed atom returned non boolean";
- return kUnknownError;
- }
- return kSuccess;
+ if (error)
+ return error;
+ if (!result->GetAsBoolean(is_displayed))
+ return new Error(kUnknownError, "IsDisplayed atom returned non boolean");
+ return NULL;
}
-ErrorCode Session::IsElementEnabled(const FrameId& frame_id,
- const WebElementId& element,
- bool* is_enabled) {
+Error* Session::IsElementEnabled(const FrameId& frame_id,
+ const WebElementId& element,
+ bool* is_enabled) {
std::string script = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::IS_ENABLED);
ListValue args;
args.Append(element.ToValue());
Value* unscoped_result = NULL;
- ErrorCode code = ExecuteScript(frame_id, script, &args, &unscoped_result);
+ Error* error = ExecuteScript(frame_id, script, &args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess)
- return code;
- if (!result->GetAsBoolean(is_enabled)) {
- LOG(ERROR) << "IsEnabled atom returned non boolean";
- return kUnknownError;
- }
- return kSuccess;
+ if (error)
+ return error;
+ if (!result->GetAsBoolean(is_enabled))
+ return new Error(kUnknownError, "IsEnabled atom returned non boolean");
+ return NULL;
}
-bool Session::WaitForAllTabsToStopLoading() {
+Error* Session::WaitForAllTabsToStopLoading() {
if (!automation_.get())
- return true;
- bool success = false;
+ return NULL;
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::WaitForAllTabsToStopLoading,
- &success));
- return success;
+ &error));
+ return error;
}
const std::string& Session::id() const {
@@ -935,14 +941,6 @@ int Session::implicit_wait() const {
return implicit_wait_;
}
-void Session::set_speed(Speed speed) {
- speed_ = speed;
-}
-
-Session::Speed Session::speed() const {
- return speed_;
-}
-
void Session::set_screenshot_on_error(bool error) {
screenshot_on_error_ = error;
}
@@ -959,6 +957,10 @@ bool Session::use_native_events() const {
return use_native_events_;
}
+const gfx::Point& Session::get_mouse_position() const {
+ return mouse_position_;
+}
+
void Session::RunSessionTask(Task* task) {
base::WaitableEvent done_event(false, false);
thread_.message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(
@@ -978,26 +980,21 @@ void Session::RunSessionTaskOnSessionThread(Task* task,
void Session::InitOnSessionThread(const FilePath& browser_exe,
const CommandLine& options,
- ErrorCode* code) {
+ Error** error) {
automation_.reset(new Automation());
if (browser_exe.empty())
- automation_->Init(options, code);
+ automation_->Init(options, error);
else
- automation_->InitWithBrowserPath(browser_exe, options, code);
- if (*code != kSuccess)
+ automation_->InitWithBrowserPath(browser_exe, options, error);
+ if (*error)
return;
- bool success = false;
std::vector<int> tab_ids;
- automation_->GetTabIds(&tab_ids, &success);
- if (!success) {
- LOG(ERROR) << "Could not get tab ids";
- *code = kUnknownError;
+ automation_->GetTabIds(&tab_ids, error);
+ if (*error)
return;
- }
if (tab_ids.empty()) {
- LOG(ERROR) << "No tab ids after initialization";
- *code = kUnknownError;
+ *error = new Error(kUnknownError, "No tab ids after initialization");
return;
}
current_target_ = FrameId(tab_ids[0], FramePath());
@@ -1009,16 +1006,15 @@ void Session::TerminateOnSessionThread() {
automation_.reset();
}
-ErrorCode Session::ExecuteScriptAndParseResponse(const FrameId& frame_id,
- const std::string& script,
- Value** value) {
-
+Error* Session::ExecuteScriptAndParseResponse(const FrameId& frame_id,
+ const std::string& script,
+ Value** value) {
// Should we also log the script that's being executed? It could be several KB
// in size and will add lots of noise to the logs.
VLOG(1) << "Executing script in frame: " << frame_id.frame_path.value();
std::string result;
- bool success = false;
+ Error* error = NULL;
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::ExecuteScript,
@@ -1026,33 +1022,18 @@ ErrorCode Session::ExecuteScriptAndParseResponse(const FrameId& frame_id,
frame_id.frame_path,
script,
&result,
- &success));
- if (!success) {
- LOG(ERROR) << "Automation failed to execute script";
- *value = Value::CreateStringValue(
- "Unknown internal script execution failure");
- return kUnknownError;
- }
+ &error));
+ if (error)
+ return error;
VLOG(1) << "...script result: " << result;
scoped_ptr<Value> r(base::JSONReader::ReadAndReturnError(
result, true, NULL, NULL));
- if (!r.get()) {
- LOG(ERROR) << "Failed to parse script result";
- *value = Value::CreateStringValue(
- "Internal script execution error: failed to parse script result");
- return kUnknownError;
- }
+ if (!r.get())
+ return new Error(kUnknownError, "Failed to parse script result");
- if (r->GetType() != Value::TYPE_DICTIONARY) {
- LOG(ERROR) << "Execute script returned non-dictionary type";
- std::ostringstream stream;
- stream << "Internal script execution error: script result must be a "
- << print_valuetype(Value::TYPE_DICTIONARY) << ", but was "
- << print_valuetype(r->GetType()) << ": " << result;
- *value = Value::CreateStringValue(stream.str());
- return kUnknownError;
- }
+ if (r->GetType() != Value::TYPE_DICTIONARY)
+ return new Error(kUnknownError, "Execute script did not return dictionary");
DictionaryValue* result_dict = static_cast<DictionaryValue*>(r.get());
@@ -1066,24 +1047,22 @@ ErrorCode Session::ExecuteScriptAndParseResponse(const FrameId& frame_id,
}
int status;
- if (!result_dict->GetInteger("status", &status)) {
- NOTREACHED() << "...script did not return a status flag.";
- }
- return static_cast<ErrorCode>(status);
+ if (!result_dict->GetInteger("status", &status))
+ return new Error(kUnknownError, "Execute script did not return status");
+ ErrorCode code = static_cast<ErrorCode>(status);
+ if (code != kSuccess)
+ return new Error(code);
+ return NULL;
}
-void Session::SendKeysOnSessionThread(const string16& keys, bool* success) {
- *success = true;
+void Session::SendKeysOnSessionThread(const string16& keys, Error** error) {
std::vector<WebKeyEvent> key_events;
std::string error_msg;
if (!ConvertKeysToWebKeyEvents(keys, &key_events, &error_msg)) {
- // TODO(kkania): Return this message to the user.
- LOG(ERROR) << error_msg;
- *success = false;
+ *error = new Error(kUnknownError, error_msg);
return;
}
for (size_t i = 0; i < key_events.size(); ++i) {
- bool key_success = false;
if (use_native_events_) {
// The automation provider will generate up/down events for us, we
// only need to call it once as compared to the WebKeyEvent method.
@@ -1094,59 +1073,62 @@ void Session::SendKeysOnSessionThread(const string16& keys, bool* success) {
current_target_.window_id,
key_events[i].key_code,
key_events[i].modifiers,
- &key_success);
+ error);
} else {
automation_->SendWebKeyEvent(
- current_target_.window_id, key_events[i], &key_success);
+ current_target_.window_id, key_events[i], error);
}
- if (!key_success) {
- LOG(ERROR) << "Failed to send key event. Event details:\n"
- << "Type: " << key_events[i].type << "\n"
- << "KeyCode: " << key_events[i].key_code << "\n"
- << "UnmodifiedText: " << key_events[i].unmodified_text << "\n"
- << "ModifiedText: " << key_events[i].modified_text << "\n"
- << "Modifiers: " << key_events[i].modifiers << "\n";
- *success = false;
+ if (*error) {
+ std::string details = base::StringPrintf(
+ "Failed to send key event. Event details:\n"
+ "Type: %d, KeyCode: %d, UnmodifiedText: %s, ModifiedText: %s, "
+ "Modifiers: %d",
+ key_events[i].type,
+ key_events[i].key_code,
+ key_events[i].unmodified_text.c_str(),
+ key_events[i].modified_text.c_str(),
+ key_events[i].modifiers);
+ (*error)->AddDetails(details);
+ return;
}
}
}
-ErrorCode Session::SwitchToFrameWithJavaScriptLocatedFrame(
- const std::string& script,
- ListValue* args) {
+Error* Session::SwitchToFrameWithJavaScriptLocatedFrame(
+ const std::string& script, ListValue* args) {
Value* unscoped_result = NULL;
- ErrorCode code = ExecuteScript(script, args, &unscoped_result);
+ Error* error = ExecuteScript(script, args, &unscoped_result);
scoped_ptr<Value> result(unscoped_result);
- if (code != kSuccess)
- return code;
+ if (error)
+ return error;
ListValue* frame_and_xpath_list;
if (!result->GetAsList(&frame_and_xpath_list))
- return kNoSuchFrame;
+ return new Error(kNoSuchFrame);
DictionaryValue* element_dict;
std::string xpath;
if (!frame_and_xpath_list->GetDictionary(0, &element_dict) ||
!frame_and_xpath_list->GetString(1, &xpath)) {
- LOG(ERROR) << "Frame finding script did not return correct type";
- return kUnknownError;
+ return new Error(kUnknownError,
+ "Frame finding script did not return correct type");
}
WebElementId new_frame_element(element_dict);
if (!new_frame_element.is_valid()) {
- LOG(ERROR) << "Frame finding script did not return a frame element";
- return kUnknownError;
+ return new Error(kUnknownError,
+ "Frame finding script did not return a frame element");
}
frame_elements_.push_back(new_frame_element);
current_target_.frame_path = current_target_.frame_path.Append(xpath);
- return kSuccess;
+ return NULL;
}
-ErrorCode Session::FindElementsHelper(const FrameId& frame_id,
- const WebElementId& root_element,
- const std::string& locator,
- const std::string& query,
- bool find_one,
- std::vector<WebElementId>* elements) {
+Error* Session::FindElementsHelper(const FrameId& frame_id,
+ const WebElementId& root_element,
+ const std::string& locator,
+ const std::string& query,
+ bool find_one,
+ std::vector<WebElementId>* elements) {
CHECK(root_element.is_valid());
std::string jscript;
@@ -1176,20 +1158,21 @@ ErrorCode Session::FindElementsHelper(const FrameId& frame_id,
base::Time start_time = base::Time::Now();
scoped_ptr<Value> value;
- ErrorCode code = kUnknownError;
+ scoped_ptr<Error> error;
bool done = false;
while (!done) {
Value* unscoped_value;
- code = ExecuteScript(frame_id, jscript, &jscript_args, &unscoped_value);
+ error.reset(ExecuteScript(
+ frame_id, jscript, &jscript_args, &unscoped_value));
value.reset(unscoped_value);
- if (code == kSuccess) {
+ if (!error.get()) {
// If searching for many elements, make sure we found at least one before
// stopping.
done = find_one ||
(value->GetType() == Value::TYPE_LIST &&
static_cast<ListValue*>(value.get())->GetSize() > 0);
- } else if (code != kNoSuchElement) {
- return code;
+ } else if (error->code() != kNoSuchElement) {
+ return error.release();
}
int64 elapsed_time = (base::Time::Now() - start_time).InMilliseconds();
done = done || elapsed_time > implicit_wait_;
@@ -1198,19 +1181,21 @@ ErrorCode Session::FindElementsHelper(const FrameId& frame_id,
}
// Parse the results.
- if (code == kSuccess) {
+ const char* kInvalidElementDictionaryMessage =
+ "Find element script returned invalid element dictionary";
+ if (!error.get()) {
if (value->IsType(Value::TYPE_LIST)) {
ListValue* element_list = static_cast<ListValue*>(value.get());
for (size_t i = 0; i < element_list->GetSize(); ++i) {
DictionaryValue* element_dict = NULL;
if (!element_list->GetDictionary(i, &element_dict)) {
- LOG(ERROR) << "Not all elements were dictionaries";
- return kUnknownError;
+ return new Error(kUnknownError,
+ "Find element script returned non-dictionary");
}
+
WebElementId element(element_dict);
if (!element.is_valid()) {
- LOG(ERROR) << "Not all elements were valid";
- return kUnknownError;
+ return new Error(kUnknownError, kInvalidElementDictionaryMessage);
}
elements->push_back(element);
}
@@ -1219,22 +1204,21 @@ ErrorCode Session::FindElementsHelper(const FrameId& frame_id,
static_cast<DictionaryValue*>(value.get());
WebElementId element(element_dict);
if (!element.is_valid()) {
- LOG(ERROR) << "Element was invalid";
- return kUnknownError;
+ return new Error(kUnknownError, kInvalidElementDictionaryMessage);
}
elements->push_back(element);
} else {
- LOG(ERROR) << "Invalid result type from find element atom";
- return kUnknownError;
+ return new Error(kUnknownError,
+ "Find element script returned unsupported type");
}
}
- return code;
+ return error.release();
}
-ErrorCode Session::GetLocationInViewHelper(const FrameId& frame_id,
- const WebElementId& element,
- const gfx::Rect& region,
- gfx::Point* location) {
+Error* Session::GetLocationInViewHelper(const FrameId& frame_id,
+ const WebElementId& element,
+ const gfx::Rect& region,
+ gfx::Point* location) {
std::string jscript = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::GET_LOCATION_IN_VIEW);
ListValue jscript_args;
@@ -1246,52 +1230,46 @@ ErrorCode Session::GetLocationInViewHelper(const FrameId& frame_id,
elem_offset_dict->SetInteger("height", region.height());
jscript_args.Append(elem_offset_dict);
Value* unscoped_value = NULL;
- ErrorCode code = ExecuteScript(frame_id, jscript, &jscript_args,
- &unscoped_value);
+ Error* error = ExecuteScript(frame_id, jscript, &jscript_args,
+ &unscoped_value);
scoped_ptr<Value> value(unscoped_value);
- if (code != kSuccess)
- return code;
+ if (error)
+ return error;
if (!value->IsType(Value::TYPE_DICTIONARY)) {
- LOG(ERROR) << "Location atom returned non-dictionary type";
- code = kUnknownError;
+ return new Error(kUnknownError,
+ "Location atom returned non-dictionary type");
}
DictionaryValue* loc_dict = static_cast<DictionaryValue*>(value.get());
int x = 0, y = 0;
if (!loc_dict->GetInteger("x", &x) ||
!loc_dict->GetInteger("y", &y)) {
- LOG(ERROR) << "Location atom returned bad coordinate dictionary";
- code = kUnknownError;
+ return new Error(kUnknownError,
+ "Location atom returned bad coordinate dictionary");
}
*location = gfx::Point(x, y);
- return kSuccess;
+ return NULL;
}
-bool Session::GetScreenShot(std::string* png) {
- bool success = false;
+Error* Session::GetScreenShot(std::string* png) {
+ Error* error = NULL;
ScopedTempDir screenshots_dir;
-
- // Create a temp directory for screenshots.
if (!screenshots_dir.CreateUniqueTempDir()) {
- return false;
+ return new Error(kUnknownError,
+ "Could not create temp directory for screenshot");
}
FilePath path = screenshots_dir.path().AppendASCII("screen");
-
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::CaptureEntirePageAsPNG,
current_target_.window_id,
path,
- &success));
-
- if (success) {
- success = file_util::ReadFileToString(path, png);
- }
- return success;
-}
-
-const gfx::Point& Session::get_mouse_position() const {
- return mouse_position_;
+ &error));
+ if (error)
+ return error;
+ if (!file_util::ReadFileToString(path, png))
+ return new Error(kUnknownError, "Could not read screenshot file");
+ return NULL;
}
} // namespace webdriver
diff --git a/chrome/test/webdriver/session.h b/chrome/test/webdriver/session.h
index 9090691..a8b8764 100644
--- a/chrome/test/webdriver/session.h
+++ b/chrome/test/webdriver/session.h
@@ -14,7 +14,6 @@
#include "base/threading/thread.h"
#include "chrome/common/automation_constants.h"
#include "chrome/test/webdriver/automation.h"
-#include "chrome/test/webdriver/error_codes.h"
#include "chrome/test/webdriver/frame_path.h"
#include "chrome/test/webdriver/web_element_id.h"
#include "ui/gfx/point.h"
@@ -37,6 +36,8 @@ class Size;
namespace webdriver {
+class Error;
+
// A window ID and frame path combination that uniquely identifies a specific
// frame within a session.
struct FrameId {
@@ -52,8 +53,6 @@ struct FrameId {
// A session manages its own lifetime.
class Session {
public:
- enum Speed { kSlow, kMedium, kFast, kUnknown };
-
// Adds this |Session| to the |SessionManager|. The session manages its own
// lifetime. Do not call delete.
Session();
@@ -64,8 +63,8 @@ class Session {
// |browser_exe|. If |browser_exe| is empty, it will search in all the default
// locations. Returns true on success. On failure, the session will delete
// itself and return an error code.
- ErrorCode Init(const FilePath& browser_exe,
- const CommandLine& options);
+ Error* Init(const FilePath& browser_exe,
+ const CommandLine& options);
// Terminates this session and deletes itself.
void Terminate();
@@ -75,99 +74,99 @@ class Session {
// (e.g. "return arguments[0]"), where |args| is the list of arguments to
// pass to the function. The caller is responsible for the script result
// |value|.
- ErrorCode ExecuteScript(const FrameId& frame_id,
- const std::string& script,
- const ListValue* const args,
- Value** value);
+ Error* ExecuteScript(const FrameId& frame_id,
+ const std::string& script,
+ const ListValue* const args,
+ Value** value);
// Same as above, but uses the currently targeted window and frame.
- ErrorCode ExecuteScript(const std::string& script,
- const ListValue* const args,
- Value** value);
+ Error* ExecuteScript(const std::string& script,
+ const ListValue* const args,
+ Value** value);
// Executes given |script| in the context of the given frame.
// The |script| should be in the form of a function body
// (e.g. "return arguments[0]"), where |args| is the list of arguments to
// pass to the function. The caller is responsible for the script result
// |value|.
- ErrorCode ExecuteAsyncScript(const FrameId& frame_id,
- const std::string& script,
- const ListValue* const args,
- Value** value);
+ Error* ExecuteAsyncScript(const FrameId& frame_id,
+ const std::string& script,
+ const ListValue* const args,
+ Value** value);
// Send the given keys to the given element dictionary. This function takes
// ownership of |element|.
- ErrorCode SendKeys(const WebElementId& element, const string16& keys);
+ Error* SendKeys(const WebElementId& element, const string16& keys);
// Clicks the mouse at the given location using the given button.
- bool MouseMoveAndClick(const gfx::Point& location,
- automation::MouseButton button);
- bool MouseMove(const gfx::Point& location);
- bool MouseDrag(const gfx::Point& start, const gfx::Point& end);
- bool MouseClick(automation::MouseButton button);
- bool MouseButtonDown();
- bool MouseButtonUp();
- bool MouseDoubleClick();
-
- bool NavigateToURL(const std::string& url);
- bool GoForward();
- bool GoBack();
- bool Reload();
- ErrorCode GetURL(std::string* url);
- ErrorCode GetURL(GURL* url);
- ErrorCode GetTitle(std::string* tab_title);
- bool GetScreenShot(std::string* png);
-
- bool GetCookies(const std::string& url, ListValue** cookies);
+ Error* MouseMoveAndClick(const gfx::Point& location,
+ automation::MouseButton button);
+ Error* MouseMove(const gfx::Point& location);
+ Error* MouseDrag(const gfx::Point& start, const gfx::Point& end);
+ Error* MouseClick(automation::MouseButton button);
+ Error* MouseButtonDown();
+ Error* MouseButtonUp();
+ Error* MouseDoubleClick();
+
+ Error* NavigateToURL(const std::string& url);
+ Error* GoForward();
+ Error* GoBack();
+ Error* Reload();
+ Error* GetURL(std::string* url);
+ Error* GetURL(GURL* url);
+ Error* GetTitle(std::string* tab_title);
+ Error* GetScreenShot(std::string* png);
+
+ Error* GetCookies(const std::string& url, ListValue** cookies);
bool GetCookiesDeprecated(const GURL& url, std::string* cookies);
bool GetCookieByNameDeprecated(const GURL& url,
const std::string& cookie_name,
std::string* cookie);
- bool DeleteCookie(const std::string& url, const std::string& cookie_name);
+ Error* DeleteCookie(const std::string& url, const std::string& cookie_name);
bool DeleteCookieDeprecated(const GURL& url, const std::string& cookie_name);
- bool SetCookie(const std::string& url, DictionaryValue* cookie_dict);
+ Error* SetCookie(const std::string& url, DictionaryValue* cookie_dict);
bool SetCookieDeprecated(const GURL& url, const std::string& cookie);
// Gets all the currently existing window IDs. Returns true on success.
- bool GetWindowIds(std::vector<int>* window_ids);
+ Error* GetWindowIds(std::vector<int>* window_ids);
// Switches the window used by default. |name| is either an ID returned by
// |GetWindowIds| or the name attribute of a DOM window.
- ErrorCode SwitchToWindow(const std::string& name);
+ Error* SwitchToWindow(const std::string& name);
// Switches the frame used by default. |name_or_id| is either the name or id
// of a frame element.
- ErrorCode SwitchToFrameWithNameOrId(const std::string& name_or_id);
+ Error* SwitchToFrameWithNameOrId(const std::string& name_or_id);
// Switches the frame used by default. |index| is the zero-based frame index.
- ErrorCode SwitchToFrameWithIndex(int index);
+ Error* SwitchToFrameWithIndex(int index);
// Switches to the frame identified by the given |element|. The element must
// be either an IFRAME or FRAME element.
- ErrorCode SwitchToFrameWithElement(const WebElementId& element);
+ Error* SwitchToFrameWithElement(const WebElementId& element);
// Switches the target frame to the topmost frame.
void SwitchToTopFrame();
// Switches the target frame to the topmost frame if the current frame is
// invalid.
- void SwitchToTopFrameIfCurrentFrameInvalid();
+ Error* SwitchToTopFrameIfCurrentFrameInvalid();
// Closes the current window. Returns true on success.
// Note: The session will be deleted if this closes the last window in the
// session.
- bool CloseWindow();
+ Error* CloseWindow();
// Gets the message of the currently active JavaScript modal dialog.
- ErrorCode GetAlertMessage(std::string* text);
+ Error* GetAlertMessage(std::string* text);
// Sets the prompt text to use when accepting or dismissing a JavaScript
// modal dialog.
- ErrorCode SetAlertPromptText(const std::string& alert_prompt_text);
+ Error* SetAlertPromptText(const std::string& alert_prompt_text);
// Accept or dismiss the currently active JavaScript modal dialog with the
// previously set alert prompt text. Then clears the saved alert prompt text.
- ErrorCode AcceptOrDismissAlert(bool accept);
+ Error* AcceptOrDismissAlert(bool accept);
// Gets the version of the running browser.
std::string GetBrowserVersion();
@@ -175,63 +174,67 @@ class Session {
// Gets whether the running browser's version is newer or equal to the given
// version. Returns true on successful comparison. For example, in the version
// 11.0.632.4, 632 is the build number and 4 is the patch number.
- bool CompareBrowserVersion(int build_no,
- int patch_no,
- bool* is_newer_or_equal);
+ Error* CompareBrowserVersion(int build_no,
+ int patch_no,
+ bool* is_newer_or_equal);
// Finds a single element in the given frame, starting at the given
// |root_element|, using the given locator strategy. |locator| should be a
// constant from |LocatorType|. Returns an error code. If successful,
// |element| will be set as the found element.
- ErrorCode FindElement(const FrameId& frame_id,
- const WebElementId& root_element,
- const std::string& locator,
- const std::string& query,
- WebElementId* element);
+ Error* FindElement(const FrameId& frame_id,
+ const WebElementId& root_element,
+ const std::string& locator,
+ const std::string& query,
+ WebElementId* element);
// Same as above, but finds multiple elements.
- ErrorCode FindElements(const FrameId& frame_id,
- const WebElementId& root_element,
- const std::string& locator,
- const std::string& query,
- std::vector<WebElementId>* elements);
+ Error* FindElements(const FrameId& frame_id,
+ const WebElementId& root_element,
+ const std::string& locator,
+ const std::string& query,
+ std::vector<WebElementId>* elements);
+
+ // Checks that the given element meets the WebDriver requirements for
+ // clicking.
+ Error* CheckElementPreconditionsForClicking(const WebElementId& element);
// Scroll the element into view and get its location relative to the client's
// viewport.
- ErrorCode GetElementLocationInView(
+ Error* GetElementLocationInView(
const WebElementId& element, gfx::Point* location);
// Gets the size of the element from the given window and frame, even if
// its display is none.
- ErrorCode GetElementSize(const FrameId& frame_id,
- const WebElementId& element,
- gfx::Size* size);
+ Error* GetElementSize(const FrameId& frame_id,
+ const WebElementId& element,
+ gfx::Size* size);
// Gets the element's effective style for the given property.
- ErrorCode GetElementEffectiveStyle(
+ Error* GetElementEffectiveStyle(
const FrameId& frame_id,
const WebElementId& element,
const std::string& prop,
std::string* value);
// Gets the top and left element border widths for the given frame.
- ErrorCode GetElementBorder(const FrameId& frame_id,
- const WebElementId& element,
- int* border_left,
- int* border_top);
+ Error* GetElementBorder(const FrameId& frame_id,
+ const WebElementId& element,
+ int* border_left,
+ int* border_top);
// Gets whether the element is currently displayed.
- ErrorCode IsElementDisplayed(const FrameId& frame_id,
- const WebElementId& element,
- bool* is_visible);
+ Error* IsElementDisplayed(const FrameId& frame_id,
+ const WebElementId& element,
+ bool* is_visible);
// Gets whether the element is currently enabled.
- ErrorCode IsElementEnabled(const FrameId& frame_id,
- const WebElementId& element,
- bool* is_enabled);
+ Error* IsElementEnabled(const FrameId& frame_id,
+ const WebElementId& element,
+ bool* is_enabled);
// Waits for all tabs to stop loading. Returns true on success.
- bool WaitForAllTabsToStopLoading();
+ Error* WaitForAllTabsToStopLoading();
const std::string& id() const;
@@ -243,9 +246,6 @@ class Session {
void set_implicit_wait(int timeout_ms);
int implicit_wait() const;
- void set_speed(Speed speed);
- Speed speed() const;
-
void set_screenshot_on_error(bool error);
bool screenshot_on_error() const;
@@ -261,30 +261,30 @@ class Session {
base::WaitableEvent* done_event);
void InitOnSessionThread(const FilePath& browser_exe,
const CommandLine& options,
- ErrorCode* code);
+ Error** error);
void TerminateOnSessionThread();
// Executes the given |script| in the context of the given frame.
// Waits for script to finish and parses the response.
// The caller is responsible for the script result |value|.
- ErrorCode ExecuteScriptAndParseResponse(const FrameId& frame_id,
- const std::string& script,
- Value** value);
+ Error* ExecuteScriptAndParseResponse(const FrameId& frame_id,
+ const std::string& script,
+ Value** value);
- void SendKeysOnSessionThread(const string16& keys, bool* success);
- ErrorCode SwitchToFrameWithJavaScriptLocatedFrame(
+ void SendKeysOnSessionThread(const string16& keys, Error** error);
+ Error* SwitchToFrameWithJavaScriptLocatedFrame(
const std::string& script,
ListValue* args);
- ErrorCode FindElementsHelper(const FrameId& frame_id,
- const WebElementId& root_element,
- const std::string& locator,
- const std::string& query,
- bool find_one,
- std::vector<WebElementId>* elements);
- ErrorCode GetLocationInViewHelper(const FrameId& frame_id,
- const WebElementId& element,
- const gfx::Rect& region,
- gfx::Point* location);
+ Error* FindElementsHelper(const FrameId& frame_id,
+ const WebElementId& root_element,
+ const std::string& locator,
+ const std::string& query,
+ bool find_one,
+ std::vector<WebElementId>* elements);
+ Error* GetLocationInViewHelper(const FrameId& frame_id,
+ const WebElementId& element,
+ const gfx::Rect& region,
+ gfx::Point* location);
const std::string id_;
FrameId current_target_;
@@ -298,8 +298,6 @@ class Session {
// Time (in ms) of how long to wait while searching for a single element.
int implicit_wait_;
- Speed speed_;
-
// Since screenshots can be very large when in base64 PNG format; the
// client is allowed to dyamically enable/disable screenshots on error
// during the lifetime of the session.
diff --git a/chrome/test/webdriver/webdriver_error.cc b/chrome/test/webdriver/webdriver_error.cc
new file mode 100644
index 0000000..33baa7e
--- /dev/null
+++ b/chrome/test/webdriver/webdriver_error.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/test/webdriver/webdriver_error.h"
+
+#include <sstream>
+
+namespace webdriver {
+
+namespace {
+
+// Returns the string equivalent of the given |ErrorCode|.
+const char* ErrorCodeToString(ErrorCode code) {
+ switch (code) {
+ case kSuccess:
+ return "SUCCESS";
+ case kNoSuchElement:
+ return "NO_SUCH_ELEMENT";
+ case kNoSuchFrame:
+ return "NO_SUCH_FRAME";
+ case kUnknownCommand:
+ return "UNKNOWN_COMMAND";
+ case kStaleElementReference:
+ return "STALE_ELEMENT_REFERENCE";
+ case kElementNotVisible:
+ return "ELEMENT_NOT_VISIBLE";
+ case kInvalidElementState:
+ return "INVALID_ELEMENT_STATE";
+ case kUnknownError:
+ return "UNKNOWN_ERROR";
+ case kElementNotSelectable:
+ return "ELEMENT_NOT_SELECTABLE";
+ case kXPathLookupError:
+ return "XPATH_LOOKUP_ERROR";
+ case kNoSuchWindow:
+ return "NO_SUCH_WINDOW";
+ case kInvalidCookieDomain:
+ return "INVALID_COOKIE_DOMAIN";
+ case kUnableToSetCookie:
+ return "UNABLE_TO_SET_COOKIE";
+ default:
+ return "<unknown>";
+ }
+}
+
+} // namespace
+
+Error::Error(ErrorCode code): code_(code) {
+}
+
+Error::Error(ErrorCode code, const std::string& details)
+ : code_(code), details_(details) {
+}
+
+Error::~Error() {
+}
+
+void Error::AddDetails(const std::string& details) {
+ if (details_.empty())
+ details_ = details;
+ else
+ details_ = details + ";\n " + details_;
+}
+
+std::string Error::ToString() const {
+ std::string error;
+ if (code_ != kUnknownError) {
+ error += ErrorCodeToString(code_);
+ error += ": ";
+ }
+ if (details_.length()) {
+ error += details_;
+ }
+ size_t count = 0;
+ trace_.Addresses(&count);
+ if (count > 0) {
+ std::ostringstream ostream;
+ trace_.OutputToStream(&ostream);
+ error += "\n";
+ error += ostream.str();
+ }
+ return error;
+}
+
+ErrorCode Error::code() const {
+ return code_;
+}
+
+const std::string& Error::details() const {
+ return details_;
+}
+
+const base::debug::StackTrace& Error::trace() const {
+ return trace_;
+}
+
+} // namespace webdriver
diff --git a/chrome/test/webdriver/webdriver_error.h b/chrome/test/webdriver/webdriver_error.h
new file mode 100644
index 0000000..0a232da
--- /dev/null
+++ b/chrome/test/webdriver/webdriver_error.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_TEST_WEBDRIVER_WEBDRIVER_ERROR_H_
+#define CHROME_TEST_WEBDRIVER_WEBDRIVER_ERROR_H_
+#pragma once
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/debug/stack_trace.h"
+
+namespace webdriver {
+
+// Error codes defined by the WebDriver wire protcol.
+// If you add a code here, don't forget to add it to |ErrorCodeToString|.
+enum ErrorCode {
+ kSuccess = 0,
+ kNoSuchElement = 7,
+ kNoSuchFrame = 8,
+ kUnknownCommand = 9,
+ kStaleElementReference = 10,
+ kElementNotVisible = 11,
+ kInvalidElementState = 12,
+ kUnknownError = 13,
+ kElementNotSelectable = 15,
+ kXPathLookupError = 19,
+ kNoSuchWindow = 23,
+ kInvalidCookieDomain = 24,
+ kUnableToSetCookie = 25,
+
+ // HTTP status codes.
+ kSeeOther = 303,
+ kBadRequest = 400,
+ kSessionNotFound = 404,
+ kMethodNotAllowed = 405,
+ kInternalServerError = 500,
+};
+
+// Represents a WebDriver error and the context within which the error occurred.
+class Error {
+ public:
+ explicit Error(ErrorCode code);
+
+ Error(ErrorCode code, const std::string& details);
+
+ virtual ~Error();
+
+ void AddDetails(const std::string& details);
+
+ // Returns a formatted string describing the error. For logging purposes.
+ std::string ToString() const;
+
+ ErrorCode code() const;
+ const std::string& details() const;
+ const base::debug::StackTrace& trace() const;
+
+ private:
+ ErrorCode code_;
+ std::string details_;
+ base::debug::StackTrace trace_;
+
+ DISALLOW_COPY_AND_ASSIGN(Error);
+};
+
+} // namespace webdriver
+
+#endif // CHROME_TEST_WEBDRIVER_WEBDRIVER_ERROR_H_