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

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

Issue 23643005: [chromedriver] Load the automation extension as a component extension. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 7 years, 3 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/test/chromedriver/capabilities.h" 5 #include "chrome/test/chromedriver/capabilities.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/json/string_escape.h"
11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
13 #include "base/strings/string_tokenizer.h" 14 #include "base/strings/string_tokenizer.h"
14 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
16 #include "base/values.h" 18 #include "base/values.h"
17 #include "chrome/test/chromedriver/chrome/log.h" 19 #include "chrome/test/chromedriver/chrome/log.h"
18 #include "chrome/test/chromedriver/chrome/status.h" 20 #include "chrome/test/chromedriver/chrome/status.h"
19 21
20 namespace { 22 namespace {
21 23
22 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser; 24 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser;
23 25
24 Status ParseBoolean( 26 Status ParseBoolean(
25 bool* to_set, 27 bool* to_set,
26 const base::Value& option, 28 const base::Value& option,
27 Capabilities* capabilities) { 29 Capabilities* capabilities) {
28 if (!option.GetAsBoolean(to_set)) 30 if (!option.GetAsBoolean(to_set))
29 return Status(kUnknownError, "value must be a boolean"); 31 return Status(kUnknownError, "must be a boolean");
30 return Status(kOk); 32 return Status(kOk);
31 } 33 }
32 34
33 Status ParseString(std::string* to_set, 35 Status ParseString(std::string* to_set,
34 const base::Value& option, 36 const base::Value& option,
35 Capabilities* capabilities) { 37 Capabilities* capabilities) {
36 std::string str; 38 std::string str;
37 if (!option.GetAsString(&str)) 39 if (!option.GetAsString(&str))
38 return Status(kUnknownError, "value must be a string"); 40 return Status(kUnknownError, "must be a string");
39 if (str.empty()) 41 if (str.empty())
40 return Status(kUnknownError, "value cannot be empty"); 42 return Status(kUnknownError, "cannot be empty");
41 *to_set = str; 43 *to_set = str;
42 return Status(kOk); 44 return Status(kOk);
43 } 45 }
44 46
47 Status ParseFilePath(base::FilePath* to_set,
48 const base::Value& option,
49 Capabilities* capabilities) {
50 base::FilePath::StringType str;
51 if (!option.GetAsString(&str))
52 return Status(kUnknownError, "must be a string");
53 if (str.empty())
chrisgao (Use stgao instead) 2013/08/29 22:53:32 I remember one webdriver client pass empty value f
kkania 2013/08/30 03:14:57 Let's have them fix their side.
54 return Status(kUnknownError, "cannot be empty");
55 *to_set = base::FilePath(str);
56 return Status(kOk);
57 }
58
45 Status IgnoreDeprecatedOption( 59 Status IgnoreDeprecatedOption(
46 Log* log, 60 Log* log,
47 const char* option_name, 61 const char* option_name,
48 const base::Value& option, 62 const base::Value& option,
49 Capabilities* capabilities) { 63 Capabilities* capabilities) {
50 log->AddEntry(Log::kWarning, 64 log->AddEntry(Log::kWarning,
51 base::StringPrintf("deprecated chrome option is ignored: '%s'", 65 base::StringPrintf("deprecated chrome option is ignored: '%s'",
52 option_name)); 66 option_name));
53 return Status(kOk); 67 return Status(kOk);
54 } 68 }
55 69
56 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) { 70 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) {
57 return Status(kOk); 71 return Status(kOk);
58 } 72 }
59 73
60 Status ParseChromeBinary(
61 const base::Value& option,
62 Capabilities* capabilities) {
63 base::FilePath::StringType path_str;
64 if (!option.GetAsString(&path_str))
65 return Status(kUnknownError, "'binary' must be a string");
66 base::FilePath chrome_exe(path_str);
67 capabilities->command.SetProgram(chrome_exe);
68 return Status(kOk);
69 }
70
71 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) { 74 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) {
72 if (!option.GetAsString(&capabilities->log_path)) 75 if (!option.GetAsString(&capabilities->log_path))
73 return Status(kUnknownError, "'logPath' must be a string"); 76 return Status(kUnknownError, "must be a string");
74 return Status(kOk); 77 return Status(kOk);
75 } 78 }
76 79
77 Status ParseArgs(bool is_android, 80 Status ParseSwitches(const base::Value& option,
78 const base::Value& option, 81 Capabilities* capabilities) {
79 Capabilities* capabilities) { 82 const base::ListValue* switches_list = NULL;
80 const base::ListValue* args_list = NULL; 83 if (!option.GetAsList(&switches_list))
81 if (!option.GetAsList(&args_list)) 84 return Status(kUnknownError, "must be a list");
82 return Status(kUnknownError, "'args' must be a list"); 85 for (size_t i = 0; i < switches_list->GetSize(); ++i) {
83 for (size_t i = 0; i < args_list->GetSize(); ++i) {
84 std::string arg_string; 86 std::string arg_string;
85 if (!args_list->GetString(i, &arg_string)) 87 if (!switches_list->GetString(i, &arg_string))
86 return Status(kUnknownError, "each argument must be a string"); 88 return Status(kUnknownError, "each argument must be a string");
87 if (is_android) { 89 capabilities->switches.SetSwitch(arg_string);
chrisgao (Use stgao instead) 2013/08/29 22:53:32 An arg_string could be "--load-extension=/path/to/
kkania 2013/08/30 03:14:57 Done.
88 capabilities->android_args += "--" + arg_string + " ";
89 } else {
90 size_t separator_index = arg_string.find("=");
91 if (separator_index != std::string::npos) {
92 CommandLine::StringType arg_string_native;
93 if (!args_list->GetString(i, &arg_string_native))
94 return Status(kUnknownError, "each argument must be a string");
95 capabilities->command.AppendSwitchNative(
96 arg_string.substr(0, separator_index),
97 arg_string_native.substr(separator_index + 1));
98 } else {
99 capabilities->command.AppendSwitch(arg_string);
100 }
101 }
102 } 90 }
103 return Status(kOk); 91 return Status(kOk);
104 } 92 }
105 93
106 Status ParsePrefs(const base::Value& option, Capabilities* capabilities) { 94 Status ParsePrefs(const base::Value& option, Capabilities* capabilities) {
107 const base::DictionaryValue* prefs = NULL; 95 const base::DictionaryValue* prefs = NULL;
108 if (!option.GetAsDictionary(&prefs)) 96 if (!option.GetAsDictionary(&prefs))
109 return Status(kUnknownError, "'prefs' must be a dictionary"); 97 return Status(kUnknownError, "must be a dictionary");
110 capabilities->prefs.reset(prefs->DeepCopy()); 98 capabilities->prefs.reset(prefs->DeepCopy());
111 return Status(kOk); 99 return Status(kOk);
112 } 100 }
113 101
114 Status ParseLocalState(const base::Value& option, Capabilities* capabilities) { 102 Status ParseLocalState(const base::Value& option, Capabilities* capabilities) {
chrisgao (Use stgao instead) 2013/08/29 22:53:32 Add a new function ParseDict instead of both Parse
kkania 2013/08/30 03:14:57 Done.
115 const base::DictionaryValue* local_state = NULL; 103 const base::DictionaryValue* local_state = NULL;
116 if (!option.GetAsDictionary(&local_state)) 104 if (!option.GetAsDictionary(&local_state))
117 return Status(kUnknownError, "'localState' must be a dictionary"); 105 return Status(kUnknownError, "must be a dictionary");
118 capabilities->local_state.reset(local_state->DeepCopy()); 106 capabilities->local_state.reset(local_state->DeepCopy());
119 return Status(kOk); 107 return Status(kOk);
120 } 108 }
121 109
122 Status ParseExtensions(const base::Value& option, Capabilities* capabilities) { 110 Status ParseExtensions(const base::Value& option, Capabilities* capabilities) {
123 const base::ListValue* extensions = NULL; 111 const base::ListValue* extensions = NULL;
124 if (!option.GetAsList(&extensions)) 112 if (!option.GetAsList(&extensions))
125 return Status(kUnknownError, "'extensions' must be a list"); 113 return Status(kUnknownError, "must be a list");
126 for (size_t i = 0; i < extensions->GetSize(); ++i) { 114 for (size_t i = 0; i < extensions->GetSize(); ++i) {
127 std::string extension; 115 std::string extension;
128 if (!extensions->GetString(i, &extension)) { 116 if (!extensions->GetString(i, &extension)) {
129 return Status(kUnknownError, 117 return Status(kUnknownError,
130 "each extension must be a base64 encoded string"); 118 "each extension must be a base64 encoded string");
131 } 119 }
132 capabilities->extensions.push_back(extension); 120 capabilities->extensions.push_back(extension);
133 } 121 }
134 return Status(kOk); 122 return Status(kOk);
135 } 123 }
136 124
137 Status ParseProxy(const base::Value& option, Capabilities* capabilities) { 125 Status ParseProxy(const base::Value& option, Capabilities* capabilities) {
138 const base::DictionaryValue* proxy_dict; 126 const base::DictionaryValue* proxy_dict;
139 if (!option.GetAsDictionary(&proxy_dict)) 127 if (!option.GetAsDictionary(&proxy_dict))
140 return Status(kUnknownError, "'proxy' must be a dictionary"); 128 return Status(kUnknownError, "must be a dictionary");
141 std::string proxy_type; 129 std::string proxy_type;
142 if (!proxy_dict->GetString("proxyType", &proxy_type)) 130 if (!proxy_dict->GetString("proxyType", &proxy_type))
143 return Status(kUnknownError, "'proxyType' must be a string"); 131 return Status(kUnknownError, "'proxyType' must be a string");
144 proxy_type = StringToLowerASCII(proxy_type); 132 proxy_type = StringToLowerASCII(proxy_type);
145 if (proxy_type == "direct") { 133 if (proxy_type == "direct") {
146 capabilities->command.AppendSwitch("no-proxy-server"); 134 capabilities->switches.SetSwitch("no-proxy-server");
147 } else if (proxy_type == "system") { 135 } else if (proxy_type == "system") {
148 // Chrome default. 136 // Chrome default.
149 } else if (proxy_type == "pac") { 137 } else if (proxy_type == "pac") {
150 CommandLine::StringType proxy_pac_url; 138 CommandLine::StringType proxy_pac_url;
151 if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url)) 139 if (!proxy_dict->GetString("proxyAutoconfigUrl", &proxy_pac_url))
152 return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string"); 140 return Status(kUnknownError, "'proxyAutoconfigUrl' must be a string");
153 capabilities->command.AppendSwitchNative("proxy-pac-url", proxy_pac_url); 141 capabilities->switches.SetSwitch("proxy-pac-url", proxy_pac_url);
154 } else if (proxy_type == "autodetect") { 142 } else if (proxy_type == "autodetect") {
155 capabilities->command.AppendSwitch("proxy-auto-detect"); 143 capabilities->switches.SetSwitch("proxy-auto-detect");
156 } else if (proxy_type == "manual") { 144 } else if (proxy_type == "manual") {
157 const char* proxy_servers_options[][2] = { 145 const char* proxy_servers_options[][2] = {
158 {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}}; 146 {"ftpProxy", "ftp"}, {"httpProxy", "http"}, {"sslProxy", "https"}};
159 const base::Value* option_value = NULL; 147 const base::Value* option_value = NULL;
160 std::string proxy_servers; 148 std::string proxy_servers;
161 for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) { 149 for (size_t i = 0; i < arraysize(proxy_servers_options); ++i) {
162 if (!proxy_dict->Get(proxy_servers_options[i][0], &option_value) || 150 if (!proxy_dict->Get(proxy_servers_options[i][0], &option_value) ||
163 option_value->IsType(base::Value::TYPE_NULL)) { 151 option_value->IsType(base::Value::TYPE_NULL)) {
164 continue; 152 continue;
165 } 153 }
(...skipping 18 matching lines...) Expand all
184 if (!option_value->GetAsString(&proxy_bypass_list)) 172 if (!option_value->GetAsString(&proxy_bypass_list))
185 return Status(kUnknownError, "'noProxy' must be a string"); 173 return Status(kUnknownError, "'noProxy' must be a string");
186 } 174 }
187 175
188 if (proxy_servers.empty() && proxy_bypass_list.empty()) { 176 if (proxy_servers.empty() && proxy_bypass_list.empty()) {
189 return Status(kUnknownError, 177 return Status(kUnknownError,
190 "proxyType is 'manual' but no manual " 178 "proxyType is 'manual' but no manual "
191 "proxy capabilities were found"); 179 "proxy capabilities were found");
192 } 180 }
193 if (!proxy_servers.empty()) 181 if (!proxy_servers.empty())
194 capabilities->command.AppendSwitchASCII("proxy-server", proxy_servers); 182 capabilities->switches.SetSwitch("proxy-server", proxy_servers);
195 if (!proxy_bypass_list.empty()) { 183 if (!proxy_bypass_list.empty()) {
196 capabilities->command.AppendSwitchASCII("proxy-bypass-list", 184 capabilities->switches.SetSwitch("proxy-bypass-list",
197 proxy_bypass_list); 185 proxy_bypass_list);
198 } 186 }
199 } else { 187 } else {
200 return Status(kUnknownError, "unrecognized proxy type:" + proxy_type); 188 return Status(kUnknownError, "unrecognized proxy type:" + proxy_type);
201 } 189 }
202 return Status(kOk); 190 return Status(kOk);
203 } 191 }
204 192
205 Status ParseExcludeSwitches(const base::Value& option, 193 Status ParseExcludeSwitches(const base::Value& option,
206 Capabilities* capabilities) { 194 Capabilities* capabilities) {
207 const base::ListValue* switches = NULL; 195 const base::ListValue* switches = NULL;
208 if (!option.GetAsList(&switches)) 196 if (!option.GetAsList(&switches))
209 return Status(kUnknownError, "'excludeSwitches' must be a list"); 197 return Status(kUnknownError, "must be a list");
210 for (size_t i = 0; i < switches->GetSize(); ++i) { 198 for (size_t i = 0; i < switches->GetSize(); ++i) {
211 std::string switch_name; 199 std::string switch_name;
212 if (!switches->GetString(i, &switch_name)) { 200 if (!switches->GetString(i, &switch_name)) {
213 return Status(kUnknownError, 201 return Status(kUnknownError,
214 "each switch to be removed must be a string"); 202 "each switch to be removed must be a string");
215 } 203 }
216 capabilities->exclude_switches.insert(switch_name); 204 capabilities->exclude_switches.insert(switch_name);
217 } 205 }
218 return Status(kOk); 206 return Status(kOk);
219 } 207 }
220 208
221 Status ParseUseExistingBrowser(const base::Value& option, 209 Status ParseUseExistingBrowser(const base::Value& option,
222 Capabilities* capabilities) { 210 Capabilities* capabilities) {
223 std::string server_addr; 211 std::string server_addr;
224 if (!option.GetAsString(&server_addr)) 212 if (!option.GetAsString(&server_addr))
225 return Status(kUnknownError, "must be 'host:port'"); 213 return Status(kUnknownError, "must be 'host:port'");
226 214
227 std::vector<std::string> values; 215 std::vector<std::string> values;
228 base::SplitString(server_addr, ':', &values); 216 base::SplitString(server_addr, ':', &values);
229 if (values.size() != 2) 217 if (values.size() != 2)
230 return Status(kUnknownError, "must be 'host:port'"); 218 return Status(kUnknownError, "must be 'host:port'");
231 219
232 // Ignoring host input for now, hardcoding to 127.0.0.1. 220 // Ignoring host input for now, hardcoding to 127.0.0.1.
233 base::StringToInt(values[1], &capabilities->existing_browser_port); 221 base::StringToInt(values[1], &capabilities->existing_browser_port);
234 if (capabilities->existing_browser_port <= 0) 222 if (capabilities->existing_browser_port <= 0)
235 return Status(kUnknownError, "port must be >= 0"); 223 return Status(kUnknownError, "port must be >= 0");
chrisgao (Use stgao instead) 2013/08/29 22:53:32 ">=" to ">"
kkania 2013/08/30 03:14:57 Done.
236 return Status(kOk); 224 return Status(kOk);
237 } 225 }
238 226
239 Status ParseLoggingPrefs(const base::Value& option, 227 Status ParseLoggingPrefs(const base::Value& option,
240 Capabilities* capabilities) { 228 Capabilities* capabilities) {
241 const base::DictionaryValue* logging_prefs_dict = NULL; 229 const base::DictionaryValue* logging_prefs_dict = NULL;
242 if (!option.GetAsDictionary(&logging_prefs_dict)) 230 if (!option.GetAsDictionary(&logging_prefs_dict))
243 return Status(kUnknownError, "'loggingPrefs' must be a dictionary"); 231 return Status(kUnknownError, "must be a dictionary");
244 232
245 // TODO(klm): verify log types. 233 // TODO(klm): verify log types.
246 // TODO(klm): verify log levels. 234 // TODO(klm): verify log levels.
247 capabilities->logging_prefs.reset(logging_prefs_dict->DeepCopy()); 235 capabilities->logging_prefs.reset(logging_prefs_dict->DeepCopy());
248 return Status(kOk); 236 return Status(kOk);
249 } 237 }
250 238
251 Status ParseChromeOptions( 239 Status ParseChromeOptions(
252 Log* log, 240 Log* log,
253 const base::Value& capability, 241 const base::Value& capability,
254 Capabilities* capabilities) { 242 Capabilities* capabilities) {
255 const base::DictionaryValue* chrome_options = NULL; 243 const base::DictionaryValue* chrome_options = NULL;
256 if (!capability.GetAsDictionary(&chrome_options)) 244 if (!capability.GetAsDictionary(&chrome_options))
257 return Status(kUnknownError, "'chromeOptions' must be a dictionary"); 245 return Status(kUnknownError, "must be a dictionary");
258 246
259 bool is_android = chrome_options->HasKey("androidPackage"); 247 bool is_android = chrome_options->HasKey("androidPackage");
260 bool is_existing = chrome_options->HasKey("useExistingBrowser"); 248 bool is_existing = chrome_options->HasKey("useExistingBrowser");
261 249
262 std::map<std::string, Parser> parser_map; 250 std::map<std::string, Parser> parser_map;
263 // Ignore 'binary' and 'extensions' capability, since the Java client 251 // Ignore 'args', 'binary' and 'extensions' capabilities by default, since the
264 // always passes them. 252 // Java client always passes them.
253 parser_map["args"] = base::Bind(&IgnoreCapability);
265 parser_map["binary"] = base::Bind(&IgnoreCapability); 254 parser_map["binary"] = base::Bind(&IgnoreCapability);
266 parser_map["extensions"] = base::Bind(&IgnoreCapability); 255 parser_map["extensions"] = base::Bind(&IgnoreCapability);
chrisgao (Use stgao instead) 2013/08/29 22:53:32 This function is for chromeOptions.* But args, bin
kkania 2013/08/30 03:14:57 talked offline
267 if (is_android) { 256 if (is_android) {
268 parser_map["androidActivity"] = 257 parser_map["androidActivity"] =
269 base::Bind(&ParseString, &capabilities->android_activity); 258 base::Bind(&ParseString, &capabilities->android_activity);
270 parser_map["androidDeviceSerial"] = 259 parser_map["androidDeviceSerial"] =
271 base::Bind(&ParseString, &capabilities->android_device_serial); 260 base::Bind(&ParseString, &capabilities->android_device_serial);
272 parser_map["androidPackage"] = 261 parser_map["androidPackage"] =
273 base::Bind(&ParseString, &capabilities->android_package); 262 base::Bind(&ParseString, &capabilities->android_package);
274 parser_map["androidProcess"] = 263 parser_map["androidProcess"] =
275 base::Bind(&ParseString, &capabilities->android_process); 264 base::Bind(&ParseString, &capabilities->android_process);
276 parser_map["args"] = base::Bind(&ParseArgs, true); 265 parser_map["args"] = base::Bind(&ParseSwitches);
266 parser_map["switches"] = base::Bind(&ParseSwitches);
277 } else if (is_existing) { 267 } else if (is_existing) {
278 parser_map["args"] = base::Bind(&IgnoreCapability);
279 parser_map["useExistingBrowser"] = base::Bind(&ParseUseExistingBrowser); 268 parser_map["useExistingBrowser"] = base::Bind(&ParseUseExistingBrowser);
chrisgao (Use stgao instead) 2013/08/29 22:53:32 not "debugger_address"?
kkania 2013/08/30 03:14:57 Done.
280 } else { 269 } else {
281 parser_map["forceDevToolsScreenshot"] = base::Bind( 270 parser_map["args"] = base::Bind(&ParseSwitches);
282 &ParseBoolean, &capabilities->force_devtools_screenshot); 271 parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary);
283 parser_map["args"] = base::Bind(&ParseArgs, false);
284 parser_map["binary"] = base::Bind(&ParseChromeBinary);
285 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach); 272 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach);
286 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches); 273 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches);
287 parser_map["extensions"] = base::Bind(&ParseExtensions); 274 parser_map["extensions"] = base::Bind(&ParseExtensions);
275 parser_map["forceDevToolsScreenshot"] = base::Bind(
276 &ParseBoolean, &capabilities->force_devtools_screenshot);
288 parser_map["loadAsync"] = 277 parser_map["loadAsync"] =
289 base::Bind(&IgnoreDeprecatedOption, log, "loadAsync"); 278 base::Bind(&IgnoreDeprecatedOption, log, "loadAsync");
290 parser_map["localState"] = base::Bind(&ParseLocalState); 279 parser_map["localState"] = base::Bind(&ParseLocalState);
291 parser_map["logPath"] = base::Bind(&ParseLogPath); 280 parser_map["logPath"] = base::Bind(&ParseLogPath);
292 parser_map["prefs"] = base::Bind(&ParsePrefs); 281 parser_map["prefs"] = base::Bind(&ParsePrefs);
282 parser_map["switches"] = base::Bind(&ParseSwitches);
chrisgao (Use stgao instead) 2013/08/29 22:53:32 What's this new "switches" for? Equivalent to "arg
kkania 2013/08/30 03:14:57 It's a synonym for args. Deleted.
293 } 283 }
294 284
295 for (base::DictionaryValue::Iterator it(*chrome_options); !it.IsAtEnd(); 285 for (base::DictionaryValue::Iterator it(*chrome_options); !it.IsAtEnd();
296 it.Advance()) { 286 it.Advance()) {
297 if (parser_map.find(it.key()) == parser_map.end()) { 287 if (parser_map.find(it.key()) == parser_map.end()) {
298 return Status(kUnknownError, 288 return Status(kUnknownError,
299 "unrecognized chrome option: " + it.key()); 289 "unrecognized chrome option: " + it.key());
300 } 290 }
301 Status status = parser_map[it.key()].Run(it.value(), capabilities); 291 Status status = parser_map[it.key()].Run(it.value(), capabilities);
302 if (status.IsError()) 292 if (status.IsError())
303 return Status(kUnknownError, "cannot parse " + it.key(), status); 293 return Status(kUnknownError, "cannot parse " + it.key(), status);
304 } 294 }
305 return Status(kOk); 295 return Status(kOk);
306 } 296 }
307 297
308 } // namespace 298 } // namespace
309 299
300 Switches::Switches() {}
301
302 Switches::~Switches() {}
303
304 void Switches::SetSwitch(const std::string& name) {
305 SetSwitch(name, NativeString());
306 }
307
308 void Switches::SetSwitch(const std::string& name, const std::string& value) {
309 #if defined(OS_WIN)
310 SetSwitch(name, UTF8ToUTF16(value));
311 #else
312 switch_map_[name] = value;
313 #endif
314 }
315
316 void Switches::SetSwitch(const std::string& name, const string16& value) {
317 #if defined(OS_WIN)
318 switch_map_[name] = value;
319 #else
320 SetSwitch(name, UTF16ToUTF8(value));
321 #endif
322 }
323
324 void Switches::SetSwitch(const std::string& name, const base::FilePath& value) {
325 SetSwitch(name, value.value());
326 }
327
328 void Switches::SetUnparsedSwitch(const std::string& unparsed_switch) {
329 std::string value;
330 size_t equals_index = unparsed_switch.find('=');
331 if (equals_index != std::string::npos)
332 value = unparsed_switch.substr(equals_index + 1);
333
334 std::string name;
335 size_t start_index = 0;
336 if (unparsed_switch.substr(0, 2) == "--")
337 start_index = 2;
338 name = unparsed_switch.substr(start_index, equals_index - start_index);
339
340 SetSwitch(name, value);
341 }
342
343 bool Switches::HasSwitch(const std::string& name) const {
344 return switch_map_.count(name) > 0;
345 }
346
347 std::string Switches::GetSwitchValue(const std::string& name) const {
348 NativeString value = GetSwitchValueNative(name);
349 #if defined(OS_WIN)
350 return UTF16ToUTF8(value);
351 #else
352 return value;
353 #endif
354 }
355
356 Switches::NativeString Switches::GetSwitchValueNative(
357 const std::string& name) const {
358 SwitchMap::const_iterator iter = switch_map_.find(name);
359 if (iter == switch_map_.end())
360 return NativeString();
361 return iter->second;
362 }
363
364 size_t Switches::GetSize() const {
365 return switch_map_.size();
366 }
367
368 void Switches::AppendToCommandLine(CommandLine* command) const {
369 for (SwitchMap::const_iterator iter = switch_map_.begin();
370 iter != switch_map_.end();
371 ++iter) {
372 command->AppendSwitchNative(iter->first, iter->second);
373 }
374 }
375
376 std::string Switches::ToString() const {
377 std::string str;
378 SwitchMap::const_iterator iter = switch_map_.begin();
379 while (iter != switch_map_.end()) {
380 str += "--" + iter->first;
381 std::string value = GetSwitchValue(iter->first);
382 if (value.length()) {
383 if (value.find(' ') != std::string::npos)
384 value = base::GetDoubleQuotedJson(value);
385 str += "=" + value;
386 }
387 ++iter;
388 if (iter == switch_map_.end())
389 break;
390 str += " ";
391 }
392 return str;
393 }
394
310 Capabilities::Capabilities() 395 Capabilities::Capabilities()
311 : force_devtools_screenshot(false), 396 : force_devtools_screenshot(false),
312 detach(false), 397 detach(false),
313 existing_browser_port(0), 398 existing_browser_port(0) {}
314 command(CommandLine::NO_PROGRAM) {}
315 399
316 Capabilities::~Capabilities() {} 400 Capabilities::~Capabilities() {}
317 401
318 bool Capabilities::IsAndroid() const { 402 bool Capabilities::IsAndroid() const {
319 return !android_package.empty(); 403 return !android_package.empty();
320 } 404 }
321 405
322 bool Capabilities::IsExistingBrowser() const { 406 bool Capabilities::IsExistingBrowser() const {
323 return existing_browser_port > 0; 407 return existing_browser_port > 0;
324 } 408 }
(...skipping 11 matching lines...) Expand all
336 if (desired_caps.Get(it->first, &capability)) { 420 if (desired_caps.Get(it->first, &capability)) {
337 Status status = it->second.Run(*capability, this); 421 Status status = it->second.Run(*capability, this);
338 if (status.IsError()) { 422 if (status.IsError()) {
339 return Status( 423 return Status(
340 kUnknownError, "cannot parse capability: " + it->first, status); 424 kUnknownError, "cannot parse capability: " + it->first, status);
341 } 425 }
342 } 426 }
343 } 427 }
344 return Status(kOk); 428 return Status(kOk);
345 } 429 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698