summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-16 23:10:58 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-16 23:10:58 +0000
commitb56da61e79ee405291e8ea6b260f51a1541928d1 (patch)
tree21fdef964b8efa4caedea151cdd0867815de528a
parent938f4ea71a0e2806f4c50b4c6d59c1586f8aa399 (diff)
downloadchromium_src-b56da61e79ee405291e8ea6b260f51a1541928d1.zip
chromium_src-b56da61e79ee405291e8ea6b260f51a1541928d1.tar.gz
chromium_src-b56da61e79ee405291e8ea6b260f51a1541928d1.tar.bz2
Have ChromeDriver return the correct error code for alerts.
Also, don't throw an alert error in set selected if the selection causes an alert. BUG=94959 TEST=none Review URL: http://codereview.chromium.org/8965008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114874 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/automation_provider_json.cc35
-rw-r--r--chrome/browser/automation/automation_provider_json.h7
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc3
-rw-r--r--chrome/browser/automation/automation_util.cc4
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc25
-rw-r--r--chrome/common/automation_constants.cc40
-rw-r--r--chrome/common/automation_constants.h42
-rw-r--r--chrome/test/automation/automation_json_requests.cc199
-rw-r--r--chrome/test/automation/automation_json_requests.h76
-rw-r--r--chrome/test/automation/tab_proxy.cc7
-rw-r--r--chrome/test/webdriver/test/chromedriver_tests.py12
-rw-r--r--chrome/test/webdriver/webdriver_automation.cc230
-rw-r--r--chrome/test/webdriver/webdriver_error.cc46
-rw-r--r--chrome/test/webdriver/webdriver_error.h8
-rw-r--r--chrome/test/webdriver/webdriver_session.cc18
15 files changed, 462 insertions, 290 deletions
diff --git a/chrome/browser/automation/automation_provider_json.cc b/chrome/browser/automation/automation_provider_json.cc
index 27c8474a..9a5c57f 100644
--- a/chrome/browser/automation/automation_provider_json.cc
+++ b/chrome/browser/automation/automation_provider_json.cc
@@ -16,20 +16,8 @@
#include "chrome/common/automation_messages.h"
#include "content/browser/tab_contents/tab_contents.h"
-namespace {
-
-// Util for creating a JSON error return string (dict with key
-// 'error' and error string value). No need to quote input.
-std::string JSONErrorString(const std::string& err) {
- std::string prefix = "{\"error\": \"";
- std::string no_quote_err;
- std::string suffix = "\"}";
-
- base::JsonDoubleQuote(err, false, &no_quote_err);
- return prefix + no_quote_err + suffix;
-}
-
-} // namespace
+using automation::Error;
+using automation::ErrorCode;
AutomationJSONReply::AutomationJSONReply(AutomationProvider* provider,
IPC::Message* reply_message)
@@ -53,10 +41,23 @@ void AutomationJSONReply::SendSuccess(const Value* value) {
}
void AutomationJSONReply::SendError(const std::string& error_message) {
+ SendErrorInternal(Error(error_message));
+}
+
+void AutomationJSONReply::SendErrorCode(ErrorCode code) {
+ SendErrorInternal(Error(code));
+}
+
+void AutomationJSONReply::SendErrorInternal(const Error& error) {
DCHECK(message_) << "Resending reply for JSON automation request";
- std::string json_string = JSONErrorString(error_message);
- AutomationMsg_SendJSONRequest::WriteReplyParams(
- message_, json_string, false);
+
+ base::DictionaryValue dict;
+ dict.SetString("error", error.message());
+ dict.SetInteger("code", error.code());
+ std::string json;
+ base::JSONWriter::Write(&dict, false /* pretty_print */, &json);
+
+ AutomationMsg_SendJSONRequest::WriteReplyParams(message_, json, false);
provider_->Send(message_);
message_ = NULL;
}
diff --git a/chrome/browser/automation/automation_provider_json.h b/chrome/browser/automation/automation_provider_json.h
index b7a8674..7b46879 100644
--- a/chrome/browser/automation/automation_provider_json.h
+++ b/chrome/browser/automation/automation_provider_json.h
@@ -11,6 +11,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "chrome/common/automation_constants.h"
class AutomationId;
class AutomationProvider;
@@ -47,7 +48,13 @@ class AutomationJSONReply {
// Send an error reply along with error message |error_message|.
void SendError(const std::string& error_message);
+ // Send an error reply along with the specified error code and its
+ // associated error message.
+ void SendErrorCode(automation::ErrorCode code);
+
private:
+ void SendErrorInternal(const automation::Error& error);
+
AutomationProvider* provider_;
IPC::Message* message_;
};
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index c1d5be9..2435617 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -1265,8 +1265,7 @@ void DomOperationMessageSender::OnDomOperationCompleted(
void DomOperationMessageSender::OnModalDialogShown() {
if (automation_ && use_json_interface_) {
AutomationJSONReply(automation_, reply_message_.release())
- .SendError("Could not complete script execution because a modal "
- "dialog is active");
+ .SendErrorCode(automation::kBlockedByModalDialog);
delete this;
}
}
diff --git a/chrome/browser/automation/automation_util.cc b/chrome/browser/automation/automation_util.cc
index 07b6909..a092763 100644
--- a/chrome/browser/automation/automation_util.cc
+++ b/chrome/browser/automation/automation_util.cc
@@ -397,8 +397,8 @@ bool SendErrorIfModalDialogActive(AutomationProvider* provider,
IPC::Message* message) {
bool active = AppModalDialogQueue::GetInstance()->HasActiveDialog();
if (active) {
- AutomationJSONReply(provider, message).SendError(
- "Command cannot be performed because a modal dialog is active");
+ AutomationJSONReply(provider, message).SendErrorCode(
+ automation::kBlockedByModalDialog);
}
return active;
}
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index aa9591f..7068738 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -145,6 +145,8 @@
#include "chrome/browser/download/download_shelf.h"
#endif
+using automation::Error;
+using automation::ErrorCode;
using automation_util::SendErrorIfModalDialogActive;
using content::BrowserThread;
using content::ChildProcessHost;
@@ -5741,14 +5743,11 @@ namespace {
// Gets the active JavaScript modal dialog, or NULL if none.
JavaScriptAppModalDialog* GetActiveJavaScriptModalDialog(
- std::string* error_msg) {
+ ErrorCode* error_code) {
AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance();
- if (!dialog_queue->HasActiveDialog()) {
- *error_msg = "No modal dialog is showing";
- return NULL;
- }
- if (!dialog_queue->active_dialog()->IsJavaScriptModalDialog()) {
- *error_msg = "No JavaScript modal dialog is showing";
+ if (!dialog_queue->HasActiveDialog() ||
+ !dialog_queue->active_dialog()->IsJavaScriptModalDialog()) {
+ *error_code = automation::kNoJavaScriptModalDialogOpen;
return NULL;
}
return static_cast<JavaScriptAppModalDialog*>(dialog_queue->active_dialog());
@@ -5759,10 +5758,10 @@ JavaScriptAppModalDialog* GetActiveJavaScriptModalDialog(
void TestingAutomationProvider::GetAppModalDialogMessage(
DictionaryValue* args, IPC::Message* reply_message) {
AutomationJSONReply reply(this, reply_message);
- std::string error_msg;
- JavaScriptAppModalDialog* dialog = GetActiveJavaScriptModalDialog(&error_msg);
+ ErrorCode code;
+ JavaScriptAppModalDialog* dialog = GetActiveJavaScriptModalDialog(&code);
if (!dialog) {
- reply.SendError(error_msg);
+ reply.SendErrorCode(code);
return;
}
DictionaryValue result_dict;
@@ -5779,10 +5778,10 @@ void TestingAutomationProvider::AcceptOrDismissAppModalDialog(
return;
}
- std::string error_msg;
- JavaScriptAppModalDialog* dialog = GetActiveJavaScriptModalDialog(&error_msg);
+ ErrorCode code;
+ JavaScriptAppModalDialog* dialog = GetActiveJavaScriptModalDialog(&code);
if (!dialog) {
- reply.SendError(error_msg);
+ reply.SendErrorCode(code);
return;
}
if (accept) {
diff --git a/chrome/common/automation_constants.cc b/chrome/common/automation_constants.cc
index f380088..0fbb0de 100644
--- a/chrome/common/automation_constants.cc
+++ b/chrome/common/automation_constants.cc
@@ -21,4 +21,44 @@ const char kNamedInterfacePrefix[] = "NamedTestingInterface:";
const int kChromeDriverAutomationVersion = 1;
+namespace {
+
+// Returns the string equivalent of the given |ErrorCode|.
+const char* DefaultMessageForErrorCode(ErrorCode code) {
+ switch (code) {
+ case kUnknownError:
+ return "Unknown error";
+ case kNoJavaScriptModalDialogOpen:
+ return "No JavaScript modal dialog is open";
+ case kBlockedByModalDialog:
+ return "Command blocked by an open modal dialog";
+ default:
+ return "<unknown>";
+ }
+}
+
+} // namespace
+
+Error::Error() : code_(kUnknownError) { }
+
+Error::Error(ErrorCode code)
+ : code_(code),
+ message_(DefaultMessageForErrorCode(code)) { }
+
+Error::Error(const std::string& error_msg)
+ : code_(kUnknownError), message_(error_msg) { }
+
+Error::Error(ErrorCode code, const std::string& error_msg)
+ : code_(code), message_(error_msg) { }
+
+Error::~Error() { }
+
+ErrorCode Error::code() const {
+ return code_;
+}
+
+const std::string& Error::message() const {
+ return message_;
+}
+
} // namespace automation
diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h
index 1e2cdb3..3754d43 100644
--- a/chrome/common/automation_constants.h
+++ b/chrome/common/automation_constants.h
@@ -6,6 +6,8 @@
#define CHROME_COMMON_AUTOMATION_CONSTANTS_H__
#pragma once
+#include <string>
+
namespace automation {
// JSON value labels for proxy settings that are passed in via
@@ -60,6 +62,46 @@ enum MouseButton {
// TODO(kkania): Investigate a better backwards compatible automation solution.
extern const int kChromeDriverAutomationVersion;
+// Automation error codes. These provide the client a simple way
+// to detect certain types of errors it may be interested in handling.
+// The error code values must stay consistent across compatible versions.
+enum ErrorCode {
+ // An unknown error occurred.
+ kUnknownError = 0,
+ // Trying to operate on a JavaScript modal dialog when none is open.
+ kNoJavaScriptModalDialogOpen = 1,
+ // An open modal dialog blocked the operation. The operation may have
+ // partially completed.
+ kBlockedByModalDialog = 2,
+};
+
+// Represents an automation error. Each error has a code and an error message.
+class Error {
+ public:
+ // Creates an invalid error.
+ Error();
+
+ // Creates an error for the given code. A default message for the given code
+ // will be used as the error message.
+ explicit Error(ErrorCode code);
+
+ // Creates an error for the given message. The |kUnknownError| type will
+ // be used.
+ explicit Error(const std::string& error_msg);
+
+ // Creates an error for the given code and message.
+ Error(ErrorCode code, const std::string& error_msg);
+
+ virtual ~Error();
+
+ ErrorCode code() const;
+ const std::string& message() const;
+
+ private:
+ ErrorCode code_;
+ std::string message_;
+};
+
} // namespace automation
// Used by AutomationProxy, declared here so that other headers don't need
diff --git a/chrome/test/automation/automation_json_requests.cc b/chrome/test/automation/automation_json_requests.cc
index 4dd8478..0c624527 100644
--- a/chrome/test/automation/automation_json_requests.cc
+++ b/chrome/test/automation/automation_json_requests.cc
@@ -18,6 +18,8 @@
#include "chrome/common/automation_messages.h"
#include "chrome/test/automation/automation_proxy.h"
+using automation::Error;
+using automation::ErrorCode;
using base::DictionaryValue;
using base::ListValue;
@@ -26,7 +28,7 @@ namespace {
bool SendAutomationJSONRequest(AutomationMessageSender* sender,
const DictionaryValue& request_dict,
DictionaryValue* reply_dict,
- std::string* error_msg) {
+ Error* error) {
std::string request, reply;
base::JSONWriter::Write(&request_dict, false, &request);
std::string command;
@@ -37,27 +39,29 @@ bool SendAutomationJSONRequest(AutomationMessageSender* sender,
bool success = false;
if (!SendAutomationJSONRequestWithDefaultTimeout(
sender, request, &reply, &success)) {
- *error_msg = base::StringPrintf(
+ *error = Error(base::StringPrintf(
"Chrome did not respond to '%s'. Elapsed time was %" PRId64 " ms.",
command.c_str(),
- (base::Time::Now() - before_sending).InMilliseconds());
+ (base::Time::Now() - before_sending).InMilliseconds()));
+ LOG(INFO) << error->message();
return false;
}
scoped_ptr<Value> value(base::JSONReader::Read(reply, true));
if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) {
+ *error = Error("JSON request did not return a dictionary");
LOG(ERROR) << "JSON request did not return dict: " << command << "\n";
return false;
}
DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
if (!success) {
- std::string error;
- dict->GetString("error", &error);
- *error_msg = base::StringPrintf(
- "Internal Chrome error during '%s': (%s).",
- command.c_str(),
- error.c_str());
- LOG(ERROR) << "JSON request failed: " << command << "\n"
- << " with error: " << error;
+ std::string error_msg;
+ dict->GetString("error", &error_msg);
+ int int_code = automation::kUnknownError;
+ dict->GetInteger("code", &int_code);
+ ErrorCode code = static_cast<ErrorCode>(int_code);
+ *error = Error(code, error_msg);
+ LOG(INFO) << "JSON request failed: " << command << "\n"
+ << " with error: " << error_msg;
return false;
}
reply_dict->MergeDictionary(dict);
@@ -203,12 +207,12 @@ bool SendGetIndicesFromTabIdJSONRequest(
int tab_id,
int* browser_index,
int* tab_index,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue request_dict;
request_dict.SetString("command", "GetIndicesFromTab");
request_dict.SetInteger("tab_id", tab_id);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict, error))
return false;
if (!reply_dict.GetInteger("windex", browser_index))
return false;
@@ -222,12 +226,12 @@ bool SendGetIndicesFromTabHandleJSONRequest(
int tab_handle,
int* browser_index,
int* tab_index,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue request_dict;
request_dict.SetString("command", "GetIndicesFromTab");
request_dict.SetInteger("tab_handle", tab_handle);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, request_dict, &reply_dict, error))
return false;
if (!reply_dict.GetInteger("windex", browser_index))
return false;
@@ -242,14 +246,14 @@ bool SendNavigateToURLJSONRequest(
const std::string& url,
int navigation_count,
AutomationMsg_NavigationResponseValues* nav_response,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "NavigateToURL");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetString("url", url);
dict.SetInteger("navigation_count", navigation_count);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
int response = 0;
if (!reply_dict.GetInteger("result", &response))
@@ -264,14 +268,14 @@ bool SendExecuteJavascriptJSONRequest(
const std::string& frame_xpath,
const std::string& javascript,
Value** result,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "ExecuteJavascript");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetString("frame_xpath", frame_xpath);
dict.SetString("javascript", javascript);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
std::string json;
@@ -297,60 +301,60 @@ bool SendExecuteJavascriptJSONRequest(
bool SendGoForwardJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GoForward");
locator.UpdateDictionary(&dict, "auto_id");
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendGoBackJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GoBack");
locator.UpdateDictionary(&dict, "auto_id");
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendReloadJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "Reload");
locator.UpdateDictionary(&dict, "auto_id");
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendCaptureEntirePageJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
const FilePath& path,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "CaptureEntirePage");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetString("path", path.value());
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendGetCookiesJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
ListValue** cookies,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GetCookies");
dict.SetString("url", url);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
Value* cookies_unscoped_value;
if (!reply_dict.Remove("cookies", &cookies_unscoped_value))
@@ -366,43 +370,43 @@ bool SendDeleteCookieJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
const std::string& cookie_name,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "DeleteCookie");
dict.SetString("url", url);
dict.SetString("name", cookie_name);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendSetCookieJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
DictionaryValue* cookie_dict,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "SetCookie");
dict.SetString("url", url);
dict.Set("cookie", cookie_dict->DeepCopy());
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendGetTabIdsJSONRequest(
AutomationMessageSender* sender,
std::vector<WebViewInfo>* views,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GetTabIds");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
ListValue* id_list;
if (reply_dict.GetList("ids", &id_list)) {
for (size_t i = 0; i < id_list->GetSize(); ++i) {
int id;
if (!id_list->GetInteger(i, &id)) {
- *error_msg = "Returned id in 'tab_ids' is not an integer";
+ *error = Error("Returned id in 'tab_ids' is not an integer");
return false;
}
views->push_back(WebViewInfo(
@@ -415,27 +419,30 @@ bool SendGetTabIdsJSONRequest(
bool SendGetWebViewsJSONRequest(
AutomationMessageSender* sender,
std::vector<WebViewInfo>* views,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GetViews");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
ListValue* views_list;
if (!reply_dict.GetList("views", &views_list)) {
- *error_msg = "Returned 'views' key is missing or invalid";
+ *error = Error("Returned 'views' key is missing or invalid");
return false;
}
for (size_t i = 0; i < views_list->GetSize(); ++i) {
DictionaryValue* view_dict;
if (!views_list->GetDictionary(i, &view_dict)) {
- *error_msg = "Returned 'views' key contains non-dictionary values";
+ *error = Error("Returned 'views' key contains non-dictionary values");
return false;
}
AutomationId view_id;
+ std::string error_msg;
if (!AutomationId::FromValueInDictionary(
- view_dict, "auto_id", &view_id, error_msg))
+ view_dict, "auto_id", &view_id, &error_msg)) {
+ *error = Error(error_msg);
return false;
+ }
std::string extension_id;
view_dict->GetString("extension_id", &extension_id);
views->push_back(WebViewInfo(
@@ -448,12 +455,12 @@ bool SendIsTabIdValidJSONRequest(
AutomationMessageSender* sender,
const WebViewId& view_id,
bool* is_valid,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "IsTabIdValid");
view_id.UpdateDictionary(&dict, "tab_id");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
return reply_dict.GetBoolean("is_valid", is_valid);
}
@@ -462,12 +469,12 @@ bool SendDoesAutomationObjectExistJSONRequest(
AutomationMessageSender* sender,
const WebViewId& view_id,
bool* does_exist,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "DoesAutomationObjectExist");
view_id.UpdateDictionary(&dict, "auto_id");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
return reply_dict.GetBoolean("does_exist", does_exist);
}
@@ -475,12 +482,12 @@ bool SendDoesAutomationObjectExistJSONRequest(
bool SendCloseViewJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "CloseTab");
locator.UpdateDictionary(&dict, "auto_id");
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendMouseMoveJSONRequest(
@@ -488,14 +495,14 @@ bool SendMouseMoveJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WebkitMouseMove");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetInteger("x", x);
dict.SetInteger("y", y);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendMouseClickJSONRequest(
@@ -504,7 +511,7 @@ bool SendMouseClickJSONRequest(
automation::MouseButton button,
int x,
int y,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WebkitMouseClick");
locator.UpdateDictionary(&dict, "auto_id");
@@ -512,7 +519,7 @@ bool SendMouseClickJSONRequest(
dict.SetInteger("x", x);
dict.SetInteger("y", y);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendMouseDragJSONRequest(
@@ -522,7 +529,7 @@ bool SendMouseDragJSONRequest(
int start_y,
int end_x,
int end_y,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WebkitMouseDrag");
locator.UpdateDictionary(&dict, "auto_id");
@@ -531,7 +538,7 @@ bool SendMouseDragJSONRequest(
dict.SetInteger("end_x", end_x);
dict.SetInteger("end_y", end_y);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendMouseButtonDownJSONRequest(
@@ -539,14 +546,14 @@ bool SendMouseButtonDownJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WebkitMouseButtonDown");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetInteger("x", x);
dict.SetInteger("y", y);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendMouseButtonUpJSONRequest(
@@ -554,14 +561,14 @@ bool SendMouseButtonUpJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WebkitMouseButtonUp");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetInteger("x", x);
dict.SetInteger("y", y);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendMouseDoubleClickJSONRequest(
@@ -569,21 +576,21 @@ bool SendMouseDoubleClickJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WebkitMouseDoubleClick");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetInteger("x", x);
dict.SetInteger("y", y);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendWebKeyEventJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
const WebKeyEvent& key_event,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "SendWebkitKeyEvent");
locator.UpdateDictionary(&dict, "auto_id");
@@ -595,7 +602,7 @@ bool SendWebKeyEventJSONRequest(
dict.SetInteger("modifiers", key_event.modifiers);
dict.SetBoolean("isSystemKey", false);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendNativeKeyEventJSONRequest(
@@ -603,14 +610,14 @@ bool SendNativeKeyEventJSONRequest(
const WebViewLocator& locator,
ui::KeyboardCode key_code,
int modifiers,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "SendOSLevelKeyEventToTab");
locator.UpdateDictionary(&dict, "auto_id");
dict.SetInteger("keyCode", key_code);
dict.SetInteger("modifiers", modifiers);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendDragAndDropFilePathsJSONRequest(
@@ -619,7 +626,7 @@ bool SendDragAndDropFilePathsJSONRequest(
int x,
int y,
const std::vector<FilePath::StringType>& paths,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "DragAndDropFilePaths");
locator.UpdateDictionary(&dict, "auto_id");
@@ -633,17 +640,17 @@ bool SendDragAndDropFilePathsJSONRequest(
dict.Set("paths", list_value);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendGetAppModalDialogMessageJSONRequest(
AutomationMessageSender* sender,
std::string* message,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GetAppModalDialogMessage");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
return reply_dict.GetString("message", message);
}
@@ -651,43 +658,43 @@ bool SendGetAppModalDialogMessageJSONRequest(
bool SendAcceptOrDismissAppModalDialogJSONRequest(
AutomationMessageSender* sender,
bool accept,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "AcceptOrDismissAppModalDialog");
dict.SetBoolean("accept", accept);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendAcceptPromptAppModalDialogJSONRequest(
AutomationMessageSender* sender,
const std::string& prompt_text,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "AcceptOrDismissAppModalDialog");
dict.SetBoolean("accept", true);
dict.SetString("prompt_text", prompt_text);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendWaitForAllViewsToStopLoadingJSONRequest(
AutomationMessageSender* sender,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "WaitForAllTabsToStopLoading");
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendGetChromeDriverAutomationVersion(
AutomationMessageSender* sender,
int* version,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GetChromeDriverAutomationVersion");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
return reply_dict.GetInteger("version", version);
}
@@ -697,16 +704,16 @@ bool SendInstallExtensionJSONRequest(
const FilePath& path,
bool with_ui,
std::string* extension_id,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "InstallExtension");
dict.SetString("path", path.value());
dict.SetBoolean("with_ui", with_ui);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
if (!reply_dict.GetString("id", extension_id)) {
- *error_msg = "Missing or invalid 'id'";
+ *error = Error("Missing or invalid 'id'");
return false;
}
return true;
@@ -715,15 +722,15 @@ bool SendInstallExtensionJSONRequest(
bool SendGetExtensionsInfoJSONRequest(
AutomationMessageSender* sender,
ListValue* extensions_list,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "GetExtensionsInfo");
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
ListValue* extensions_list_swap;
if (!reply_dict.GetList("extensions", &extensions_list_swap)) {
- *error_msg = "Missing or invalid 'extensions'";
+ *error = Error("Missing or invalid 'extensions'");
return false;
}
extensions_list->Swap(extensions_list_swap);
@@ -735,16 +742,16 @@ bool SendIsPageActionVisibleJSONRequest(
const WebViewId& tab_id,
const std::string& extension_id,
bool* is_visible,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "IsPageActionVisible");
tab_id.UpdateDictionary(&dict, "auto_id");
dict.SetString("extension_id", extension_id);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
if (!reply_dict.GetBoolean("is_visible", is_visible)) {
- *error_msg = "Missing or invalid 'is_visible'";
+ *error = Error("Missing or invalid 'is_visible'");
return false;
}
return true;
@@ -755,21 +762,21 @@ bool SendSetExtensionStateJSONRequest(
const std::string& extension_id,
bool enable,
bool allow_in_incognito,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "SetExtensionStateById");
dict.SetString("id", extension_id);
dict.SetBoolean("enable", enable);
dict.SetBoolean("allow_in_incognito", allow_in_incognito);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendClickExtensionButtonJSONRequest(
AutomationMessageSender* sender,
const std::string& extension_id,
bool browser_action,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
if (browser_action)
dict.SetString("command", "TriggerBrowserActionById");
@@ -779,26 +786,26 @@ bool SendClickExtensionButtonJSONRequest(
dict.SetInteger("windex", 0);
dict.SetInteger("tab_index", 0);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendUninstallExtensionJSONRequest(
AutomationMessageSender* sender,
const std::string& extension_id,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "UninstallExtensionById");
dict.SetString("id", extension_id);
DictionaryValue reply_dict;
- if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg))
+ if (!SendAutomationJSONRequest(sender, dict, &reply_dict, error))
return false;
bool success;
if (!reply_dict.GetBoolean("success", &success)) {
- *error_msg = "Missing or invalid 'success'";
+ *error = Error("Missing or invalid 'success'");
return false;
}
if (!success) {
- *error_msg = "Extension uninstall not permitted";
+ *error = Error("Extension uninstall not permitted");
return false;
}
return true;
@@ -808,25 +815,25 @@ bool SendSetLocalStatePreferenceJSONRequest(
AutomationMessageSender* sender,
const std::string& pref,
base::Value* value,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "SetLocalStatePrefs");
dict.SetString("path", pref);
dict.Set("value", value);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
bool SendSetPreferenceJSONRequest(
AutomationMessageSender* sender,
const std::string& pref,
base::Value* value,
- std::string* error_msg) {
+ Error* error) {
DictionaryValue dict;
dict.SetString("command", "SetPrefs");
dict.SetInteger("windex", 0);
dict.SetString("path", pref);
dict.Set("value", value);
DictionaryValue reply_dict;
- return SendAutomationJSONRequest(sender, dict, &reply_dict, error_msg);
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
diff --git a/chrome/test/automation/automation_json_requests.h b/chrome/test/automation/automation_json_requests.h
index 89b1072..4d855b1 100644
--- a/chrome/test/automation/automation_json_requests.h
+++ b/chrome/test/automation/automation_json_requests.h
@@ -170,7 +170,7 @@ bool SendGetIndicesFromTabIdJSONRequest(
int tab_id,
int* browser_index,
int* tab_index,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the current browser and tab indices for the given |TabProxy|
// handle. Returns true on success.
@@ -179,7 +179,7 @@ bool SendGetIndicesFromTabHandleJSONRequest(
int tab_proxy_handle,
int* browser_index,
int* tab_index,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to navigate to the given url and wait for the given number of
// navigations to complete. Returns true on success.
@@ -189,7 +189,7 @@ bool SendNavigateToURLJSONRequest(
const std::string& url,
int navigation_count,
AutomationMsg_NavigationResponseValues* nav_response,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the given javascript to be executed in the frame specified by the
// given xpath. Returns true on success. If true, |result| will be set to the
@@ -200,28 +200,28 @@ bool SendExecuteJavascriptJSONRequest(
const std::string& frame_xpath,
const std::string& javascript,
base::Value** result,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the specified view to go forward. Waits for the load to complete.
// Returns true on success.
bool SendGoForwardJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the specified view to go back. Waits for the load to complete.
// Returns true on success.
bool SendGoBackJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the specified view to reload. Waits for the load to complete.
// Returns true on success.
bool SendReloadJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests a snapshot of the entire page to be saved to the given path
// in PNG format.
@@ -230,7 +230,7 @@ bool SendCaptureEntirePageJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
const FilePath& path,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests all the cookies for the given URL. On success returns true and
// caller takes ownership of |cookies|, which is a list of all the cookies in
@@ -239,7 +239,7 @@ bool SendGetCookiesJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
base::ListValue** cookies,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests deletion of the cookie with the given name and URL. Returns true
// on success.
@@ -247,7 +247,7 @@ bool SendDeleteCookieJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
const std::string& cookie_name,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests setting the given cookie for the given URL. Returns true on
// success. The caller retains ownership of |cookie_dict|.
@@ -255,26 +255,26 @@ bool SendSetCookieJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
base::DictionaryValue* cookie_dict,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the IDs for all open tabs. Returns true on success.
bool SendGetTabIdsJSONRequest(
AutomationMessageSender* sender,
std::vector<WebViewInfo>* views,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests info for all open views. Returns true on success.
bool SendGetWebViewsJSONRequest(
AutomationMessageSender* sender,
std::vector<WebViewInfo>* views,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests whether the given tab ID is valid. Returns true on success.
bool SendIsTabIdValidJSONRequest(
AutomationMessageSender* sender,
const WebViewId& view_id,
bool* is_valid,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests whether the given automation ID refers to an actual automation
// object. Returns true on success.
@@ -282,13 +282,13 @@ bool SendDoesAutomationObjectExistJSONRequest(
AutomationMessageSender* sender,
const WebViewId& view_id,
bool* does_exist,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to close the given view. Returns true on success.
bool SendCloseViewJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit event for a mouse move to the given
// coordinate in the specified view. Returns true on success.
@@ -297,7 +297,7 @@ bool SendMouseMoveJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit events for a mouse click at the given
// coordinate in the specified view. Returns true on success.
@@ -307,7 +307,7 @@ bool SendMouseClickJSONRequest(
automation::MouseButton button,
int x,
int y,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit events for a mouse drag from the start to end
// coordinates given in the specified view. Returns true on success.
@@ -318,7 +318,7 @@ bool SendMouseDragJSONRequest(
int start_y,
int end_x,
int end_y,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit event for a mouse button down at the given
// coordinate in the specified view. Returns true on success.
@@ -327,7 +327,7 @@ bool SendMouseButtonDownJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit event for a mouse button up at the given
// coordinate in the specified view. Returns true on success.
@@ -336,7 +336,7 @@ bool SendMouseButtonUpJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit event for a mouse double click at the given
// coordinate in the specified view. Returns true on success.
@@ -345,7 +345,7 @@ bool SendMouseDoubleClickJSONRequest(
const WebViewLocator& locator,
int x,
int y,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the WebKit event for the given |WebKeyEvent| in a
// specified view. Returns true on success.
@@ -353,7 +353,7 @@ bool SendWebKeyEventJSONRequest(
AutomationMessageSender* sender,
const WebViewLocator& locator,
const WebKeyEvent& key_event,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to send the key event for the given keycode+modifiers to a
// browser window containing the specified view. Returns true on success.
@@ -362,7 +362,7 @@ bool SendNativeKeyEventJSONRequest(
const WebViewLocator& locator,
ui::KeyboardCode key_code,
int modifiers,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to drag and drop the file paths at the given coordinate in the
// specified view. Returns true on success.
@@ -372,40 +372,40 @@ bool SendDragAndDropFilePathsJSONRequest(
int x,
int y,
const std::vector<FilePath::StringType>& paths,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to get the active JavaScript modal dialog's message. Returns true
// on success.
bool SendGetAppModalDialogMessageJSONRequest(
AutomationMessageSender* sender,
std::string* message,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to accept or dismiss the active JavaScript modal dialog.
// Returns true on success.
bool SendAcceptOrDismissAppModalDialogJSONRequest(
AutomationMessageSender* sender,
bool accept,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to accept the active JavaScript modal dialog with the given prompt
// text. Returns true on success.
bool SendAcceptPromptAppModalDialogJSONRequest(
AutomationMessageSender* sender,
const std::string& prompt_text,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests to wait for all views to stop loading. Returns true on success.
bool SendWaitForAllViewsToStopLoadingJSONRequest(
AutomationMessageSender* sender,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the version of ChromeDriver automation supported by the automation
// server. Returns true on success.
bool SendGetChromeDriverAutomationVersion(
AutomationMessageSender* sender,
int* version,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests that the given extension be installed. If |with_ui| is false,
// the extension will be installed silently. Returns true on success.
@@ -414,13 +414,13 @@ bool SendInstallExtensionJSONRequest(
const FilePath& path,
bool with_ui,
std::string* extension_id,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests info about all installed extensions. Returns true on success.
bool SendGetExtensionsInfoJSONRequest(
AutomationMessageSender* sender,
base::ListValue* extensions_list,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests whether the given extension's page action is visible in the
// given tab.
@@ -429,7 +429,7 @@ bool SendIsPageActionVisibleJSONRequest(
const WebViewId& tab_id,
const std::string& extension_id,
bool* is_visible,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests a modification of the given extension state. Returns true on
// success.
@@ -438,7 +438,7 @@ bool SendSetExtensionStateJSONRequest(
const std::string& extension_id,
bool enable,
bool allow_in_incognito,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the given extension's action button be pressed. Returns true on
// success.
@@ -446,13 +446,13 @@ bool SendClickExtensionButtonJSONRequest(
AutomationMessageSender* sender,
const std::string& extension_id,
bool browser_action,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the given extension be uninstalled. Returns true on success.
bool SendUninstallExtensionJSONRequest(
AutomationMessageSender* sender,
const std::string& extension_id,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the local state preference to be set to the given value.
// Ownership of |value| is taken by this function. Returns true on success.
@@ -460,7 +460,7 @@ bool SendSetLocalStatePreferenceJSONRequest(
AutomationMessageSender* sender,
const std::string& pref,
base::Value* value,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
// Requests the user preference to be set to the given value.
// Ownership of |value| is taken by this function. Returns true on success.
@@ -468,6 +468,6 @@ bool SendSetPreferenceJSONRequest(
AutomationMessageSender* sender,
const std::string& pref,
base::Value* value,
- std::string* error_msg) WARN_UNUSED_RESULT;
+ automation::Error* error) WARN_UNUSED_RESULT;
#endif // CHROME_TEST_AUTOMATION_AUTOMATION_JSON_REQUESTS_H_
diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc
index b24c23c..094fee3 100644
--- a/chrome/test/automation/tab_proxy.cc
+++ b/chrome/test/automation/tab_proxy.cc
@@ -11,6 +11,7 @@
#include "base/string16.h"
#include "base/threading/platform_thread.h"
#include "base/utf_string_conversions.h"
+#include "chrome/common/automation_constants.h"
#include "chrome/common/automation_messages.h"
#include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/automation/automation_proxy.h"
@@ -723,15 +724,15 @@ bool TabProxy::CaptureEntirePageAsPNG(const FilePath& path) {
return false;
int browser_index, tab_index;
- std::string error_msg;
+ automation::Error error;
if (!SendGetIndicesFromTabHandleJSONRequest(
- sender_, handle_, &browser_index, &tab_index, &error_msg)) {
+ sender_, handle_, &browser_index, &tab_index, &error)) {
return false;
}
return SendCaptureEntirePageJSONRequest(
sender_, WebViewLocator::ForIndexPair(browser_index, tab_index),
- path, &error_msg);
+ path, &error);
}
#if defined(OS_WIN) && !defined(USE_AURA)
diff --git a/chrome/test/webdriver/test/chromedriver_tests.py b/chrome/test/webdriver/test/chromedriver_tests.py
index cae9772..1666f5a 100644
--- a/chrome/test/webdriver/test/chromedriver_tests.py
+++ b/chrome/test/webdriver/test/chromedriver_tests.py
@@ -815,6 +815,18 @@ class AlertTest(ChromeDriverTest):
driver.get(self.GetTestDataUrl() + '/alerts.html')
self.assertRaises(WebDriverException, driver.execute_script, 'alert("ok")')
+ # See http://code.google.com/p/selenium/issues/detail?id=2671.
+ def testCanPerformJSBasedActionsThatCauseAlertsAtTheEnd(self):
+ driver = self.GetNewDriver()
+ driver.execute_script(
+ 'var select = document.createElement("select");' +
+ 'select.innerHTML = "<option>1</option><option>2</option>";' +
+ 'select.addEventListener("change", function() { alert("hi"); });' +
+ 'document.body.appendChild(select);')
+
+ # Shouldn't throw an exception, even though an alert appears mid-script.
+ driver.find_elements_by_tag_name('option')[-1].click()
+
def testMustHandleAlertFirst(self):
driver = self.GetNewDriver()
driver.get(self.GetTestDataUrl() + '/alerts.html')
diff --git a/chrome/test/webdriver/webdriver_automation.cc b/chrome/test/webdriver/webdriver_automation.cc
index 7334c16..80e25c5 100644
--- a/chrome/test/webdriver/webdriver_automation.cc
+++ b/chrome/test/webdriver/webdriver_automation.cc
@@ -286,10 +286,10 @@ void Automation::Init(const BrowserOptions& options, Error** error) {
// Check the version of Chrome is compatible with this ChromeDriver.
chrome_details += ", version (" + automation()->server_version() + ")";
int version = 0;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendGetChromeDriverAutomationVersion(
- automation(), &version, &error_msg)) {
- *error = new Error(kUnknownError, error_msg + " " + chrome_details);
+ automation(), &version, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
return;
}
if (version > automation::kChromeDriverAutomationVersion) {
@@ -335,11 +335,11 @@ void Automation::ExecuteScript(const WebViewId& view_id,
return;
Value* unscoped_value;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendExecuteJavascriptJSONRequest(automation(), view_locator,
frame_path.value(), script,
- &unscoped_value, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ &unscoped_value, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
return;
}
scoped_ptr<Value> value(unscoped_value);
@@ -355,11 +355,11 @@ void Automation::MouseMove(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendMouseMoveJSONRequest(
automation(), view_locator, p.rounded_x(), p.rounded_y(),
- &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -372,11 +372,11 @@ void Automation::MouseClick(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendMouseClickJSONRequest(
automation(), view_locator, button, p.rounded_x(),
- p.rounded_y(), &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ p.rounded_y(), &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -389,11 +389,11 @@ void Automation::MouseDrag(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendMouseDragJSONRequest(
automation(), view_locator, start.rounded_x(), start.rounded_y(),
- end.rounded_x(), end.rounded_y(), &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ end.rounded_x(), end.rounded_y(), &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -409,11 +409,11 @@ void Automation::MouseButtonUp(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendMouseButtonUpJSONRequest(
automation(), view_locator, p.rounded_x(), p.rounded_y(),
- &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -429,11 +429,11 @@ void Automation::MouseButtonDown(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendMouseButtonDownJSONRequest(
automation(), view_locator, p.rounded_x(), p.rounded_y(),
- &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -449,11 +449,11 @@ void Automation::MouseDoubleClick(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendMouseDoubleClickJSONRequest(
automation(), view_locator, p.rounded_x(), p.rounded_y(),
- &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -466,11 +466,11 @@ void Automation::DragAndDropFilePaths(
return;
}
- std::string error_msg;
+ automation::Error auto_error;
if (!SendDragAndDropFilePathsJSONRequest(
automation(), view_locator, location.rounded_x(),
- location.rounded_y(), paths, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ location.rounded_y(), paths, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -482,10 +482,10 @@ void Automation::SendWebKeyEvent(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendWebKeyEventJSONRequest(
- automation(), view_locator, key_event, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), view_locator, key_event, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -498,10 +498,10 @@ void Automation::SendNativeKeyEvent(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendNativeKeyEventJSONRequest(
- automation(), view_locator, key_code, modifiers, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), view_locator, key_code, modifiers, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -513,10 +513,10 @@ void Automation::CaptureEntirePageAsPNG(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendCaptureEntirePageJSONRequest(
- automation(), view_locator, path, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), view_locator, path, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -529,11 +529,11 @@ void Automation::NavigateToURL(const WebViewId& view_id,
return;
AutomationMsg_NavigationResponseValues navigate_response;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendNavigateToURLJSONRequest(automation(), view_locator,
url, 1, &navigate_response,
- &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
return;
}
// TODO(kkania): Do not rely on this enum.
@@ -549,12 +549,12 @@ void Automation::NavigateToURLAsync(const WebViewId& view_id,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!view_id.old_style()) {
AutomationMsg_NavigationResponseValues navigate_response;
if (!SendNavigateToURLJSONRequest(automation(), view_locator, url,
- 0, &navigate_response, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ 0, &navigate_response, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
return;
}
} else {
@@ -582,10 +582,10 @@ void Automation::GoForward(const WebViewId& view_id, Error** error) {
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendGoForwardJSONRequest(
- automation(), view_locator, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), view_locator, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -595,9 +595,9 @@ void Automation::GoBack(const WebViewId& view_id, Error** error) {
if (*error)
return;
- std::string error_msg;
- if (!SendGoBackJSONRequest(automation(), view_locator, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendGoBackJSONRequest(automation(), view_locator, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::Reload(const WebViewId& view_id, Error** error) {
@@ -606,35 +606,35 @@ void Automation::Reload(const WebViewId& view_id, Error** error) {
if (*error)
return;
- std::string error_msg;
- if (!SendReloadJSONRequest(automation(), view_locator, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendReloadJSONRequest(automation(), view_locator, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::GetCookies(const std::string& url,
ListValue** cookies,
Error** error) {
- std::string error_msg;
- if (!SendGetCookiesJSONRequest(automation(), url, cookies, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendGetCookiesJSONRequest(automation(), url, cookies, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::DeleteCookie(const std::string& url,
const std::string& cookie_name,
Error** error) {
- std::string error_msg;
+ automation::Error auto_error;
if (!SendDeleteCookieJSONRequest(
- automation(), url, cookie_name, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), url, cookie_name, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
void Automation::SetCookie(const std::string& url,
DictionaryValue* cookie_dict,
Error** error) {
- std::string error_msg;
- if (!SendSetCookieJSONRequest(automation(), url, cookie_dict, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendSetCookieJSONRequest(automation(), url, cookie_dict, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::GetViews(std::vector<WebViewInfo>* views,
@@ -644,27 +644,27 @@ void Automation::GetViews(std::vector<WebViewInfo>* views,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (has_views) {
- if (!SendGetWebViewsJSONRequest(automation(), views, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ if (!SendGetWebViewsJSONRequest(automation(), views, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
} else {
- if (!SendGetTabIdsJSONRequest(automation(), views, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ if (!SendGetTabIdsJSONRequest(automation(), views, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
}
void Automation::DoesViewExist(
const WebViewId& view_id, bool* does_exist, Error** error) {
- std::string error_msg;
+ automation::Error auto_error;
if (view_id.old_style()) {
if (!SendIsTabIdValidJSONRequest(
- automation(), view_id, does_exist, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), view_id, does_exist, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
} else {
if (!SendDoesAutomationObjectExistJSONRequest(
- automation(), view_id, does_exist, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), view_id, does_exist, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -674,9 +674,9 @@ void Automation::CloseView(const WebViewId& view_id, Error** error) {
if (*error)
return;
- std::string error_msg;
- if (!SendCloseViewJSONRequest(automation(), view_locator, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendCloseViewJSONRequest(automation(), view_locator, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::GetAppModalDialogMessage(std::string* message, Error** error) {
@@ -684,10 +684,10 @@ void Automation::GetAppModalDialogMessage(std::string* message, Error** error) {
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendGetAppModalDialogMessageJSONRequest(
- automation(), message, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), message, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -696,10 +696,10 @@ void Automation::AcceptOrDismissAppModalDialog(bool accept, Error** error) {
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendAcceptOrDismissAppModalDialogJSONRequest(
- automation(), accept, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), accept, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -709,10 +709,10 @@ void Automation::AcceptPromptAppModalDialog(const std::string& prompt_text,
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendAcceptPromptAppModalDialogJSONRequest(
- automation(), prompt_text, &error_msg)) {
- *error = new Error(kUnknownError, error_msg);
+ automation(), prompt_text, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
}
}
@@ -721,15 +721,15 @@ void Automation::GetBrowserVersion(std::string* version) {
}
void Automation::GetChromeDriverAutomationVersion(int* version, Error** error) {
- std::string error_msg;
- if (!SendGetChromeDriverAutomationVersion(automation(), version, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendGetChromeDriverAutomationVersion(automation(), version, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::WaitForAllViewsToStopLoading(Error** error) {
- std::string error_msg;
- if (!SendWaitForAllViewsToStopLoadingJSONRequest(automation(), &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation::Error auto_error;
+ if (!SendWaitForAllViewsToStopLoadingJSONRequest(automation(), &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::InstallExtensionDeprecated(
@@ -744,11 +744,11 @@ void Automation::InstallExtension(
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendInstallExtensionJSONRequest(
automation(), path, false /* with_ui */, extension_id,
- &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::GetExtensionsInfo(
@@ -757,10 +757,10 @@ void Automation::GetExtensionsInfo(
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendGetExtensionsInfoJSONRequest(
- automation(), extensions_list, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), extensions_list, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::IsPageActionVisible(
@@ -772,10 +772,10 @@ void Automation::IsPageActionVisible(
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendIsPageActionVisibleJSONRequest(
- automation(), tab_id, extension_id, is_visible, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), tab_id, extension_id, is_visible, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::SetExtensionState(
@@ -786,21 +786,21 @@ void Automation::SetExtensionState(
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendSetExtensionStateJSONRequest(
automation(), extension_id, enable /* enable */,
- false /* allow_in_incognito */, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ false /* allow_in_incognito */, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::ClickExtensionButton(
const std::string& extension_id,
bool browser_action,
Error** error) {
- std::string error_msg;
+ automation::Error auto_error;
if (!SendClickExtensionButtonJSONRequest(
- automation(), extension_id, browser_action, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), extension_id, browser_action, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::UninstallExtension(
@@ -809,10 +809,10 @@ void Automation::UninstallExtension(
if (*error)
return;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendUninstallExtensionJSONRequest(
- automation(), extension_id, &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), extension_id, &auto_error))
+ *error = Error::FromAutomationError(auto_error);
}
void Automation::SetLocalStatePreference(const std::string& pref,
@@ -827,10 +827,10 @@ void Automation::SetLocalStatePreference(const std::string& pref,
return;
if (has_new_local_state_api) {
- std::string error_msg;
+ automation::Error auto_error;
if (!SendSetLocalStatePreferenceJSONRequest(
- automation(), pref, scoped_value.release(), &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), pref, scoped_value.release(), &auto_error))
+ *error = Error::FromAutomationError(auto_error);
} else {
std::string request, response;
DictionaryValue request_dict;
@@ -858,10 +858,10 @@ void Automation::SetPreference(const std::string& pref,
return;
if (has_new_pref_api) {
- std::string error_msg;
+ automation::Error auto_error;
if (!SendSetPreferenceJSONRequest(
- automation(), pref, scoped_value.release(), &error_msg))
- *error = new Error(kUnknownError, error_msg);
+ automation(), pref, scoped_value.release(), &auto_error))
+ *error = Error::FromAutomationError(auto_error);
} else {
std::string request, response;
DictionaryValue request_dict;
@@ -886,11 +886,11 @@ Error* Automation::ConvertViewIdToLocator(
const WebViewId& view_id, WebViewLocator* view_locator) {
if (view_id.old_style()) {
int browser_index, tab_index;
- std::string error_msg;
+ automation::Error auto_error;
if (!SendGetIndicesFromTabIdJSONRequest(
automation(), view_id.tab_id(), &browser_index, &tab_index,
- &error_msg))
- return new Error(kUnknownError, error_msg);
+ &auto_error))
+ return Error::FromAutomationError(auto_error);
*view_locator = WebViewLocator::ForIndexPair(browser_index, tab_index);
} else {
*view_locator = WebViewLocator::ForViewId(view_id.GetId());
diff --git a/chrome/test/webdriver/webdriver_error.cc b/chrome/test/webdriver/webdriver_error.cc
index 200d797..0884e10 100644
--- a/chrome/test/webdriver/webdriver_error.cc
+++ b/chrome/test/webdriver/webdriver_error.cc
@@ -6,6 +6,8 @@
#include <sstream>
+#include "chrome/common/automation_constants.h"
+
namespace webdriver {
namespace {
@@ -39,6 +41,10 @@ const char* DefaultMessageForErrorCode(ErrorCode code) {
return "The cookie domain is invalid";
case kUnableToSetCookie:
return "Unable to set cookie";
+ case kUnexpectedAlertOpen:
+ return "An open modal dialog blocked the operation";
+ case kNoAlertOpenError:
+ return "No JavaScript modal dialog is open";
default:
return "<unknown>";
}
@@ -46,6 +52,46 @@ const char* DefaultMessageForErrorCode(ErrorCode code) {
} // namespace
+// static
+Error* Error::FromAutomationError(const automation::Error& error) {
+ ErrorCode code = kUnknownError;
+ switch (error.code()) {
+ case automation::kNoJavaScriptModalDialogOpen:
+ code = kNoAlertOpenError;
+ break;
+ case automation::kBlockedByModalDialog:
+ code = kUnexpectedAlertOpen;
+ break;
+ default:
+ break;
+ }
+
+ // In Chrome 17 and before, the automation error was just a string.
+ // Compare against some strings that correspond to webdriver errors.
+ // TODO(kkania): Remove these comparisons when Chrome 17 is unsupported.
+ if (code == kUnknownError) {
+ if (error.message() ==
+ "Command cannot be performed because a modal dialog is active" ||
+ error.message() ==
+ "Could not complete script execution because a modal "
+ "dialog is active") {
+ code = kUnexpectedAlertOpen;
+ } else if (error.message() == "No modal dialog is showing" ||
+ error.message() == "No JavaScript modal dialog is showing") {
+ code = kNoAlertOpenError;
+ }
+ }
+
+ // If the automation error code did not refer to a webdriver error code
+ // (besides unknown), include the error message from chrome. Otherwise,
+ // include the webdriver error code and the webdriver error message.
+ if (code == kUnknownError) {
+ return new Error(code, error.message());
+ } else {
+ return new Error(code);
+ }
+}
+
Error::Error(ErrorCode code)
: code_(code),
details_(DefaultMessageForErrorCode(code)) {
diff --git a/chrome/test/webdriver/webdriver_error.h b/chrome/test/webdriver/webdriver_error.h
index 0ed0c51..dbc7229d 100644
--- a/chrome/test/webdriver/webdriver_error.h
+++ b/chrome/test/webdriver/webdriver_error.h
@@ -10,6 +10,10 @@
#include "base/basictypes.h"
+namespace automation {
+class Error;
+}
+
namespace webdriver {
// Error codes defined by the WebDriver wire protcol.
@@ -28,6 +32,8 @@ enum ErrorCode {
kNoSuchWindow = 23,
kInvalidCookieDomain = 24,
kUnableToSetCookie = 25,
+ kUnexpectedAlertOpen = 26,
+ kNoAlertOpenError = 27,
// HTTP status codes.
kSeeOther = 303,
@@ -40,6 +46,8 @@ enum ErrorCode {
// Represents a WebDriver error and the context within which the error occurred.
class Error {
public:
+ static Error* FromAutomationError(const automation::Error& error);
+
explicit Error(ErrorCode code);
Error(ErrorCode code, const std::string& details);
diff --git a/chrome/test/webdriver/webdriver_session.cc b/chrome/test/webdriver/webdriver_session.cc
index e1a25c6..c5b1c16 100644
--- a/chrome/test/webdriver/webdriver_session.cc
+++ b/chrome/test/webdriver/webdriver_session.cc
@@ -921,12 +921,22 @@ Error* Session::IsOptionElementSelected(const FrameId& frame_id,
Error* Session::SetOptionElementSelected(const FrameId& frame_id,
const ElementId& element,
bool selected) {
- return ExecuteScriptAndParse(
+ // This wrapper ensures the script is started successfully and
+ // allows for an alert to happen when the option selection occurs.
+ // See selenium bug 2671.
+ const char kSetSelectedWrapper[] =
+ "var args = [].slice.apply(arguments);"
+ "args[args.length - 1]();"
+ "return (%s).apply(null, args.slice(0, args.length - 1));";
+ Value* value = NULL;
+ Error* error = ExecuteAsyncScript(
frame_id,
- atoms::asString(atoms::SET_SELECTED),
- "setSelected",
+ base::StringPrintf(kSetSelectedWrapper,
+ atoms::asString(atoms::SET_SELECTED).c_str()),
CreateListValueFrom(element, selected),
- CreateDirectValueParser(kSkipParsing));
+ &value);
+ scoped_ptr<Value> scoped_value(value);
+ return error;
}
Error* Session::ToggleOptionElement(const FrameId& frame_id,