Chromium Code Reviews| Index: chrome/test/webdriver/commands/webelement_commands.cc |
| diff --git a/chrome/test/webdriver/commands/webelement_commands.cc b/chrome/test/webdriver/commands/webelement_commands.cc |
| index dae3e4eba697cf4ea7397069c73313c502834cbb..b6875b699943e39bd1ffd03706d015fb66ae9d6b 100644 |
| --- a/chrome/test/webdriver/commands/webelement_commands.cc |
| +++ b/chrome/test/webdriver/commands/webelement_commands.cc |
| @@ -4,7 +4,9 @@ |
| #include "chrome/test/webdriver/commands/webelement_commands.h" |
| +#include "base/file_util.h" |
| #include "base/memory/scoped_ptr.h" |
| +#include "base/string_util.h" |
| #include "base/stringprintf.h" |
| #include "base/third_party/icu/icu_utf.h" |
| #include "base/values.h" |
| @@ -44,6 +46,44 @@ bool WebElementCommand::Init(Response* const response) { |
| return true; |
| } |
| +Error* WebElementCommand::GetAttribute(const std::string& key, |
| + Value** value) const { |
| + std::string script = base::StringPrintf( |
| + "return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE); |
| + |
| + scoped_ptr<ListValue> args(new ListValue); |
|
kkania
2011/05/27 20:48:47
don't use scoped_ptr here; just allocate it on the
nodchip
2011/05/30 04:51:45
Done.
|
| + args->Append(element.ToValue()); |
| + args->Append(Value::CreateStringValue(key)); |
| + |
| + Error* error = session_->ExecuteScript(script, args.get(), value); |
| + if (error) { |
| + return error; |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| +Error* WebElementCommand::GetClickableLocation(gfx::Point* location) const { |
| + Error* error = session_->CheckElementPreconditionsForClicking(element); |
| + if (error) { |
| + return error; |
| + } |
| + |
| + error = session_->GetElementLocationInView(element, location); |
| + if (error) { |
| + return error; |
| + } |
| + |
| + gfx::Size size; |
| + error = session_->GetElementSize(session_->current_target(), element, &size); |
| + if (error) { |
| + return error; |
| + } |
| + |
| + location->Offset(size.width() / 2, size.height() / 2); |
| + return NULL; |
| +} |
| + |
| ///////////////////// ElementAttributeCommand //////////////////// |
| ElementAttributeCommand::ElementAttributeCommand( |
| @@ -65,20 +105,15 @@ void ElementAttributeCommand::ExecuteGet(Response* const response) { |
| return; |
| } |
| - std::string script = base::StringPrintf( |
| - "return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE); |
| - |
| - ListValue args; |
| - args.Append(element.ToValue()); |
| - args.Append(Value::CreateStringValue(path_segments_.at(6))); |
| - |
| - Value* result = NULL; |
| - Error* error = session_->ExecuteScript(script, &args, &result); |
| + const std::string key = path_segments_.at(6); |
| + Value* value; |
| + Error* error = GetAttribute(key, &value); |
| if (error) { |
| response->SetError(error); |
| return; |
| } |
| - response->SetValue(result); |
| + |
| + response->SetValue(value); |
| } |
| ///////////////////// ElementClearCommand //////////////////// |
| @@ -498,12 +533,97 @@ void ElementValueCommand::ExecuteGet(Response* const response) { |
| } |
| void ElementValueCommand::ExecutePost(Response* const response) { |
| + bool is_input = false; |
| + Error* error = HasAttribute("tagName", "input", &is_input); |
| + if (error) { |
| + response->SetError(error); |
| + return; |
| + } |
| + |
| + bool is_file = false; |
| + error = HasAttribute("type", "file", &is_file); |
| + if (error) { |
| + response->SetError(error); |
| + return; |
| + } |
| + |
| + // If the element is a file upload control, set the file paths to the element. |
| + // Otherwise send the value to the element as key input. |
| + if (is_input && is_file) { |
| + error = DragAndDropFilePaths(); |
| + } else { |
| + error = SendKeys(); |
| + } |
| + |
| + if (error) { |
| + response->SetError(error); |
| + return; |
| + } |
| + |
| + response->SetStatus(kSuccess); |
| +} |
| + |
| +Error* ElementValueCommand::HasAttribute(const std::string& key, |
|
kkania
2011/05/27 20:48:47
HasAttribute sounds a bit misleading to me. How ab
nodchip
2011/05/30 04:51:45
Done.
|
| + const std::string& value, |
| + bool* result) const { |
| + Value* unscoped_value = NULL; |
| + Error* error = GetAttribute(key, &unscoped_value); |
| + scoped_ptr<Value> scoped_value(unscoped_value); |
| + unscoped_value = NULL; |
| + |
| + if (error) { |
| + return error; |
| + } |
| + |
| + if (!scoped_value.get()) { |
|
kkania
2011/05/27 20:48:47
can this ever happen? I thought ExecuteScript neve
nodchip
2011/05/30 04:51:45
Done.
|
| + *result = false; |
| + return NULL; |
| + } |
| + |
| + std::string actual_value; |
| + if (!scoped_value->GetAsString(&actual_value)) { |
|
kkania
2011/05/27 20:48:47
could scoped_value be TYPE_NULL?
nodchip
2011/05/30 04:51:45
Done. I added a type check.
|
| + return new Error(kUnknownError, "Could not get the attribute value"); |
| + } |
| + |
| + *result = LowerCaseEqualsASCII(actual_value, value.c_str()); |
| + return NULL; |
| +} |
| + |
| +Error* ElementValueCommand::DragAndDropFilePaths() const { |
| + ListValue* path_list; |
| + if (!GetListParameter("value", &path_list)) { |
| + return new Error(kBadRequest, "Missing or invalid 'value' parameter"); |
| + } |
| + |
| + std::vector<std::string> paths; |
| + for (size_t i = 0; i < path_list->GetSize(); ++i) { |
| + std::string path; |
| + if (!path_list->GetString(i, &path)) { |
| + return new Error(kBadRequest, "Invalid element in 'value' parameter"); |
| + } |
| + |
| + if (!file_util::PathExists(FilePath(path))) { |
|
kkania
2011/05/27 20:48:47
you can't make a file path with a std::string on w
nodchip
2011/05/30 04:51:45
Done.
|
| + return new Error(kBadRequest, "Path does not exist"); |
| + } |
| + |
| + paths.push_back(path); |
| + } |
| + |
| + gfx::Point location; |
| + Error* error = GetClickableLocation(&location); |
| + if (error) { |
| + return error; |
| + } |
| + |
| + return session_->DragAndDropFilePaths(location, paths); |
| +} |
| + |
| +Error* ElementValueCommand::SendKeys() const { |
| ListValue* key_list; |
| if (!GetListParameter("value", &key_list)) { |
| - response->SetError(new Error( |
| - kBadRequest, "Missing or invalid 'value' parameter")); |
| - return; |
| + return new Error(kBadRequest, "Missing or invalid 'value' parameter"); |
| } |
| + |
| // Flatten the given array of strings into one. |
| string16 keys; |
| for (size_t i = 0; i < key_list->GetSize(); ++i) { |
| @@ -511,17 +631,14 @@ 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])) { |
| - response->SetError(new Error( |
| - kBadRequest, "ChromeDriver only supports characters in the BMP")); |
| - return; |
| + return new Error(kBadRequest, |
| + "ChromeDriver only supports characters in the BMP"); |
| } |
| } |
| keys.append(keys_list_part); |
| } |
| - Error* error = session_->SendKeys(element, keys); |
| - if (error) |
| - response->SetError(error); |
| + return session_->SendKeys(element, keys); |
| } |
| ///////////////////// ElementTextCommand //////////////////// |