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

Side by Side 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: Check unexpected capabilities failed java tests. 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_parser.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"
kkania 2013/04/06 17:17:52 base/strings/
chrisgao (Use stgao instead) 2013/04/08 08:26:56 no stringprintf.h in directory "base/strings/". An
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::Callback<bool(const base::FilePath&)>& file_checker,
kkania 2013/04/06 17:17:52 i notice this is the only place where we use the f
chrisgao (Use stgao instead) 2013/04/08 08:26:56 Done.
22 const base::Value& option,
23 Capabilities* capabilities) {
24 base::FilePath::StringType path_str;
25 if (!option.GetAsString(&path_str))
26 return Status(kUnknownError, "'binary' must be a string");
27 base::FilePath chrome_exe(path_str);
28 if (!file_checker.Run(chrome_exe)) {
29 return Status(kUnknownError,
30 base::StringPrintf("no chrome binary at %" PRFilePath,
31 path_str.c_str()));
32 }
33 capabilities->command.SetProgram(chrome_exe);
34 return Status(kOk);
35 }
36
37 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) {
38 if (!option.GetAsString(&capabilities->log_path))
39 return Status(kUnknownError, "'logPath' must be a string");
40 return Status(kOk);
41 }
42
43 Status ParseArgs(const base::Value& option, Capabilities* capabilities) {
44 const base::ListValue* args_list = NULL;
45 if (!option.GetAsList(&args_list))
46 return Status(kUnknownError, "'args' must be a list");
47 for (size_t i = 0; i < args_list->GetSize(); ++i) {
48 std::string arg_string;
49 if (!args_list->GetString(i, &arg_string))
50 return Status(kUnknownError, "each argument must be a string");
51 size_t separator_index = arg_string.find("=");
52 if (separator_index != std::string::npos) {
53 CommandLine::StringType arg_string_native;
54 if (!args_list->GetString(i, &arg_string_native))
55 return Status(kUnknownError, "each argument must be a string");
56 capabilities->command.AppendSwitchNative(
57 arg_string.substr(0, separator_index),
58 arg_string_native.substr(separator_index + 1));
59 } else {
60 capabilities->command.AppendSwitch(arg_string);
61 }
62 }
63 return Status(kOk);
64 }
65
66 Status ParsePrefs(const base::Value& option, Capabilities* capabilities) {
67 const base::DictionaryValue* prefs = NULL;
68 if (!option.GetAsDictionary(&prefs))
69 return Status(kUnknownError, "'prefs' must be a dictionary");
70 capabilities->prefs.reset(prefs->DeepCopy());
71 return Status(kOk);
72 }
73
74 Status ParseLocalState(const base::Value& option, Capabilities* capabilities) {
75 const base::DictionaryValue* local_state = NULL;
76 if (!option.GetAsDictionary(&local_state))
77 return Status(kUnknownError, "'localState' must be a dictionary");
78 capabilities->local_state.reset(local_state->DeepCopy());
79 return Status(kOk);
80 }
81
82 Status ParseExtensions(const base::Value& option, Capabilities* capabilities) {
83 const base::ListValue* extensions = NULL;
84 if (!option.GetAsList(&extensions))
85 return Status(kUnknownError, "'extensions' must be a list");
86 for (size_t i = 0; i < extensions->GetSize(); ++i) {
87 std::string extension;
88 if (!extensions->GetString(i, &extension)) {
89 return Status(kUnknownError,
90 "each extension must be a base64 encoded string");
91 }
92 capabilities->extensions.push_back(extension);
93 }
94 return Status(kOk);
95 }
96
97 Status ParseProxy(const base::Value& option, Capabilities* capabilities) {
98 const base::DictionaryValue* proxy_dict;
99 if (!option.GetAsDictionary(&proxy_dict))
100 return Status(kUnknownError, "'proxy' must be a dictionary");
101 std::string proxy_type;
102 if (!proxy_dict->GetString("proxyType", &proxy_type))
103 return Status(kUnknownError, "'proxyType' must be a string");
104 proxy_type = StringToLowerASCII(proxy_type);
105 if (proxy_type == "direct") {
106 capabilities->command.AppendSwitch("no-proxy-server");
107 } else if (proxy_type == "system") {
108 // Chrome default.
109 } else if (proxy_type == "pac") {
110 CommandLine::StringType proxy_pac_url;
111 if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url))
112 return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string");
113 capabilities->command.AppendSwitchNative("proxy-pac-url", proxy_pac_url);
114 } else if (proxy_type == "autodetect") {
115 capabilities->command.AppendSwitch("proxy-auto-detect");
116 } else if (proxy_type == "manual") {
117 const char* proxy_servers_options[][2] = {
118 {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}};
119 std::string proxy_servers;
120 for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) {
121 if (!proxy_dict->HasKey(proxy_servers_options[i][0]))
122 continue;
123 std::string value;
124 if (!proxy_dict->GetString(proxy_servers_options[i][0], &value)) {
125 return Status(
126 kUnknownError,
127 base::StringPrintf("'%s' must be a string",
128 proxy_servers_options[i][0]));
129 }
130 // Converts into Chrome proxy scheme.
131 // Example: "http=localhost:9000;ftp=localhost:8000".
132 if (!proxy_servers.empty())
133 proxy_servers += ";";
134 proxy_servers += base::StringPrintf(
135 "%s=%s", proxy_servers_options[i][1], value.c_str());
136 }
137
138 std::string proxy_bypass_list;
139 if (proxy_dict->HasKey("noProxy")) {
140 if (!proxy_dict->GetString("noProxy", & proxy_bypass_list))
kkania 2013/04/06 17:17:52 no space
chrisgao (Use stgao instead) 2013/04/08 08:26:56 Done.
141 return Status(kUnknownError, "'noProxy' must be a string");
142 }
143
144 if (proxy_servers.empty() && proxy_bypass_list.empty()) {
145 return Status(kUnknownError,
146 "proxyType is 'manual' but no manual "
147 "proxy capabilities were found");
148 }
149 if (!proxy_servers.empty())
150 capabilities->command.AppendSwitchASCII("proxy-server", proxy_servers);
151 if (!proxy_bypass_list.empty()) {
152 capabilities->command.AppendSwitchASCII("proxy-bypass-list",
153 proxy_bypass_list);
154 }
155 } else {
156 return Status(kUnknownError, "unrecognized proxy type:" + proxy_type);
157 }
158 return Status(kOk);
159 }
160
161 Status ParseDesktopChromeOption(
162 const base::Callback<bool(const base::FilePath&)>& file_checker,
163 const base::Value& capability,
164 Capabilities* capabilities) {
165 const base::DictionaryValue* chrome_options = NULL;
166 if (!capability.GetAsDictionary(&chrome_options))
167 return Status(kUnknownError, "'chromeOptions' must be a dictionary");
168
169 std::map<std::string, Parser> parser_map;
170
171 parser_map["binary"] = base::Bind(&ParseChromeBinary, file_checker);
172 parser_map["logPath"] = base::Bind(&ParseLogPath);
173 parser_map["args"] = base::Bind(&ParseArgs);
174 parser_map["prefs"] = base::Bind(&ParsePrefs);
175 parser_map["localState"] = base::Bind(&ParseLocalState);
176 parser_map["extensions"] = base::Bind(&ParseExtensions);
177
178 for (base::DictionaryValue::Iterator it(*chrome_options); !it.IsAtEnd();
179 it.Advance()) {
180 if (parser_map.find(it.key()) == parser_map.end()) {
181 return Status(kUnknownError,
182 "unrecognized chrome option: " + it.key());
183 }
184 Status status = parser_map[it.key()].Run(it.value(), capabilities);
185 if (status.IsError())
186 return status;
187 }
188 return Status(kOk);
189 }
190
191 Status ParseAndroidChromeCapabilities(const base::DictionaryValue& desired_caps,
192 Capabilities* capabilities) {
193 const base::Value* chrome_options = NULL;
194 if (desired_caps.Get("chromeOptions", &chrome_options)) {
195 const base::DictionaryValue* chrome_options_dict = NULL;
196 if (!chrome_options->GetAsDictionary(&chrome_options_dict))
197 return Status(kUnknownError, "'chromeOptions' must be a dictionary");
198
199 const base::Value* android_package_value;
200 if (chrome_options_dict->Get("android_package", &android_package_value)) {
201 if (!android_package_value->GetAsString(&capabilities->android_package) ||
202 capabilities->android_package.empty()) {
203 return Status(kUnknownError,
204 "'android_package' must be a non-empty string");
205 }
206 }
207 }
208 return Status(kOk);
209 }
210
211 } // namespace
212
213 Capabilities::Capabilities() : command(CommandLine::NO_PROGRAM) {}
214
215 Capabilities::~Capabilities() {}
216
217 bool Capabilities::IsAndroid() const {
218 return !android_package.empty();
219 }
220
221 Status Capabilities::Parse(
222 const base::DictionaryValue& desired_caps,
223 const base::Callback<bool(const base::FilePath&)>& file_checker) {
224 Status status = ParseAndroidChromeCapabilities(desired_caps, this);
225 if (status.IsError())
226 return status;
227 if (IsAndroid())
228 return Status(kOk);
229
230 std::map<std::string, Parser> parser_map;
231 parser_map["proxy"] = base::Bind(&ParseProxy);
232 parser_map["chromeOptions"] = base::Bind(&ParseDesktopChromeOption,
233 file_checker);
234 for (std::map<std::string, Parser>::iterator it = parser_map.begin();
235 it != parser_map.end(); ++it) {
236 const base::Value* capability = NULL;
237 if (desired_caps.Get(it->first, &capability)) {
238 status = it->second.Run(*capability, this);
239 if (status.IsError())
240 return status;
241 }
242 }
243 return Status(kOk);
244 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698