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