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..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); |
| +} |