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

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