summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchrisgao@chromium.org <chrisgao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-01 16:28:33 +0000
committerchrisgao@chromium.org <chrisgao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-01 16:28:33 +0000
commit0b4468ed16cf93bac23d5abf3ef39e400665d694 (patch)
treef6b9c65b60fb7c3b5b54c4141bb6554128e52513
parenta1129f2eb6d0cb85284c427b09a4cb6fd5e4312e (diff)
downloadchromium_src-0b4468ed16cf93bac23d5abf3ef39e400665d694.zip
chromium_src-0b4468ed16cf93bac23d5abf3ef39e400665d694.tar.gz
chromium_src-0b4468ed16cf93bac23d5abf3ef39e400665d694.tar.bz2
[chromedriver] Implement file upload in SendKeys command.
BUG=chromedriver:276, chromedriver:154 Review URL: https://chromiumcodereview.appspot.com/13127002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191615 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/chromedriver/chrome/chrome.h2
-rw-r--r--chrome/test/chromedriver/chrome/chrome_impl.cc4
-rw-r--r--chrome/test/chromedriver/chrome/chrome_impl.h1
-rw-r--r--chrome/test/chromedriver/chrome/stub_chrome.cc4
-rw-r--r--chrome/test/chromedriver/chrome/stub_chrome.h1
-rw-r--r--chrome/test/chromedriver/chrome/stub_web_view.cc6
-rw-r--r--chrome/test/chromedriver/chrome/stub_web_view.h3
-rw-r--r--chrome/test/chromedriver/chrome/web_view.h7
-rw-r--r--chrome/test/chromedriver/chrome/web_view_impl.cc23
-rw-r--r--chrome/test/chromedriver/chrome/web_view_impl.h3
-rw-r--r--chrome/test/chromedriver/element_commands.cc44
11 files changed, 96 insertions, 2 deletions
diff --git a/chrome/test/chromedriver/chrome/chrome.h b/chrome/test/chromedriver/chrome/chrome.h
index 1e64cdf..854027a 100644
--- a/chrome/test/chromedriver/chrome/chrome.h
+++ b/chrome/test/chromedriver/chrome/chrome.h
@@ -17,6 +17,8 @@ class Chrome {
virtual std::string GetVersion() = 0;
+ virtual int GetBuildNo() = 0;
+
// Return ids of opened WebViews in the same order as they are opened.
virtual Status GetWebViewIds(std::list<std::string>* web_view_ids) = 0;
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.cc b/chrome/test/chromedriver/chrome/chrome_impl.cc
index c5d266c..f7b0d7e 100644
--- a/chrome/test/chromedriver/chrome/chrome_impl.cc
+++ b/chrome/test/chromedriver/chrome/chrome_impl.cc
@@ -211,6 +211,10 @@ std::string ChromeImpl::GetVersion() {
return version_;
}
+int ChromeImpl::GetBuildNo() {
+ return build_no_;
+}
+
Status ChromeImpl::GetWebViewIds(std::list<std::string>* web_view_ids) {
WebViewInfoList info_list;
Status status = FetchWebViewsInfo(
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.h b/chrome/test/chromedriver/chrome/chrome_impl.h
index d9f3217..161d477 100644
--- a/chrome/test/chromedriver/chrome/chrome_impl.h
+++ b/chrome/test/chromedriver/chrome/chrome_impl.h
@@ -30,6 +30,7 @@ class ChromeImpl : public Chrome, public WebViewDelegate {
// Overridden from Chrome:
virtual std::string GetVersion() OVERRIDE;
+ virtual int GetBuildNo() OVERRIDE;
virtual Status GetWebViewIds(std::list<std::string>* web_view_ids) OVERRIDE;
virtual Status GetWebViewById(const std::string& id,
WebView** web_view) OVERRIDE;
diff --git a/chrome/test/chromedriver/chrome/stub_chrome.cc b/chrome/test/chromedriver/chrome/stub_chrome.cc
index 56b565f..642e9cd 100644
--- a/chrome/test/chromedriver/chrome/stub_chrome.cc
+++ b/chrome/test/chromedriver/chrome/stub_chrome.cc
@@ -14,6 +14,10 @@ std::string StubChrome::GetVersion() {
return "";
}
+int StubChrome::GetBuildNo() {
+ return 9999;
+}
+
Status StubChrome::GetWebViewIds(std::list<std::string>* web_view_ids) {
return Status(kOk);
}
diff --git a/chrome/test/chromedriver/chrome/stub_chrome.h b/chrome/test/chromedriver/chrome/stub_chrome.h
index a919be6..df51692 100644
--- a/chrome/test/chromedriver/chrome/stub_chrome.h
+++ b/chrome/test/chromedriver/chrome/stub_chrome.h
@@ -20,6 +20,7 @@ class StubChrome : public Chrome {
// Overridden from Chrome:
virtual std::string GetVersion() OVERRIDE;
+ virtual int GetBuildNo() OVERRIDE;
virtual Status GetWebViewIds(std::list<std::string>* web_view_ids) OVERRIDE;
virtual Status GetWebViewById(const std::string& id,
WebView** web_view) OVERRIDE;
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.cc b/chrome/test/chromedriver/chrome/stub_web_view.cc
index a62a66e..8824b2f 100644
--- a/chrome/test/chromedriver/chrome/stub_web_view.cc
+++ b/chrome/test/chromedriver/chrome/stub_web_view.cc
@@ -92,3 +92,9 @@ Status StubWebView::OverrideGeolocation(const Geoposition& geoposition) {
Status StubWebView::CaptureScreenshot(std::string* screenshot) {
return Status(kOk);
}
+
+Status StubWebView::SetFileInputFiles(const std::string& frame,
+ const base::DictionaryValue& element,
+ const base::ListValue& files) {
+ return Status(kOk);
+}
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.h b/chrome/test/chromedriver/chrome/stub_web_view.h
index 0dc612b..27de7e9 100644
--- a/chrome/test/chromedriver/chrome/stub_web_view.h
+++ b/chrome/test/chromedriver/chrome/stub_web_view.h
@@ -57,6 +57,9 @@ class StubWebView : public WebView {
virtual JavaScriptDialogManager* GetJavaScriptDialogManager() OVERRIDE;
virtual Status OverrideGeolocation(const Geoposition& geoposition) OVERRIDE;
virtual Status CaptureScreenshot(std::string* screenshot) OVERRIDE;
+ virtual Status SetFileInputFiles(const std::string& frame,
+ const base::DictionaryValue& element,
+ const base::ListValue& files) OVERRIDE;
private:
std::string id_;
diff --git a/chrome/test/chromedriver/chrome/web_view.h b/chrome/test/chromedriver/chrome/web_view.h
index 5bfe5d1..14759f4 100644
--- a/chrome/test/chromedriver/chrome/web_view.h
+++ b/chrome/test/chromedriver/chrome/web_view.h
@@ -11,6 +11,7 @@
#include "base/memory/scoped_ptr.h"
namespace base {
+class DictionaryValue;
class ListValue;
class Value;
}
@@ -98,6 +99,12 @@ class WebView {
// Captures the visible portions of the web view as a base64-encoded PNG.
virtual Status CaptureScreenshot(std::string* screenshot) = 0;
+
+ // Set files in a file input element.
+ // |element| is the WebElement JSON Object of the input element.
+ virtual Status SetFileInputFiles(const std::string& frame,
+ const base::DictionaryValue& element,
+ const base::ListValue& files) = 0;
};
#endif // CHROME_TEST_CHROMEDRIVER_CHROME_WEB_VIEW_H_
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc
index 7da699c..9ccbbe6 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -299,6 +299,29 @@ Status WebViewImpl::CaptureScreenshot(std::string* screenshot) {
return Status(kOk);
}
+Status WebViewImpl::SetFileInputFiles(const std::string& frame,
+ const base::DictionaryValue& element,
+ const base::ListValue& files) {
+ int context_id;
+ Status status = GetContextIdForFrame(frame_tracker_.get(), frame,
+ &context_id);
+ if (status.IsError())
+ return status;
+ base::ListValue args;
+ args.Append(element.DeepCopy());
+ int node_id;
+ status = internal::GetNodeIdFromFunction(
+ client_.get(), context_id, "function(element) { return element; }",
+ args, &node_id);
+ if (status.IsError())
+ return status;
+ base::DictionaryValue params;
+ params.SetInteger("nodeId", node_id);
+ params.Set("files", files.DeepCopy());
+ return client_->SendCommand("DOM.setFileInputFiles", params);
+}
+
+
namespace internal {
Status EvaluateScript(DevToolsClient* client,
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.h b/chrome/test/chromedriver/chrome/web_view_impl.h
index 57ccb0c..378ad57 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.h
+++ b/chrome/test/chromedriver/chrome/web_view_impl.h
@@ -70,6 +70,9 @@ class WebViewImpl : public WebView {
virtual JavaScriptDialogManager* GetJavaScriptDialogManager() OVERRIDE;
virtual Status OverrideGeolocation(const Geoposition& geoposition) OVERRIDE;
virtual Status CaptureScreenshot(std::string* screenshot) OVERRIDE;
+ virtual Status SetFileInputFiles(const std::string& frame,
+ const base::DictionaryValue& element,
+ const base::ListValue& files) OVERRIDE;
private:
std::string id_;
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc
index 594bf59..395da59 100644
--- a/chrome/test/chromedriver/element_commands.cc
+++ b/chrome/test/chromedriver/element_commands.cc
@@ -5,8 +5,12 @@
#include "chrome/test/chromedriver/element_commands.h"
#include <list>
+#include <vector>
#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/stringprintf.h"
+#include "base/strings/string_split.h"
#include "base/values.h"
#include "chrome/test/chromedriver/basic_types.h"
#include "chrome/test/chromedriver/chrome/chrome.h"
@@ -188,8 +192,44 @@ Status ExecuteSendKeysToElement(
if (status.IsError())
return status;
if (is_input && is_file) {
- // TODO(chrisgao): Implement file upload.
- return Status(kUnknownError, "file upload is not implemented");
+ // File upload is only supported for chrome 27+.
+ if (session->chrome->GetBuildNo() < 1420) {
+ return Status(
+ kUnknownError,
+ base::StringPrintf(
+ "file upload requires chrome 27+, build 1420+,"
+ "while current one is %s",
+ session->chrome->GetVersion().c_str()));
+ }
+
+ // Compress array into a single string.
+ base::FilePath::StringType paths_string;
+ for (size_t i = 0; i < key_list->GetSize(); ++i) {
+ base::FilePath::StringType path_part;
+ if (!key_list->GetString(i, &path_part))
+ return Status(kUnknownError, "'value' is invalid");
+ paths_string.append(path_part);
+ }
+
+ // Separate the string into separate paths, delimited by '\n'.
+ std::vector<base::FilePath::StringType> paths;
+ base::SplitString(paths_string, '\n', &paths);
+
+ bool multiple = false;
+ status = IsElementAttributeEqualToIgnoreCase(
+ session, web_view, element_id, "multiple", "true", &multiple);
+ if (status.IsError())
+ return status;
+ if (!multiple && paths.size() > 1)
+ return Status(kUnknownError, "the element can not hold multiple files");
+
+ base::ListValue files;
+ for (size_t i = 0; i < paths.size(); ++i)
+ files.AppendString(paths[i]);
+
+ scoped_ptr<base::DictionaryValue> element(CreateElement(element_id));
+ return web_view->SetFileInputFiles(
+ session->GetCurrentFrameId(), *element, files);
} else {
return SendKeysToElement(session, web_view, element_id, key_list);
}