@@ -69,6 +69,9 @@ public class ChromeOptions
69
69
private const string DebuggerAddressChromeOption = "debuggerAddress" ;
70
70
private const string ExcludeSwitchesChromeOption = "excludeSwitches" ;
71
71
private const string MinidumpPathChromeOption = "minidumpPath" ;
72
+ private const string MobileEmulationChromeOption = "mobileEmulation" ;
73
+ private const string PerformanceLoggingPreferencesChromeOption = "perfLoggingPrefs" ;
74
+ private const string WindowTypesChromeOption = "windowTypes" ;
72
75
73
76
private bool leaveBrowserRunning ;
74
77
private string binaryLocation ;
@@ -78,10 +81,16 @@ public class ChromeOptions
78
81
private List < string > extensionFiles = new List < string > ( ) ;
79
82
private List < string > encodedExtensions = new List < string > ( ) ;
80
83
private List < string > excludedSwitches = new List < string > ( ) ;
84
+ private List < string > windowTypes = new List < string > ( ) ;
81
85
private Dictionary < string , object > additionalCapabilities = new Dictionary < string , object > ( ) ;
82
86
private Dictionary < string , object > additionalChromeOptions = new Dictionary < string , object > ( ) ;
83
87
private Dictionary < string , object > userProfilePreferences ;
84
88
private Dictionary < string , object > localStatePreferences ;
89
+
90
+ private string mobileEmulationDeviceName ;
91
+ private ChromeMobileEmulationDeviceSettings mobileEmulationDeviceSettings ;
92
+ private ChromePerformanceLoggingPreferences perfLoggingPreferences ;
93
+
85
94
private Proxy proxy ;
86
95
87
96
/// <summary>
@@ -158,6 +167,15 @@ public string MinidumpPath
158
167
set { this . minidumpPath = value ; }
159
168
}
160
169
170
+ /// <summary>
171
+ /// Gets or sets the performance logging preferences for the driver.
172
+ /// </summary>
173
+ public ChromePerformanceLoggingPreferences PerformanceLoggingPreferences
174
+ {
175
+ get { return this . perfLoggingPreferences ; }
176
+ set { this . perfLoggingPreferences = value ; }
177
+ }
178
+
161
179
/// <summary>
162
180
/// Adds a single argument to the list of arguments to be appended to the Chrome.exe command line.
163
181
/// </summary>
@@ -370,6 +388,83 @@ public void AddLocalStatePreference(string preferenceName, object preferenceValu
370
388
this . localStatePreferences [ preferenceName ] = preferenceValue ;
371
389
}
372
390
391
+ /// <summary>
392
+ /// Allows the Chrome browser to emulate a mobile device.
393
+ /// </summary>
394
+ /// <param name="deviceName">The name of the device to emulate. The device name must be a
395
+ /// valid device name from the Chrome DevTools Emulation panel.</param>
396
+ /// <remarks>Specifying an invalid device name will not throw an exeption, but
397
+ /// will generate an error in Chrome when the driver starts. To unset mobile
398
+ /// emulation, call this method with <see langword="null"/> as the argument.</remarks>
399
+ public void EnableMobileEmulation ( string deviceName )
400
+ {
401
+ this . mobileEmulationDeviceSettings = null ;
402
+ this . mobileEmulationDeviceName = deviceName ;
403
+ }
404
+
405
+ /// <summary>
406
+ /// Allows the Chrome browser to emulate a mobile device.
407
+ /// </summary>
408
+ /// <param name="deviceSettings">The <see cref="ChromeMobileEmulationDeviceSettings"/>
409
+ /// object containing the settings of the device to emulate.</param>
410
+ /// <exception cref="ArgumentException">Thrown if the device settings option does
411
+ /// not have a user agent string set.</exception>
412
+ /// <remarks>Specifying an invalid device name will not throw an exeption, but
413
+ /// will generate an error in Chrome when the driver starts. To unset mobile
414
+ /// emulation, call this method with <see langword="null"/> as the argument.</remarks>
415
+ public void EnableMobileDeviceEmulation ( ChromeMobileEmulationDeviceSettings deviceSettings )
416
+ {
417
+ this . mobileEmulationDeviceName = null ;
418
+ if ( deviceSettings != null && string . IsNullOrEmpty ( deviceSettings . UserAgent ) )
419
+ {
420
+ throw new ArgumentException ( "Device settings must include a user agent string." , "deviceSettings" ) ;
421
+ }
422
+
423
+ this . mobileEmulationDeviceSettings = deviceSettings ;
424
+ }
425
+
426
+ /// <summary>
427
+ /// Adds a type of window that will be listed in the list of window handles
428
+ /// returned by the Chrome driver.
429
+ /// </summary>
430
+ /// <param name="windowType">The name of the window type to add.</param>
431
+ /// <remarks>This method can be used to allow the driver to access {webview}
432
+ /// elements by adding "webview" as a window type.</remarks>
433
+ public void AddWindowType ( string windowType )
434
+ {
435
+ if ( string . IsNullOrEmpty ( windowType ) )
436
+ {
437
+ throw new ArgumentException ( "windowType must not be null or empty" , "windowType" ) ;
438
+ }
439
+
440
+ this . AddWindowTypes ( windowType ) ;
441
+ }
442
+
443
+ /// <summary>
444
+ /// Adds a list of window types that will be listed in the list of window handles
445
+ /// returned by the Chrome driver.
446
+ /// </summary>
447
+ /// <param name="windowTypesToAdd">An array of window types to add.</param>
448
+ public void AddWindowTypes ( params string [ ] windowTypesToAdd )
449
+ {
450
+ this . AddWindowTypes ( new List < string > ( windowTypesToAdd ) ) ;
451
+ }
452
+
453
+ /// <summary>
454
+ /// Adds a list of window types that will be listed in the list of window handles
455
+ /// returned by the Chrome driver.
456
+ /// </summary>
457
+ /// <param name="windowTypesToAdd">An <see cref="IEnumerable{T}"/> of window types to add.</param>
458
+ public void AddWindowTypes ( IEnumerable < string > windowTypesToAdd )
459
+ {
460
+ if ( windowTypesToAdd == null )
461
+ {
462
+ throw new ArgumentNullException ( "windowTypesToAdd" , "windowTypesToAdd must not be null" ) ;
463
+ }
464
+
465
+ this . windowTypes . AddRange ( windowTypesToAdd ) ;
466
+ }
467
+
373
468
/// <summary>
374
469
/// Provides a means to add additional capabilities not yet added as type safe options
375
470
/// for the Chrome driver.
@@ -421,7 +516,10 @@ public void AddAdditionalCapability(string capabilityName, object capabilityValu
421
516
capabilityName == ChromeOptions . DebuggerAddressChromeOption ||
422
517
capabilityName == ChromeOptions . ExtensionsChromeOption ||
423
518
capabilityName == ChromeOptions . ExcludeSwitchesChromeOption ||
424
- capabilityName == ChromeOptions . MinidumpPathChromeOption )
519
+ capabilityName == ChromeOptions . MinidumpPathChromeOption ||
520
+ capabilityName == ChromeOptions . MobileEmulationChromeOption ||
521
+ capabilityName == ChromeOptions . PerformanceLoggingPreferencesChromeOption ||
522
+ capabilityName == ChromeOptions . WindowTypesChromeOption )
425
523
{
426
524
string message = string . Format ( CultureInfo . InvariantCulture , "There is already an option for the {0} capability. Please use that instead." , capabilityName ) ;
427
525
throw new ArgumentException ( message , "capabilityName" ) ;
@@ -517,12 +615,69 @@ private Dictionary<string, object> BuildChromeOptionsDictionary()
517
615
chromeOptions [ MinidumpPathChromeOption ] = this . minidumpPath ;
518
616
}
519
617
618
+ if ( ! string . IsNullOrEmpty ( this . mobileEmulationDeviceName ) || this . mobileEmulationDeviceSettings != null )
619
+ {
620
+ chromeOptions [ MobileEmulationChromeOption ] = this . GenerateMobileEmulationSettingsDictionary ( ) ;
621
+ }
622
+
623
+ if ( this . perfLoggingPreferences != null )
624
+ {
625
+ chromeOptions [ PerformanceLoggingPreferencesChromeOption ] = this . GeneratePerformanceLoggingPreferencesDictionary ( ) ;
626
+ }
627
+
628
+ if ( this . windowTypes . Count > 0 )
629
+ {
630
+ chromeOptions [ WindowTypesChromeOption ] = this . windowTypes ;
631
+ }
632
+
520
633
foreach ( KeyValuePair < string , object > pair in this . additionalChromeOptions )
521
634
{
522
635
chromeOptions . Add ( pair . Key , pair . Value ) ;
523
636
}
524
637
525
638
return chromeOptions ;
526
639
}
640
+
641
+ private Dictionary < string , object > GeneratePerformanceLoggingPreferencesDictionary ( )
642
+ {
643
+ Dictionary < string , object > perfLoggingPrefsDictionary = new Dictionary < string , object > ( ) ;
644
+ perfLoggingPrefsDictionary [ "enableNetwork" ] = this . perfLoggingPreferences . IsCollectingNetworkEvents ;
645
+ perfLoggingPrefsDictionary [ "enablePage" ] = this . perfLoggingPreferences . IsCollectingPageEvents ;
646
+ perfLoggingPrefsDictionary [ "enableTimeline" ] = this . perfLoggingPreferences . IsCollectingTimelineEvents ;
647
+
648
+ string tracingCategories = this . perfLoggingPreferences . TracingCategories ;
649
+ if ( ! string . IsNullOrEmpty ( tracingCategories ) )
650
+ {
651
+ perfLoggingPrefsDictionary [ "tracingCategories" ] = tracingCategories ;
652
+ }
653
+
654
+ perfLoggingPrefsDictionary [ "bufferUsageReportingInterval" ] = Convert . ToInt64 ( this . perfLoggingPreferences . BufferUsageReportingInterval . TotalMilliseconds ) ;
655
+
656
+ return perfLoggingPrefsDictionary ;
657
+ }
658
+
659
+ private Dictionary < string , object > GenerateMobileEmulationSettingsDictionary ( )
660
+ {
661
+ Dictionary < string , object > mobileEmulationSettings = new Dictionary < string , object > ( ) ;
662
+
663
+ if ( ! string . IsNullOrEmpty ( this . mobileEmulationDeviceName ) )
664
+ {
665
+ mobileEmulationSettings [ "deviceName" ] = this . mobileEmulationDeviceName ;
666
+ }
667
+ else if ( this . mobileEmulationDeviceSettings != null )
668
+ {
669
+ mobileEmulationSettings [ "userAgent" ] = this . mobileEmulationDeviceSettings . UserAgent ;
670
+ Dictionary < string , object > deviceMetrics = new Dictionary < string , object > ( ) ;
671
+ deviceMetrics [ "width" ] = this . mobileEmulationDeviceSettings . Width ;
672
+ deviceMetrics [ "height" ] = this . mobileEmulationDeviceSettings . Height ;
673
+ deviceMetrics [ "pixelRatio" ] = this . mobileEmulationDeviceSettings . PixelRatio ;
674
+ if ( ! this . mobileEmulationDeviceSettings . EnableTouchEvents )
675
+ {
676
+ deviceMetrics [ "touch" ] = this . mobileEmulationDeviceSettings . EnableTouchEvents ;
677
+ }
678
+ }
679
+
680
+ return mobileEmulationSettings ;
681
+ }
527
682
}
528
683
}
0 commit comments