Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Unified Diff: chrome/test/chromedriver/capabilities_parser.cc

Issue 13185004: [chromedriver] Implement proxy capability. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/test/chromedriver/capabilities_parser.cc
diff --git a/chrome/test/chromedriver/capabilities_parser.cc b/chrome/test/chromedriver/capabilities_parser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e951f5269b8065aaed9c76e89c6a662c902040b1
--- /dev/null
+++ b/chrome/test/chromedriver/capabilities_parser.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2013 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/chromedriver/capabilities_parser.h"
+
+#include <map>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "chrome/test/chromedriver/chrome/status.h"
+
+namespace {
+
+Status ParseChromeBinary(
+ const base::Callback<bool(const base::FilePath&)>& file_checker,
+ const base::Value& option,
+ Capabilities* capabilities) {
+ base::FilePath::StringType path_str;
+ if (!option.GetAsString(&path_str))
+ return Status(kUnknownError, "'binary' must be a string");
+ base::FilePath chrome_exe(path_str);
+ if (!file_checker.Run(chrome_exe)) {
+ return Status(kUnknownError,
+ base::StringPrintf("no chrome binary at %" PRFilePath,
+ path_str.c_str()));
+ }
+ capabilities->chrome_exe = chrome_exe;
+ return Status(kOk);
+}
+
+Status ParseLogPath(const base::Value& option, Capabilities* capabilities) {
+ if (!option.GetAsString(&capabilities->log_path))
+ return Status(kUnknownError, "'logPath' must be a string");
+ return Status(kOk);
+}
+
+Status ParseArgs(const base::Value& option, Capabilities* capabilities) {
+ const base::ListValue* args_list = NULL;
+ if (!option.GetAsList(&args_list))
+ return Status(kUnknownError, "'args' must be a list");
+ for (size_t i = 0; i < args_list->GetSize(); ++i) {
+ const base::Value* value = NULL;
+ args_list->Get(i, &value);
+ capabilities->args.Append(value->DeepCopy());
+ }
+ return Status(kOk);
+}
+
+Status ParsePrefs(const base::Value& option, Capabilities* capabilities) {
+ if (!option.GetAsDictionary(&capabilities->prefs))
+ return Status(kUnknownError, "'prefs' must be a dictionary");
+ return Status(kOk);
+}
+
+Status ParseLocalState(const base::Value& option, Capabilities* capabilities) {
+ if (!option.GetAsDictionary(&capabilities->local_state))
+ return Status(kUnknownError, "'localState' must be a dictionary");
+ return Status(kOk);
+}
+
+Status ParseExtensions(const base::Value& option, Capabilities* capabilities) {
+ if (!option.GetAsList(&capabilities->extensions))
+ return Status(kUnknownError, "'extensions' must be a list");
+ return Status(kOk);
+}
+
+Status ParseProxy(const base::Value& option, Capabilities* capabilities) {
+ const base::DictionaryValue* proxy_dict;
+ if (!option.GetAsDictionary(&proxy_dict))
+ return Status(kUnknownError, "'proxy' must be a dictionary");
+ std::string proxy_type;
+ if (!proxy_dict->GetString("proxyType", &proxy_type))
+ return Status(kUnknownError, "'proxyType' must be a string");
+ proxy_type = StringToLowerASCII(proxy_type);
+ if (proxy_type == "direct") {
+ capabilities->args.AppendString("no-proxy-server");
+ } else if (proxy_type == "system") {
+ // Chrome default.
+ } else if (proxy_type == "pac") {
+ std::string proxy_pac_url;
+ if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url))
+ return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string");
+ capabilities->args.AppendString("proxy-pac-url=" + proxy_pac_url);
+ } else if (proxy_type == "autodetect") {
+ capabilities->args.AppendString("proxy-auto-detect");
+ } else if (proxy_type == "manual") {
+ const char* proxy_servers_options[][2] = {
+ {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}};
+ std::string proxy_servers;
+ for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) {
+ if (!proxy_dict->HasKey(proxy_servers_options[i][0]))
+ continue;
+ std::string value;
+ if (!proxy_dict->GetString(proxy_servers_options[i][0], &value)) {
+ return Status(
+ kUnknownError,
+ base::StringPrintf("'%s' must be a string",
+ proxy_servers_options[i][0]));
+ }
+ // Converts into Chrome proxy scheme.
+ // Example: "http=localhost:9000;ftp=localhost:8000".
+ if (!proxy_servers.empty())
+ proxy_servers += ";";
+ proxy_servers += base::StringPrintf(
+ "%s=%s", proxy_servers_options[i][1], value.c_str());
+ }
+
+ std::string proxy_bypass_list;
+ if (proxy_dict->HasKey("noProxy")) {
+ if (!proxy_dict->GetString("noProxy", & proxy_bypass_list))
+ return Status(kUnknownError, "'noProxy' must be a string");
+ }
+
+ if (proxy_servers.empty() && proxy_bypass_list.empty()) {
+ return Status(kUnknownError, "proxyType is 'manual' but no manual "
+ "proxy capabilities were found");
+ }
+ if (!proxy_servers.empty())
+ capabilities->args.AppendString("proxy-server=" + proxy_servers);
+ if (!proxy_bypass_list.empty())
+ capabilities->args.AppendString("proxy-bypass-list=" + proxy_bypass_list);
+ } else {
+ return Status(kUnknownError, "unrecognized proxy type:" + proxy_type);
+ }
+ return Status(kOk);
+}
+
+} // namespace
+
+Capabilities::Capabilities()
+ : prefs(NULL), local_state(NULL), extensions(NULL) {}
+
+Capabilities::~Capabilities() {}
+
+bool Capabilities::HasAndroidPackage() const {
+ return !android_package.empty();
+}
+
+Status Capabilities::Parse(
+ const base::DictionaryValue& chrome_options,
+ const base::Callback<bool(const base::FilePath&)>& file_checker) {
+ const base::Value* android_package_value;
+ if (chrome_options.Get("android_package", &android_package_value)) {
+ if (!android_package_value->GetAsString(&android_package) ||
+ android_package.empty()) {
+ return Status(kUnknownError,
+ "'android_package' must be a non-empty string");
+ } else if (chrome_options.size() > 1u) {
+ return Status(kUnknownError,
+ "Android only supports option 'android_package'");
+ }
+ } else {
+ typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser;
+ std::map<std::string, Parser> parser_map;
+
+ parser_map["binary"] = base::Bind(&ParseChromeBinary, file_checker);
+ parser_map["logPath"] = base::Bind(&ParseLogPath);
+ parser_map["args"] = base::Bind(&ParseArgs);
+ parser_map["prefs"] = base::Bind(&ParsePrefs);
+ parser_map["localState"] = base::Bind(&ParseLocalState);
+ parser_map["extensions"] = base::Bind(&ParseExtensions);
+ parser_map["proxy"] = base::Bind(&ParseProxy);
kkania 2013/04/03 19:09:35 this isn't part of chromeOptions. It's a cross-bro
chrisgao (Use stgao instead) 2013/04/06 01:12:01 Done.
+
+ for (base::DictionaryValue::Iterator it(chrome_options); !it.IsAtEnd();
+ it.Advance()) {
+ if (parser_map.find(it.key()) == parser_map.end()) {
+ return Status(kUnknownError,
+ "unrecognized chrome capability: " + it.key());
+ }
+ Status status = parser_map[it.key()].Run(it.value(), this);
+ if (status.IsError())
+ return status;
+ }
+ }
+ return Status(kOk);
+}

Powered by Google App Engine
This is Rietveld 408576698