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

Side by Side Diff: chrome/test/chromedriver/capabilities.cc

Issue 13185004: [chromedriver] Implement proxy capability. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and Address comments. Created 7 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/test/chromedriver/capabilities.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/string_util.h"
12 #include "base/stringprintf.h"
13 #include "base/values.h"
14 #include "chrome/test/chromedriver/chrome/status.h"
15
16 namespace {
17
18 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser;
19
20 Status ParseChromeBinary(
21 const base::Value& option,
22 Capabilities* capabilities) {
23 base::FilePath::StringType path_str;
24 if (!option.GetAsString(&path_str))
25 return Status(kUnknownError, "'binary' must be a string");
26 base::FilePath chrome_exe(path_str);
27 capabilities->command.SetProgram(chrome_exe);
28 return Status(kOk);
29 }
30
31 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) {
32 if (!option.GetAsString(&capabilities->log_path))
33 return Status(kUnknownError, "'logPath' must be a string");
34 return Status(kOk);
35 }
36
37 Status ParseArgs(const base::Value& option, Capabilities* capabilities) {
38 const base::ListValue* args_list = NULL;
39 if (!option.GetAsList(&args_list))
40 return Status(kUnknownError, "'args' must be a list");
41 for (size_t i = 0; i < args_list->GetSize(); ++i) {
42 std::string arg_string;
43 if (!args_list->GetString(i, &arg_string))
44 return Status(kUnknownError, "each argument must be a string");
45 size_t separator_index = arg_string.find("=");
46 if (separator_index != std::string::npos) {
47 CommandLine::StringType arg_string_native;
48 if (!args_list->GetString(i, &arg_string_native))
49 return Status(kUnknownError, "each argument must be a string");
50 capabilities->command.AppendSwitchNative(
51 arg_string.substr(0, separator_index),
52 arg_string_native.substr(separator_index + 1));
53 } else {
54 capabilities->command.AppendSwitch(arg_string);
55 }
56 }
57 return Status(kOk);
58 }
59
60 Status ParsePrefs(const base::Value& option, Capabilities* capabilities) {
61 const base::DictionaryValue* prefs = NULL;
62 if (!option.GetAsDictionary(&prefs))
63 return Status(kUnknownError, "'prefs' must be a dictionary");
64 capabilities->prefs.reset(prefs->DeepCopy());
65 return Status(kOk);
66 }
67
68 Status ParseLocalState(const base::Value& option, Capabilities* capabilities) {
69 const base::DictionaryValue* local_state = NULL;
70 if (!option.GetAsDictionary(&local_state))
71 return Status(kUnknownError, "'localState' must be a dictionary");
72 capabilities->local_state.reset(local_state->DeepCopy());
73 return Status(kOk);
74 }
75
76 Status ParseExtensions(const base::Value& option, Capabilities* capabilities) {
77 const base::ListValue* extensions = NULL;
78 if (!option.GetAsList(&extensions))
79 return Status(kUnknownError, "'extensions' must be a list");
80 for (size_t i = 0; i < extensions->GetSize(); ++i) {
81 std::string extension;
82 if (!extensions->GetString(i, &extension)) {
83 return Status(kUnknownError,
84 "each extension must be a base64 encoded string");
85 }
86 capabilities->extensions.push_back(extension);
87 }
88 return Status(kOk);
89 }
90
91 Status ParseProxy(const base::Value& option, Capabilities* capabilities) {
92 const base::DictionaryValue* proxy_dict;
93 if (!option.GetAsDictionary(&proxy_dict))
94 return Status(kUnknownError, "'proxy' must be a dictionary");
95 std::string proxy_type;
96 if (!proxy_dict->GetString("proxyType", &proxy_type))
97 return Status(kUnknownError, "'proxyType' must be a string");
98 proxy_type = StringToLowerASCII(proxy_type);
99 if (proxy_type == "direct") {
100 capabilities->command.AppendSwitch("no-proxy-server");
101 } else if (proxy_type == "system") {
102 // Chrome default.
103 } else if (proxy_type == "pac") {
104 CommandLine::StringType proxy_pac_url;
105 if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url))
106 return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string");
107 capabilities->command.AppendSwitchNative("proxy-pac-url", proxy_pac_url);
108 } else if (proxy_type == "autodetect") {
109 capabilities->command.AppendSwitch("proxy-auto-detect");
110 } else if (proxy_type == "manual") {
111 const char* proxy_servers_options[][2] = {
112 {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}};
113 std::string proxy_servers;
114 for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) {
115 if (!proxy_dict->HasKey(proxy_servers_options[i][0]))
116 continue;
117 std::string value;
118 if (!proxy_dict->GetString(proxy_servers_options[i][0], &value)) {
119 return Status(
120 kUnknownError,
121 base::StringPrintf("'%s' must be a string",
122 proxy_servers_options[i][0]));
123 }
124 // Converts into Chrome proxy scheme.
125 // Example: "http=localhost:9000;ftp=localhost:8000".
126 if (!proxy_servers.empty())
127 proxy_servers += ";";
128 proxy_servers += base::StringPrintf(
129 "%s=%s", proxy_servers_options[i][1], value.c_str());
130 }
131
132 std::string proxy_bypass_list;
133 if (proxy_dict->HasKey("noProxy")) {
134 if (!proxy_dict->GetString("noProxy", &proxy_bypass_list))
135 return Status(kUnknownError, "'noProxy' must be a string");
136 }
137
138 if (proxy_servers.empty() && proxy_bypass_list.empty()) {
139 return Status(kUnknownError,
140 "proxyType is 'manual' but no manual "
141 "proxy capabilities were found");
142 }
143 if (!proxy_servers.empty())
144 capabilities->command.AppendSwitchASCII("proxy-server", proxy_servers);
145 if (!proxy_bypass_list.empty()) {
146 capabilities->command.AppendSwitchASCII("proxy-bypass-list",
147 proxy_bypass_list);
148 }
149 } else {
150 return Status(kUnknownError, "unrecognized proxy type:" + proxy_type);
151 }
152 return Status(kOk);
153 }
154
155 Status ParseDesktopChromeOption(
156 const base::Value& capability,
157 Capabilities* capabilities) {
158 const base::DictionaryValue* chrome_options = NULL;
159 if (!capability.GetAsDictionary(&chrome_options))
160 return Status(kUnknownError, "'chromeOptions' must be a dictionary");
161
162 std::map<std::string, Parser> parser_map;
163
164 parser_map["binary"] = base::Bind(&ParseChromeBinary);
165 parser_map["logPath"] = base::Bind(&ParseLogPath);
166 parser_map["args"] = base::Bind(&ParseArgs);
167 parser_map["prefs"] = base::Bind(&ParsePrefs);
168 parser_map["localState"] = base::Bind(&ParseLocalState);
169 parser_map["extensions"] = base::Bind(&ParseExtensions);
170
171 for (base::DictionaryValue::Iterator it(*chrome_options); !it.IsAtEnd();
172 it.Advance()) {
173 if (parser_map.find(it.key()) == parser_map.end()) {
174 return Status(kUnknownError,
175 "unrecognized chrome option: " + it.key());
176 }
177 Status status = parser_map[it.key()].Run(it.value(), capabilities);
178 if (status.IsError())
179 return status;
180 }
181 return Status(kOk);
182 }
183
184 Status ParseAndroidChromeCapabilities(const base::DictionaryValue& desired_caps,
185 Capabilities* capabilities) {
186 const base::Value* chrome_options = NULL;
187 if (desired_caps.Get("chromeOptions", &chrome_options)) {
188 const base::DictionaryValue* chrome_options_dict = NULL;
189 if (!chrome_options->GetAsDictionary(&chrome_options_dict))
190 return Status(kUnknownError, "'chromeOptions' must be a dictionary");
191
192 const base::Value* android_package_value;
193 if (chrome_options_dict->Get("android_package", &android_package_value)) {
194 if (!android_package_value->GetAsString(&capabilities->android_package) ||
195 capabilities->android_package.empty()) {
196 return Status(kUnknownError,
197 "'android_package' must be a non-empty string");
198 }
199 }
200 }
201 return Status(kOk);
202 }
203
204 } // namespace
205
206 Capabilities::Capabilities() : command(CommandLine::NO_PROGRAM) {}
207
208 Capabilities::~Capabilities() {}
209
210 bool Capabilities::IsAndroid() const {
211 return !android_package.empty();
212 }
213
214 Status Capabilities::Parse(const base::DictionaryValue& desired_caps) {
215 Status status = ParseAndroidChromeCapabilities(desired_caps, this);
216 if (status.IsError())
217 return status;
218 if (IsAndroid())
219 return Status(kOk);
220
221 std::map<std::string, Parser> parser_map;
222 parser_map["proxy"] = base::Bind(&ParseProxy);
223 parser_map["chromeOptions"] = base::Bind(&ParseDesktopChromeOption);
224 for (std::map<std::string, Parser>::iterator it = parser_map.begin();
225 it != parser_map.end(); ++it) {
226 const base::Value* capability = NULL;
227 if (desired_caps.Get(it->first, &capability)) {
228 status = it->second.Run(*capability, this);
229 if (status.IsError())
230 return status;
231 }
232 }
233 return Status(kOk);
234 }
OLDNEW
« no previous file with comments | « chrome/test/chromedriver/capabilities.h ('k') | chrome/test/chromedriver/capabilities_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698