Home | History | Annotate | Download | only in chromedriver
      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 
     13 TEST(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 
     21 TEST(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 
     35 TEST(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 
     49 TEST(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 
     62 TEST(Switches, Remove) {
     63   Switches switches;
     64   switches.SetSwitch("a", "1");
     65   switches.RemoveSwitch("a");
     66   ASSERT_FALSE(switches.HasSwitch("a"));
     67 }
     68 
     69 TEST(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 
     77 TEST(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 
     90 TEST(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 
    101 TEST(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 
    111 TEST(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 
    119 TEST(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 
    127 TEST(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 
    136 TEST(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 
    154 TEST(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 
    166 TEST(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 
    178 TEST(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 
    192 TEST(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 
    202 TEST(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 
    212 TEST(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 
    224 TEST(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 
    235 TEST(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 
    248 TEST(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 
    259 TEST(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 
    271 TEST(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 
    292 TEST(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 
    302 TEST(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 
    320 TEST(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 
    332 TEST(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 
    340 TEST(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 
    368 TEST(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 
    389 TEST(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 
    405 TEST(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 
    417 TEST(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 
    429 TEST(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 
    445 TEST(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 
    460 TEST(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 
    471 TEST(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 
    485 TEST(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 
    501 TEST(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 
    523 TEST(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 
    531 TEST(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 
    541 TEST(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 
    553 TEST(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