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 "base/values.h"
8 #include "chrome/test/chromedriver/chrome/log.h"
9 #include "chrome/test/chromedriver/chrome/status.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
TEST(Switches,Empty)12 TEST(Switches, Empty) {
13 Switches switches;
14 CommandLine cmd(CommandLine::NO_PROGRAM);
15 switches.AppendToCommandLine(&cmd);
16 ASSERT_EQ(0u, cmd.GetSwitches().size());
17 ASSERT_EQ("", switches.ToString());
18 }
19
TEST(Switches,NoValue)20 TEST(Switches, NoValue) {
21 Switches switches;
22 switches.SetSwitch("hello");
23
24 ASSERT_TRUE(switches.HasSwitch("hello"));
25 ASSERT_EQ("", switches.GetSwitchValue("hello"));
26
27 CommandLine cmd(CommandLine::NO_PROGRAM);
28 switches.AppendToCommandLine(&cmd);
29 ASSERT_TRUE(cmd.HasSwitch("hello"));
30 ASSERT_EQ(FILE_PATH_LITERAL(""), cmd.GetSwitchValueNative("hello"));
31 ASSERT_EQ("--hello", switches.ToString());
32 }
33
TEST(Switches,Value)34 TEST(Switches, Value) {
35 Switches switches;
36 switches.SetSwitch("hello", "there");
37
38 ASSERT_TRUE(switches.HasSwitch("hello"));
39 ASSERT_EQ("there", switches.GetSwitchValue("hello"));
40
41 CommandLine cmd(CommandLine::NO_PROGRAM);
42 switches.AppendToCommandLine(&cmd);
43 ASSERT_TRUE(cmd.HasSwitch("hello"));
44 ASSERT_EQ(FILE_PATH_LITERAL("there"), cmd.GetSwitchValueNative("hello"));
45 ASSERT_EQ("--hello=there", switches.ToString());
46 }
47
TEST(Switches,FromOther)48 TEST(Switches, FromOther) {
49 Switches switches;
50 switches.SetSwitch("a", "1");
51 switches.SetSwitch("b", "1");
52
53 Switches switches2;
54 switches2.SetSwitch("b", "2");
55 switches2.SetSwitch("c", "2");
56
57 switches.SetFromSwitches(switches2);
58 ASSERT_EQ("--a=1 --b=2 --c=2", switches.ToString());
59 }
60
TEST(Switches,Remove)61 TEST(Switches, Remove) {
62 Switches switches;
63 switches.SetSwitch("a", "1");
64 switches.RemoveSwitch("a");
65 ASSERT_FALSE(switches.HasSwitch("a"));
66 }
67
TEST(Switches,Quoting)68 TEST(Switches, Quoting) {
69 Switches switches;
70 switches.SetSwitch("hello", "a b");
71 switches.SetSwitch("hello2", " '\" ");
72
73 ASSERT_EQ("--hello=\"a b\" --hello2=\" '\\\" \"", switches.ToString());
74 }
75
TEST(Switches,Multiple)76 TEST(Switches, Multiple) {
77 Switches switches;
78 switches.SetSwitch("switch");
79 switches.SetSwitch("hello", "there");
80
81 CommandLine cmd(CommandLine::NO_PROGRAM);
82 switches.AppendToCommandLine(&cmd);
83 ASSERT_TRUE(cmd.HasSwitch("switch"));
84 ASSERT_TRUE(cmd.HasSwitch("hello"));
85 ASSERT_EQ(FILE_PATH_LITERAL("there"), cmd.GetSwitchValueNative("hello"));
86 ASSERT_EQ("--hello=there --switch", switches.ToString());
87 }
88
TEST(Switches,Unparsed)89 TEST(Switches, Unparsed) {
90 Switches switches;
91 switches.SetUnparsedSwitch("a");
92 switches.SetUnparsedSwitch("--b");
93 switches.SetUnparsedSwitch("--c=1");
94 switches.SetUnparsedSwitch("d=1");
95 switches.SetUnparsedSwitch("-e=--1=1");
96
97 ASSERT_EQ("---e=--1=1 --a --b --c=1 --d=1", switches.ToString());
98 }
99
TEST(ParseCapabilities,WithAndroidPackage)100 TEST(ParseCapabilities, WithAndroidPackage) {
101 Capabilities capabilities;
102 base::DictionaryValue caps;
103 caps.SetString("chromeOptions.androidPackage", "abc");
104 Status status = capabilities.Parse(caps);
105 ASSERT_TRUE(status.IsOk());
106 ASSERT_TRUE(capabilities.IsAndroid());
107 ASSERT_EQ("abc", capabilities.android_package);
108 }
109
TEST(ParseCapabilities,EmptyAndroidPackage)110 TEST(ParseCapabilities, EmptyAndroidPackage) {
111 Capabilities capabilities;
112 base::DictionaryValue caps;
113 caps.SetString("chromeOptions.androidPackage", std::string());
114 Status status = capabilities.Parse(caps);
115 ASSERT_FALSE(status.IsOk());
116 }
117
TEST(ParseCapabilities,IllegalAndroidPackage)118 TEST(ParseCapabilities, IllegalAndroidPackage) {
119 Capabilities capabilities;
120 base::DictionaryValue caps;
121 caps.SetInteger("chromeOptions.androidPackage", 123);
122 Status status = capabilities.Parse(caps);
123 ASSERT_FALSE(status.IsOk());
124 }
125
TEST(ParseCapabilities,LogPath)126 TEST(ParseCapabilities, LogPath) {
127 Capabilities capabilities;
128 base::DictionaryValue caps;
129 caps.SetString("chromeOptions.logPath", "path/to/logfile");
130 Status status = capabilities.Parse(caps);
131 ASSERT_TRUE(status.IsOk());
132 ASSERT_STREQ("path/to/logfile", capabilities.log_path.c_str());
133 }
134
TEST(ParseCapabilities,Args)135 TEST(ParseCapabilities, Args) {
136 Capabilities capabilities;
137 base::ListValue args;
138 args.AppendString("arg1");
139 args.AppendString("arg2=val");
140 base::DictionaryValue caps;
141 caps.Set("chromeOptions.args", args.DeepCopy());
142
143 Status status = capabilities.Parse(caps);
144 ASSERT_TRUE(status.IsOk());
145
146 ASSERT_EQ(2u, capabilities.switches.GetSize());
147 ASSERT_TRUE(capabilities.switches.HasSwitch("arg1"));
148 ASSERT_TRUE(capabilities.switches.HasSwitch("arg2"));
149 ASSERT_EQ("", capabilities.switches.GetSwitchValue("arg1"));
150 ASSERT_EQ("val", capabilities.switches.GetSwitchValue("arg2"));
151 }
152
TEST(ParseCapabilities,Prefs)153 TEST(ParseCapabilities, Prefs) {
154 Capabilities capabilities;
155 base::DictionaryValue prefs;
156 prefs.SetString("key1", "value1");
157 prefs.SetString("key2.k", "value2");
158 base::DictionaryValue caps;
159 caps.Set("chromeOptions.prefs", prefs.DeepCopy());
160 Status status = capabilities.Parse(caps);
161 ASSERT_TRUE(status.IsOk());
162 ASSERT_TRUE(capabilities.prefs->Equals(&prefs));
163 }
164
TEST(ParseCapabilities,LocalState)165 TEST(ParseCapabilities, LocalState) {
166 Capabilities capabilities;
167 base::DictionaryValue local_state;
168 local_state.SetString("s1", "v1");
169 local_state.SetString("s2.s", "v2");
170 base::DictionaryValue caps;
171 caps.Set("chromeOptions.localState", local_state.DeepCopy());
172 Status status = capabilities.Parse(caps);
173 ASSERT_TRUE(status.IsOk());
174 ASSERT_TRUE(capabilities.local_state->Equals(&local_state));
175 }
176
TEST(ParseCapabilities,Extensions)177 TEST(ParseCapabilities, Extensions) {
178 Capabilities capabilities;
179 base::ListValue extensions;
180 extensions.AppendString("ext1");
181 extensions.AppendString("ext2");
182 base::DictionaryValue caps;
183 caps.Set("chromeOptions.extensions", extensions.DeepCopy());
184 Status status = capabilities.Parse(caps);
185 ASSERT_TRUE(status.IsOk());
186 ASSERT_EQ(2u, capabilities.extensions.size());
187 ASSERT_EQ("ext1", capabilities.extensions[0]);
188 ASSERT_EQ("ext2", capabilities.extensions[1]);
189 }
190
TEST(ParseCapabilities,UnrecognizedProxyType)191 TEST(ParseCapabilities, UnrecognizedProxyType) {
192 Capabilities capabilities;
193 base::DictionaryValue proxy;
194 proxy.SetString("proxyType", "unknown proxy type");
195 base::DictionaryValue caps;
196 caps.Set("proxy", proxy.DeepCopy());
197 Status status = capabilities.Parse(caps);
198 ASSERT_FALSE(status.IsOk());
199 }
200
TEST(ParseCapabilities,IllegalProxyType)201 TEST(ParseCapabilities, IllegalProxyType) {
202 Capabilities capabilities;
203 base::DictionaryValue proxy;
204 proxy.SetInteger("proxyType", 123);
205 base::DictionaryValue caps;
206 caps.Set("proxy", proxy.DeepCopy());
207 Status status = capabilities.Parse(caps);
208 ASSERT_FALSE(status.IsOk());
209 }
210
TEST(ParseCapabilities,DirectProxy)211 TEST(ParseCapabilities, DirectProxy) {
212 Capabilities capabilities;
213 base::DictionaryValue proxy;
214 proxy.SetString("proxyType", "DIRECT");
215 base::DictionaryValue caps;
216 caps.Set("proxy", proxy.DeepCopy());
217 Status status = capabilities.Parse(caps);
218 ASSERT_TRUE(status.IsOk());
219 ASSERT_EQ(1u, capabilities.switches.GetSize());
220 ASSERT_TRUE(capabilities.switches.HasSwitch("no-proxy-server"));
221 }
222
TEST(ParseCapabilities,SystemProxy)223 TEST(ParseCapabilities, SystemProxy) {
224 Capabilities capabilities;
225 base::DictionaryValue proxy;
226 proxy.SetString("proxyType", "system");
227 base::DictionaryValue caps;
228 caps.Set("proxy", proxy.DeepCopy());
229 Status status = capabilities.Parse(caps);
230 ASSERT_TRUE(status.IsOk());
231 ASSERT_EQ(0u, capabilities.switches.GetSize());
232 }
233
TEST(ParseCapabilities,PacProxy)234 TEST(ParseCapabilities, PacProxy) {
235 Capabilities capabilities;
236 base::DictionaryValue proxy;
237 proxy.SetString("proxyType", "PAC");
238 proxy.SetString("proxyAutoconfigUrl", "test.wpad");
239 base::DictionaryValue caps;
240 caps.Set("proxy", proxy.DeepCopy());
241 Status status = capabilities.Parse(caps);
242 ASSERT_TRUE(status.IsOk());
243 ASSERT_EQ(1u, capabilities.switches.GetSize());
244 ASSERT_EQ("test.wpad", capabilities.switches.GetSwitchValue("proxy-pac-url"));
245 }
246
TEST(ParseCapabilities,MissingProxyAutoconfigUrl)247 TEST(ParseCapabilities, MissingProxyAutoconfigUrl) {
248 Capabilities capabilities;
249 base::DictionaryValue proxy;
250 proxy.SetString("proxyType", "PAC");
251 proxy.SetString("httpProxy", "http://localhost:8001");
252 base::DictionaryValue caps;
253 caps.Set("proxy", proxy.DeepCopy());
254 Status status = capabilities.Parse(caps);
255 ASSERT_FALSE(status.IsOk());
256 }
257
TEST(ParseCapabilities,AutodetectProxy)258 TEST(ParseCapabilities, AutodetectProxy) {
259 Capabilities capabilities;
260 base::DictionaryValue proxy;
261 proxy.SetString("proxyType", "autodetect");
262 base::DictionaryValue caps;
263 caps.Set("proxy", proxy.DeepCopy());
264 Status status = capabilities.Parse(caps);
265 ASSERT_TRUE(status.IsOk());
266 ASSERT_EQ(1u, capabilities.switches.GetSize());
267 ASSERT_TRUE(capabilities.switches.HasSwitch("proxy-auto-detect"));
268 }
269
TEST(ParseCapabilities,ManualProxy)270 TEST(ParseCapabilities, ManualProxy) {
271 Capabilities capabilities;
272 base::DictionaryValue proxy;
273 proxy.SetString("proxyType", "manual");
274 proxy.SetString("ftpProxy", "localhost:9001");
275 proxy.SetString("httpProxy", "localhost:8001");
276 proxy.SetString("sslProxy", "localhost:10001");
277 proxy.SetString("noProxy", "google.com, youtube.com");
278 base::DictionaryValue caps;
279 caps.Set("proxy", proxy.DeepCopy());
280 Status status = capabilities.Parse(caps);
281 ASSERT_TRUE(status.IsOk());
282 ASSERT_EQ(2u, capabilities.switches.GetSize());
283 ASSERT_EQ(
284 "ftp=localhost:9001;http=localhost:8001;https=localhost:10001",
285 capabilities.switches.GetSwitchValue("proxy-server"));
286 ASSERT_EQ(
287 "google.com, youtube.com",
288 capabilities.switches.GetSwitchValue("proxy-bypass-list"));
289 }
290
TEST(ParseCapabilities,MissingSettingForManualProxy)291 TEST(ParseCapabilities, MissingSettingForManualProxy) {
292 Capabilities capabilities;
293 base::DictionaryValue proxy;
294 proxy.SetString("proxyType", "manual");
295 base::DictionaryValue caps;
296 caps.Set("proxy", proxy.DeepCopy());
297 Status status = capabilities.Parse(caps);
298 ASSERT_FALSE(status.IsOk());
299 }
300
TEST(ParseCapabilities,IgnoreNullValueForManualProxy)301 TEST(ParseCapabilities, IgnoreNullValueForManualProxy) {
302 Capabilities capabilities;
303 base::DictionaryValue proxy;
304 proxy.SetString("proxyType", "manual");
305 proxy.SetString("ftpProxy", "localhost:9001");
306 proxy.Set("sslProxy", base::Value::CreateNullValue());
307 proxy.Set("noProxy", base::Value::CreateNullValue());
308 base::DictionaryValue caps;
309 caps.Set("proxy", proxy.DeepCopy());
310 Status status = capabilities.Parse(caps);
311 ASSERT_TRUE(status.IsOk());
312 ASSERT_EQ(1u, capabilities.switches.GetSize());
313 ASSERT_TRUE(capabilities.switches.HasSwitch("proxy-server"));
314 ASSERT_EQ(
315 "ftp=localhost:9001",
316 capabilities.switches.GetSwitchValue("proxy-server"));
317 }
318
TEST(ParseCapabilities,LoggingPrefsOk)319 TEST(ParseCapabilities, LoggingPrefsOk) {
320 Capabilities capabilities;
321 base::DictionaryValue logging_prefs;
322 logging_prefs.SetString("Network", "INFO");
323 base::DictionaryValue caps;
324 caps.Set("loggingPrefs", logging_prefs.DeepCopy());
325 Status status = capabilities.Parse(caps);
326 ASSERT_TRUE(status.IsOk());
327 ASSERT_EQ(1u, capabilities.logging_prefs.size());
328 ASSERT_EQ(Log::kInfo, capabilities.logging_prefs["Network"]);
329 }
330
TEST(ParseCapabilities,LoggingPrefsNotDict)331 TEST(ParseCapabilities, LoggingPrefsNotDict) {
332 Capabilities capabilities;
333 base::DictionaryValue caps;
334 caps.SetString("loggingPrefs", "INFO");
335 Status status = capabilities.Parse(caps);
336 ASSERT_FALSE(status.IsOk());
337 }
338
TEST(ParseCapabilities,ExcludeSwitches)339 TEST(ParseCapabilities, ExcludeSwitches) {
340 Capabilities capabilities;
341 base::ListValue exclude_switches;
342 exclude_switches.AppendString("switch1");
343 exclude_switches.AppendString("switch2");
344 base::DictionaryValue caps;
345 caps.Set("chromeOptions.excludeSwitches", exclude_switches.DeepCopy());
346 Status status = capabilities.Parse(caps);
347 ASSERT_TRUE(status.IsOk());
348 ASSERT_EQ(2u, capabilities.exclude_switches.size());
349 const std::set<std::string>& switches = capabilities.exclude_switches;
350 ASSERT_TRUE(switches.find("switch1") != switches.end());
351 ASSERT_TRUE(switches.find("switch2") != switches.end());
352 }
353
TEST(ParseCapabilities,UseRemoteBrowser)354 TEST(ParseCapabilities, UseRemoteBrowser) {
355 Capabilities capabilities;
356 base::DictionaryValue caps;
357 caps.SetString("chromeOptions.debuggerAddress", "abc:123");
358 Status status = capabilities.Parse(caps);
359 ASSERT_TRUE(status.IsOk());
360 ASSERT_TRUE(capabilities.IsRemoteBrowser());
361 ASSERT_EQ("abc", capabilities.debugger_address.host());
362 ASSERT_EQ(123, capabilities.debugger_address.port());
363 }
364
TEST(ParseCapabilities,MobileEmulationUserAgent)365 TEST(ParseCapabilities, MobileEmulationUserAgent) {
366 Capabilities capabilities;
367 base::DictionaryValue mobile_emulation;
368 mobile_emulation.SetString("userAgent", "Agent Smith");
369 base::DictionaryValue caps;
370 caps.Set("chromeOptions.mobileEmulation", mobile_emulation.DeepCopy());
371 Status status = capabilities.Parse(caps);
372 ASSERT_TRUE(status.IsOk());
373
374 ASSERT_EQ(1u, capabilities.switches.GetSize());
375 ASSERT_TRUE(capabilities.switches.HasSwitch("user-agent"));
376 ASSERT_EQ("Agent Smith", capabilities.switches.GetSwitchValue("user-agent"));
377 }
378
TEST(ParseCapabilities,MobileEmulationDeviceMetrics)379 TEST(ParseCapabilities, MobileEmulationDeviceMetrics) {
380 Capabilities capabilities;
381 base::DictionaryValue mobile_emulation;
382 mobile_emulation.SetInteger("deviceMetrics.width", 360);
383 mobile_emulation.SetInteger("deviceMetrics.height", 640);
384 mobile_emulation.SetDouble("deviceMetrics.pixelRatio", 3.0);
385 base::DictionaryValue caps;
386 caps.Set("chromeOptions.mobileEmulation", mobile_emulation.DeepCopy());
387 Status status = capabilities.Parse(caps);
388 ASSERT_TRUE(status.IsOk());
389
390 ASSERT_EQ(360, capabilities.device_metrics->width);
391 ASSERT_EQ(640, capabilities.device_metrics->height);
392 ASSERT_EQ(3.0, capabilities.device_metrics->device_scale_factor);
393 }
394
TEST(ParseCapabilities,MobileEmulationDeviceName)395 TEST(ParseCapabilities, MobileEmulationDeviceName) {
396 Capabilities capabilities;
397 base::DictionaryValue mobile_emulation;
398 mobile_emulation.SetString("deviceName", "Google Nexus 5");
399 base::DictionaryValue caps;
400 caps.Set("chromeOptions.mobileEmulation", mobile_emulation.DeepCopy());
401 Status status = capabilities.Parse(caps);
402 ASSERT_TRUE(status.IsOk());
403
404 ASSERT_EQ(1u, capabilities.switches.GetSize());
405 ASSERT_TRUE(capabilities.switches.HasSwitch("user-agent"));
406 ASSERT_EQ(
407 "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) "
408 "AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 "
409 "Mobile Safari/535.19",
410 capabilities.switches.GetSwitchValue("user-agent"));
411
412 ASSERT_EQ(360, capabilities.device_metrics->width);
413 ASSERT_EQ(640, capabilities.device_metrics->height);
414 ASSERT_EQ(3.0, capabilities.device_metrics->device_scale_factor);
415 }
416
TEST(ParseCapabilities,MobileEmulationNotDict)417 TEST(ParseCapabilities, MobileEmulationNotDict) {
418 Capabilities capabilities;
419 base::DictionaryValue caps;
420 caps.SetString("chromeOptions.mobileEmulation", "Google Nexus 5");
421 Status status = capabilities.Parse(caps);
422 ASSERT_FALSE(status.IsOk());
423 }
424
TEST(ParseCapabilities,MobileEmulationDeviceMetricsNotDict)425 TEST(ParseCapabilities, MobileEmulationDeviceMetricsNotDict) {
426 Capabilities capabilities;
427 base::DictionaryValue mobile_emulation;
428 mobile_emulation.SetInteger("deviceMetrics", 360);
429 base::DictionaryValue caps;
430 caps.Set("chromeOptions.mobileEmulation", mobile_emulation.DeepCopy());
431 Status status = capabilities.Parse(caps);
432 ASSERT_FALSE(status.IsOk());
433 }
434
TEST(ParseCapabilities,MobileEmulationDeviceMetricsNotNumbers)435 TEST(ParseCapabilities, MobileEmulationDeviceMetricsNotNumbers) {
436 Capabilities capabilities;
437 base::DictionaryValue mobile_emulation;
438 mobile_emulation.SetString("deviceMetrics.width", "360");
439 mobile_emulation.SetString("deviceMetrics.height", "640");
440 mobile_emulation.SetString("deviceMetrics.pixelRatio", "3.0");
441 base::DictionaryValue caps;
442 caps.Set("chromeOptions.mobileEmulation", mobile_emulation.DeepCopy());
443 Status status = capabilities.Parse(caps);
444 ASSERT_FALSE(status.IsOk());
445 }
446
TEST(ParseCapabilities,MobileEmulationBadDict)447 TEST(ParseCapabilities, MobileEmulationBadDict) {
448 Capabilities capabilities;
449 base::DictionaryValue mobile_emulation;
450 mobile_emulation.SetString("deviceName", "Google Nexus 5");
451 mobile_emulation.SetInteger("deviceMetrics.width", 360);
452 mobile_emulation.SetInteger("deviceMetrics.height", 640);
453 mobile_emulation.SetDouble("deviceMetrics.pixelRatio", 3.0);
454 base::DictionaryValue caps;
455 caps.Set("chromeOptions.mobileEmulation", mobile_emulation.DeepCopy());
456 Status status = capabilities.Parse(caps);
457 ASSERT_FALSE(status.IsOk());
458 }
459