Chromium Code Reviews| 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..6ce952db19b5d74031f9b9ba5e4bbeb37d4f92ca |
| --- /dev/null |
| +++ b/chrome/test/chromedriver/capabilities_parser.cc |
| @@ -0,0 +1,173 @@ |
| +// 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 "base/callback.h" |
| +#include "base/string_util.h" |
| +#include "base/stringprintf.h" |
| +#include "chrome/test/chromedriver/chrome/status.h" |
| + |
| +namespace { |
| + |
| +// Parse information of proxy, add them as chrome switches to |args_list|. |
| +Status ParseProxy(const base::DictionaryValue& proxy_dict, |
| + base::ListValue* args_list) { |
| + 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") { |
| + args_list->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"); |
| + args_list->AppendString("proxy-pac-url=" + proxy_pac_url); |
| + } else if (proxy_type == "autodetect") { |
| + args_list->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()) |
| + args_list->AppendString("proxy-server=" + proxy_servers); |
| + if (!proxy_bypass_list.empty()) |
| + args_list->AppendString("proxy-bypass-list=" + proxy_bypass_list); |
| + } else { |
| + return Status(kUnknownError, "unrecognized proxy type:" + proxy_type); |
| + } |
| + return Status(kOk); |
| +} |
| + |
| +} // namespace |
| + |
| +Capabilities::Capabilities() |
| + : prefs_dict(NULL), local_state_dict(NULL), extensions_list(NULL) {} |
| + |
| +Capabilities::~Capabilities() {} |
| + |
| +bool Capabilities::HasAndroidPackage() { |
| + return !android_package.empty(); |
| +} |
| + |
| +Status ParseCapabilities( |
| + const base::DictionaryValue& desired_caps, |
| + Capabilities* capabilities, |
| + const base::Callback<bool(const base::FilePath&)>& file_checker) { |
| + const base::Value* android_package; |
| + if (desired_caps.Get("chromeOptions.android_package", &android_package)) { |
| + if (!android_package->GetAsString(&capabilities->android_package) || |
| + capabilities->android_package.empty()) { |
| + return Status(kUnknownError, |
| + "'android_package' must be a non-empty string"); |
| + } |
| + } else { |
| + base::FilePath::StringType path_str; |
| + base::FilePath chrome_exe; |
| + if (desired_caps.GetString("chromeOptions.binary", &path_str)) { |
| + chrome_exe = base::FilePath(path_str); |
| + if (!file_checker.Run(chrome_exe)) { |
| + std::string message = base::StringPrintf( |
| + "no chrome binary at %" PRFilePath, |
| + path_str.c_str()); |
| + return Status(kUnknownError, message); |
| + } |
| + } |
| + |
| + const base::Value* log_path = NULL; |
| + std::string chrome_log_path; |
| + if (desired_caps.Get("chromeOptions.logPath", &log_path) && |
|
kkania
2013/04/02 16:24:08
what do you think about iterating through ChromeOp
chrisgao (Use stgao instead)
2013/04/03 18:51:43
Done.
|
| + !log_path->GetAsString(&chrome_log_path)) { |
| + return Status(kUnknownError, |
| + "chrome log path must be a string"); |
| + } |
| + |
| + const base::Value* args = NULL; |
| + const base::ListValue* args_list = NULL; |
| + if (desired_caps.Get("chromeOptions.args", &args) && |
| + !args->GetAsList(&args_list)) { |
| + return Status(kUnknownError, |
| + "command line arguments for chrome must be a list"); |
| + } |
| + |
| + const base::Value* prefs = NULL; |
| + const base::DictionaryValue* prefs_dict = NULL; |
| + if (desired_caps.Get("chromeOptions.prefs", &prefs) && |
| + !prefs->GetAsDictionary(&prefs_dict)) { |
| + return Status(kUnknownError, "'prefs' must be a dictionary"); |
| + } |
| + |
| + const base::Value* local_state = NULL; |
| + const base::DictionaryValue* local_state_dict = NULL; |
| + if (desired_caps.Get("chromeOptions.localState", &local_state) && |
| + !local_state->GetAsDictionary(&local_state_dict)) { |
| + return Status(kUnknownError, "'localState' must be a dictionary"); |
| + } |
| + |
| + const base::Value* extensions = NULL; |
| + const base::ListValue* extensions_list = NULL; |
| + if (desired_caps.Get("chromeOptions.extensions", &extensions) |
| + && !extensions->GetAsList(&extensions_list)) { |
| + return Status(kUnknownError, |
| + "chrome extensions must be a list"); |
| + } |
| + |
| + const base::Value* proxy = NULL; |
| + base::ListValue proxy_args_list; |
| + if (desired_caps.Get("chromeOptions.proxy", &proxy)) { |
| + const base::DictionaryValue* proxy_dict = NULL; |
| + if (!proxy->GetAsDictionary(&proxy_dict)) |
| + return Status(kUnknownError, "proxy must be a dictionary"); |
| + Status status = ParseProxy(*proxy_dict, &proxy_args_list); |
| + if (status.IsError()) |
| + return status; |
| + } |
| + |
| + capabilities->chrome_exe = chrome_exe; |
| + capabilities->log_path = chrome_log_path; |
| + capabilities->args_list.Swap(&proxy_args_list); |
| + if (args_list) { |
| + for (size_t i = 0; i < args_list->GetSize(); ++i) { |
| + const base::Value* value = NULL; |
| + args_list->Get(i, &value); |
| + capabilities->args_list.Append(value->DeepCopy()); |
| + } |
| + } |
| + capabilities->prefs_dict = prefs_dict; |
| + capabilities->local_state_dict = local_state_dict; |
| + capabilities->extensions_list = extensions_list; |
| + } |
| + return Status(kOk); |
| +} |