0
# Browser Configuration: Options, Service, and Proxy
1
2
This document covers browser configuration in Python Selenium WebDriver, including browser options, service configuration, and proxy settings. These configurations allow you to customize browser behavior, manage driver processes, and control network settings.
3
4
## Browser Options Overview
5
6
Browser options allow you to configure browser behavior before launching. Each browser has its own options class that inherits from common base classes.
7
8
### Common Base Classes
9
10
{ .api }
11
```python
12
from selenium.webdriver.common.options import ArgOptions
13
14
class ArgOptions(BaseOptions):
15
def __init__(self) -> None
16
def add_argument(self, argument: str) -> None
17
def add_extension(self, extension: str) -> None
18
def add_encoded_extension(self, extension: str) -> None
19
```
20
21
**Description**: Base class for browser options that support arguments and extensions.
22
23
## Chrome/Chromium Options
24
25
{ .api }
26
```python
27
from selenium.webdriver.chrome.options import Options as ChromeOptions
28
from selenium.webdriver.chromium.options import ChromiumOptions
29
30
class ChromiumOptions(ArgOptions):
31
KEY = "goog:chromeOptions"
32
33
def __init__(self) -> None
34
```
35
36
**Description**: Base class for Chromium-based browsers (Chrome, Edge) providing common functionality.
37
38
### Binary Location
39
40
{ .api }
41
```python
42
@property
43
def binary_location(self) -> str
44
45
@binary_location.setter
46
def binary_location(self, value: str) -> None
47
```
48
49
**Description**: The location of the browser binary.
50
51
**Parameters**:
52
- `value`: Path to the browser executable
53
54
**Example**:
55
```python
56
from selenium.webdriver.chrome.options import Options
57
58
options = Options()
59
options.binary_location = "/usr/bin/google-chrome-beta"
60
driver = webdriver.Chrome(options=options)
61
```
62
63
### Extensions
64
65
{ .api }
66
```python
67
@property
68
def extensions(self) -> List[str]
69
70
def add_extension(self, extension: str) -> None
71
72
def add_encoded_extension(self, extension: str) -> None
73
```
74
75
**Description**: Manage browser extensions.
76
77
**Parameters**:
78
- `extension`: Path to .crx file or Base64 encoded extension data
79
80
**Example**:
81
```python
82
options = Options()
83
84
# Add extension from file
85
options.add_extension("/path/to/extension.crx")
86
87
# Add extension from base64 encoded string
88
with open("/path/to/extension.crx", "rb") as f:
89
encoded_extension = base64.b64encode(f.read()).decode('utf-8')
90
options.add_encoded_extension(encoded_extension)
91
```
92
93
### Experimental Options
94
95
{ .api }
96
```python
97
@property
98
def experimental_options(self) -> dict
99
100
def add_experimental_option(self, name: str, value: Union[str, int, dict, List[str]]) -> None
101
```
102
103
**Description**: Add experimental Chrome options.
104
105
**Parameters**:
106
- `name`: The experimental option name
107
- `value`: The option value
108
109
**Example**:
110
```python
111
options = Options()
112
113
# Enable Chrome DevTools Protocol
114
options.add_experimental_option("useAutomationExtension", False)
115
options.add_experimental_option("excludeSwitches", ["enable-automation"])
116
117
# Set download preferences
118
prefs = {
119
"download.default_directory": "/path/to/downloads",
120
"download.prompt_for_download": False,
121
"download.directory_upgrade": True,
122
"safebrowsing.enabled": True
123
}
124
options.add_experimental_option("prefs", prefs)
125
126
# Enable logging
127
options.add_experimental_option("w3c", True)
128
```
129
130
### Debugger Address
131
132
{ .api }
133
```python
134
@property
135
def debugger_address(self) -> Optional[str]
136
137
@debugger_address.setter
138
def debugger_address(self, value: str) -> None
139
```
140
141
**Description**: Address of the remote devtools instance.
142
143
**Parameters**:
144
- `value`: Address of remote devtools instance (hostname[:port])
145
146
**Example**:
147
```python
148
options = Options()
149
options.debugger_address = "127.0.0.1:9222"
150
151
# Connect to existing Chrome instance
152
driver = webdriver.Chrome(options=options)
153
```
154
155
### Common Chrome Arguments
156
157
**Example**:
158
```python
159
options = Options()
160
161
# Headless mode
162
options.add_argument("--headless")
163
164
# Window size and position
165
options.add_argument("--window-size=1920,1080")
166
options.add_argument("--window-position=0,0")
167
168
# Disable features
169
options.add_argument("--disable-extensions")
170
options.add_argument("--disable-gpu")
171
options.add_argument("--disable-dev-shm-usage")
172
options.add_argument("--no-sandbox")
173
174
# User agent
175
options.add_argument("--user-agent=Custom User Agent String")
176
177
# Disable images for faster loading
178
options.add_argument("--blink-settings=imagesEnabled=false")
179
180
# Enable verbose logging
181
options.add_argument("--enable-logging")
182
options.add_argument("--log-level=0")
183
184
# Proxy
185
options.add_argument("--proxy-server=http://proxy.example.com:8080")
186
187
# Incognito mode
188
options.add_argument("--incognito")
189
190
# Disable notifications
191
options.add_argument("--disable-notifications")
192
```
193
194
### Mobile Emulation
195
196
{ .api }
197
```python
198
def enable_mobile(
199
self,
200
android_package: Optional[str] = "com.android.chrome",
201
android_activity: Optional[str] = None,
202
device_serial: Optional[str] = None,
203
) -> None
204
```
205
206
**Description**: Enable mobile emulation.
207
208
**Parameters**:
209
- `android_package`: Android package name
210
- `android_activity`: Android activity name
211
- `device_serial`: Device serial number
212
213
**Example**:
214
```python
215
options = Options()
216
217
# Mobile emulation with device metrics
218
mobile_emulation = {
219
"deviceMetrics": {
220
"width": 375,
221
"height": 667,
222
"pixelRatio": 2.0
223
},
224
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_0 like Mac OS X) AppleWebKit/605.1.15"
225
}
226
options.add_experimental_option("mobileEmulation", mobile_emulation)
227
228
# Or use predefined device
229
mobile_emulation = {"deviceName": "iPhone X"}
230
options.add_experimental_option("mobileEmulation", mobile_emulation)
231
```
232
233
## Firefox Options
234
235
{ .api }
236
```python
237
from selenium.webdriver.firefox.options import Options as FirefoxOptions
238
239
class Options(ArgOptions):
240
KEY = "moz:firefoxOptions"
241
242
def __init__(self) -> None
243
```
244
245
**Description**: Firefox-specific browser options.
246
247
### Binary Location
248
249
{ .api }
250
```python
251
@property
252
def binary_location(self) -> str
253
254
@binary_location.setter
255
def binary_location(self, value: str) -> None
256
```
257
258
**Description**: Sets the location of the Firefox binary.
259
260
**Example**:
261
```python
262
from selenium.webdriver.firefox.options import Options
263
264
options = Options()
265
options.binary_location = "/usr/bin/firefox-developer-edition"
266
```
267
268
### Preferences
269
270
{ .api }
271
```python
272
@property
273
def preferences(self) -> dict
274
275
def set_preference(self, name: str, value: Union[str, int, bool]) -> None
276
```
277
278
**Description**: Set Firefox preferences (about:config values).
279
280
**Parameters**:
281
- `name`: Preference name
282
- `value`: Preference value (string, integer, or boolean)
283
284
**Example**:
285
```python
286
options = Options()
287
288
# Disable images
289
options.set_preference("permissions.default.image", 2)
290
291
# Set download directory
292
options.set_preference("browser.download.dir", "/path/to/downloads")
293
options.set_preference("browser.download.folderList", 2)
294
options.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
295
296
# Disable geolocation
297
options.set_preference("geo.enabled", False)
298
299
# Set user agent
300
options.set_preference("general.useragent.override", "Custom User Agent")
301
302
# Enable/disable JavaScript
303
options.set_preference("javascript.enabled", True)
304
305
# Disable notifications
306
options.set_preference("dom.webnotifications.enabled", False)
307
```
308
309
### Profile
310
311
{ .api }
312
```python
313
@property
314
def profile(self) -> Optional[FirefoxProfile]
315
316
@profile.setter
317
def profile(self, new_profile: Union[str, FirefoxProfile]) -> None
318
```
319
320
**Description**: Set Firefox profile to use.
321
322
**Parameters**:
323
- `new_profile`: Path to profile directory or FirefoxProfile object
324
325
**Example**:
326
```python
327
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
328
329
# Create custom profile
330
profile = FirefoxProfile()
331
profile.set_preference("browser.download.dir", "/custom/download/path")
332
profile.set_preference("browser.download.folderList", 2)
333
334
options = Options()
335
options.profile = profile
336
337
# Or use existing profile directory
338
options.profile = "/path/to/existing/profile"
339
```
340
341
### Logging
342
343
{ .api }
344
```python
345
class Log:
346
def __init__(self) -> None
347
348
@property
349
def level(self) -> Optional[str]
350
351
@level.setter
352
def level(self, value: str) -> None
353
```
354
355
**Description**: Configure Firefox logging.
356
357
**Example**:
358
```python
359
options = Options()
360
options.log.level = "trace" # trace, debug, config, info, warn, error, fatal
361
```
362
363
### Firefox Arguments
364
365
**Example**:
366
```python
367
options = Options()
368
369
# Headless mode
370
options.add_argument("--headless")
371
372
# Window size
373
options.add_argument("--width=1920")
374
options.add_argument("--height=1080")
375
376
# Private browsing
377
options.add_argument("--private")
378
379
# Safe mode
380
options.add_argument("--safe-mode")
381
382
# Profile directory
383
options.add_argument("--profile=/path/to/profile")
384
```
385
386
## Edge Options
387
388
{ .api }
389
```python
390
from selenium.webdriver.edge.options import Options as EdgeOptions
391
392
class Options(ChromiumOptions):
393
@property
394
def default_capabilities(self) -> dict
395
```
396
397
**Description**: Microsoft Edge options (inherits from ChromiumOptions).
398
399
**Example**:
400
```python
401
from selenium.webdriver.edge.options import Options
402
403
options = Options()
404
options.add_argument("--headless")
405
options.add_argument("--disable-gpu")
406
407
# Edge-specific experimental options
408
options.add_experimental_option("useAutomationExtension", False)
409
options.add_experimental_option("excludeSwitches", ["enable-automation"])
410
```
411
412
## Safari Options
413
414
{ .api }
415
```python
416
from selenium.webdriver.safari.options import Options as SafariOptions
417
418
class Options(BaseOptions):
419
def __init__(self) -> None
420
```
421
422
**Description**: Safari browser options (limited configuration available).
423
424
**Example**:
425
```python
426
from selenium.webdriver.safari.options import Options
427
428
options = Options()
429
# Safari has limited configuration options
430
driver = webdriver.Safari(options=options)
431
```
432
433
## Service Configuration
434
435
Service objects manage the driver process (ChromeDriver, GeckoDriver, etc.).
436
437
{ .api }
438
```python
439
from selenium.webdriver.common.service import Service
440
441
class Service(ABC):
442
def __init__(
443
self,
444
executable_path: Optional[str] = None,
445
port: int = 0,
446
log_output: SubprocessStdAlias = None,
447
env: Optional[Mapping[Any, Any]] = None,
448
driver_path_env_key: Optional[str] = None,
449
**kwargs,
450
) -> None
451
```
452
453
**Description**: Base class for all service objects that launch driver processes.
454
455
**Parameters**:
456
- `executable_path`: Path to the driver executable
457
- `port`: Port for the service to run on (0 = auto-assign)
458
- `log_output`: Logging output configuration
459
- `env`: Environment variables for the process
460
- `driver_path_env_key`: Environment variable for driver path
461
462
### Browser-Specific Services
463
464
#### Chrome Service
465
466
{ .api }
467
```python
468
from selenium.webdriver.chrome.service import Service as ChromeService
469
470
class Service(ChromiumService):
471
def __init__(
472
self,
473
executable_path: Optional[str] = None,
474
port: int = 0,
475
service_args: Optional[List[str]] = None,
476
log_output: SubprocessStdAlias = None,
477
env: Optional[Mapping[str, str]] = None,
478
**kwargs,
479
) -> None
480
```
481
482
**Example**:
483
```python
484
from selenium.webdriver.chrome.service import Service
485
from selenium.webdriver.chrome.options import Options
486
487
# Basic service
488
service = Service(executable_path="/path/to/chromedriver")
489
490
# Service with custom port and logging
491
service = Service(
492
executable_path="/path/to/chromedriver",
493
port=4444,
494
service_args=["--verbose"],
495
log_output="chromedriver.log"
496
)
497
498
options = Options()
499
driver = webdriver.Chrome(service=service, options=options)
500
```
501
502
#### Firefox Service
503
504
{ .api }
505
```python
506
from selenium.webdriver.firefox.service import Service as FirefoxService
507
508
class Service(Service):
509
def __init__(
510
self,
511
executable_path: Optional[str] = None,
512
port: int = 0,
513
service_args: Optional[List[str]] = None,
514
log_output: SubprocessStdAlias = None,
515
env: Optional[Mapping[str, str]] = None,
516
**kwargs,
517
) -> None
518
```
519
520
**Example**:
521
```python
522
from selenium.webdriver.firefox.service import Service
523
524
service = Service(
525
executable_path="/path/to/geckodriver",
526
log_output="geckodriver.log",
527
service_args=["--log=trace"]
528
)
529
```
530
531
### Service Methods
532
533
{ .api }
534
```python
535
def start(self) -> None
536
```
537
538
**Description**: Starts the service.
539
540
**Raises**: WebDriverException if service cannot be started or connected to
541
542
{ .api }
543
```python
544
def stop(self) -> None
545
```
546
547
**Description**: Stops the service.
548
549
{ .api }
550
```python
551
def is_connectable(self) -> bool
552
```
553
554
**Description**: Check if the service is connectable.
555
556
**Returns**: True if service is accessible, False otherwise
557
558
{ .api }
559
```python
560
@property
561
def service_url(self) -> str
562
```
563
564
**Description**: Gets the URL of the service.
565
566
**Returns**: Service URL (e.g., "http://localhost:4444")
567
568
### Service Logging Configuration
569
570
**Example**:
571
```python
572
import subprocess
573
574
# Log to file
575
service = Service(log_output="/path/to/driver.log")
576
577
# Log to stdout
578
service = Service(log_output=subprocess.STDOUT)
579
580
# Disable logging
581
service = Service(log_output=subprocess.DEVNULL)
582
583
# Log to custom file handle
584
with open("/path/to/custom.log", "w") as log_file:
585
service = Service(log_output=log_file)
586
```
587
588
## Proxy Configuration
589
590
{ .api }
591
```python
592
from selenium.webdriver.common.proxy import Proxy, ProxyType
593
594
class Proxy:
595
def __init__(self, raw: Optional[dict] = None) -> None
596
```
597
598
**Description**: Proxy configuration for WebDriver.
599
600
### Proxy Types
601
602
{ .api }
603
```python
604
class ProxyType:
605
DIRECT = {"ff_value": 0, "string": "DIRECT"}
606
MANUAL = {"ff_value": 1, "string": "MANUAL"}
607
PAC = {"ff_value": 2, "string": "PAC"}
608
AUTODETECT = {"ff_value": 4, "string": "AUTODETECT"}
609
SYSTEM = {"ff_value": 5, "string": "SYSTEM"}
610
UNSPECIFIED = {"ff_value": 6, "string": "UNSPECIFIED"}
611
```
612
613
**Description**: Set of possible proxy types.
614
615
### Manual Proxy Configuration
616
617
{ .api }
618
```python
619
@property
620
def http_proxy(self) -> str
621
622
@http_proxy.setter
623
def http_proxy(self, value: str) -> None
624
625
@property
626
def ssl_proxy(self) -> str
627
628
@ssl_proxy.setter
629
def ssl_proxy(self, value: str) -> None
630
631
@property
632
def ftp_proxy(self) -> str
633
634
@ftp_proxy.setter
635
def ftp_proxy(self, value: str) -> None
636
637
@property
638
def socks_proxy(self) -> str
639
640
@socks_proxy.setter
641
def socks_proxy(self, value: str) -> None
642
643
@property
644
def no_proxy(self) -> str
645
646
@no_proxy.setter
647
def no_proxy(self, value: str) -> None
648
```
649
650
**Description**: Manual proxy settings for different protocols.
651
652
### SOCKS Proxy Authentication
653
654
{ .api }
655
```python
656
@property
657
def socks_username(self) -> str
658
659
@socks_username.setter
660
def socks_username(self, value: str) -> None
661
662
@property
663
def socks_password(self) -> str
664
665
@socks_password.setter
666
def socks_password(self, value: str) -> None
667
668
@property
669
def socks_version(self) -> Optional[int]
670
671
@socks_version.setter
672
def socks_version(self, value: int) -> None
673
```
674
675
**Description**: SOCKS proxy authentication settings.
676
677
### PAC (Proxy Auto-Configuration)
678
679
{ .api }
680
```python
681
@property
682
def proxy_autoconfig_url(self) -> str
683
684
@proxy_autoconfig_url.setter
685
def proxy_autoconfig_url(self, value: str) -> None
686
```
687
688
**Description**: URL for proxy auto-configuration script.
689
690
### Auto-Detection
691
692
{ .api }
693
```python
694
@property
695
def auto_detect(self) -> bool
696
697
@auto_detect.setter
698
def auto_detect(self, value: bool) -> None
699
```
700
701
**Description**: Enable proxy auto-detection.
702
703
### Proxy Examples
704
705
**Manual HTTP Proxy**:
706
```python
707
from selenium.webdriver.common.proxy import Proxy, ProxyType
708
709
proxy = Proxy()
710
proxy.proxy_type = ProxyType.MANUAL
711
proxy.http_proxy = "proxy.example.com:8080"
712
proxy.ssl_proxy = "proxy.example.com:8080"
713
714
# Apply to capabilities
715
capabilities = webdriver.DesiredCapabilities.CHROME.copy()
716
proxy.add_to_capabilities(capabilities)
717
718
driver = webdriver.Chrome(desired_capabilities=capabilities)
719
```
720
721
**SOCKS Proxy with Authentication**:
722
```python
723
proxy = Proxy()
724
proxy.proxy_type = ProxyType.MANUAL
725
proxy.socks_proxy = "socks.proxy.com:1080"
726
proxy.socks_username = "username"
727
proxy.socks_password = "password"
728
proxy.socks_version = 5
729
```
730
731
**PAC File Configuration**:
732
```python
733
proxy = Proxy()
734
proxy.proxy_type = ProxyType.PAC
735
proxy.proxy_autoconfig_url = "http://proxy.example.com/proxy.pac"
736
```
737
738
**Auto-Detection**:
739
```python
740
proxy = Proxy()
741
proxy.proxy_type = ProxyType.AUTODETECT
742
proxy.auto_detect = True
743
```
744
745
**No Proxy for Specific Domains**:
746
```python
747
proxy = Proxy()
748
proxy.proxy_type = ProxyType.MANUAL
749
proxy.http_proxy = "proxy.example.com:8080"
750
proxy.no_proxy = "localhost,127.0.0.1,*.local,*.internal"
751
```
752
753
**System Proxy**:
754
```python
755
proxy = Proxy()
756
proxy.proxy_type = ProxyType.SYSTEM
757
```
758
759
## Complete Configuration Examples
760
761
### Production Chrome Setup
762
763
```python
764
from selenium import webdriver
765
from selenium.webdriver.chrome.options import Options
766
from selenium.webdriver.chrome.service import Service
767
from selenium.webdriver.common.proxy import Proxy, ProxyType
768
769
def create_production_chrome_driver():
770
# Service configuration
771
service = Service(
772
executable_path="/usr/local/bin/chromedriver",
773
port=4444,
774
log_output="/var/log/chromedriver.log"
775
)
776
777
# Chrome options
778
options = Options()
779
options.add_argument("--headless")
780
options.add_argument("--no-sandbox")
781
options.add_argument("--disable-dev-shm-usage")
782
options.add_argument("--disable-gpu")
783
options.add_argument("--window-size=1920,1080")
784
785
# Performance optimizations
786
options.add_argument("--disable-extensions")
787
options.add_argument("--disable-images")
788
options.add_argument("--disable-plugins")
789
options.add_argument("--disable-java")
790
791
# Security
792
options.add_argument("--disable-web-security")
793
options.add_argument("--allow-running-insecure-content")
794
795
# Download preferences
796
prefs = {
797
"profile.default_content_settings.popups": 0,
798
"download.default_directory": "/tmp/downloads",
799
"download.prompt_for_download": False,
800
"download.directory_upgrade": True,
801
"safebrowsing.enabled": True
802
}
803
options.add_experimental_option("prefs", prefs)
804
805
# Proxy configuration
806
proxy = Proxy()
807
proxy.proxy_type = ProxyType.MANUAL
808
proxy.http_proxy = "corporate-proxy:8080"
809
proxy.ssl_proxy = "corporate-proxy:8080"
810
proxy.no_proxy = "localhost,127.0.0.1,*.internal"
811
812
capabilities = options.to_capabilities()
813
proxy.add_to_capabilities(capabilities)
814
815
return webdriver.Chrome(
816
service=service,
817
options=options,
818
desired_capabilities=capabilities
819
)
820
```
821
822
### Firefox Development Setup
823
824
```python
825
from selenium.webdriver.firefox.options import Options
826
from selenium.webdriver.firefox.service import Service
827
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
828
829
def create_firefox_dev_driver():
830
# Profile setup
831
profile = FirefoxProfile()
832
833
# Developer preferences
834
profile.set_preference("devtools.console.stdout.content", True)
835
profile.set_preference("browser.cache.disk.enable", False)
836
profile.set_preference("browser.cache.memory.enable", False)
837
profile.set_preference("browser.cache.offline.enable", False)
838
profile.set_preference("network.http.use-cache", False)
839
840
# Download preferences
841
profile.set_preference("browser.download.dir", "/tmp/firefox-downloads")
842
profile.set_preference("browser.download.folderList", 2)
843
profile.set_preference("browser.helperApps.neverAsk.saveToDisk",
844
"application/pdf,text/csv,application/zip")
845
846
# Service configuration
847
service = Service(
848
executable_path="/usr/local/bin/geckodriver",
849
log_output="/var/log/geckodriver.log",
850
service_args=["--log=debug"]
851
)
852
853
# Options
854
options = Options()
855
options.profile = profile
856
options.add_argument("--width=1920")
857
options.add_argument("--height=1080")
858
859
# Development logging
860
options.log.level = "trace"
861
862
return webdriver.Firefox(service=service, options=options)
863
```
864
865
### Mobile Testing Configuration
866
867
```python
868
def create_mobile_chrome_driver():
869
options = Options()
870
871
# Mobile emulation
872
mobile_emulation = {
873
"deviceMetrics": {
874
"width": 375,
875
"height": 812,
876
"pixelRatio": 3.0
877
},
878
"userAgent": (
879
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_0 like Mac OS X) "
880
"AppleWebKit/605.1.15 (KHTML, like Gecko) "
881
"Version/13.0 Mobile/15E148 Safari/604.1"
882
)
883
}
884
options.add_experimental_option("mobileEmulation", mobile_emulation)
885
886
# Touch events
887
options.add_argument("--touch-events")
888
889
return webdriver.Chrome(options=options)
890
```
891
892
### Headless Testing with Custom User Agent
893
894
```python
895
def create_headless_driver_with_stealth():
896
options = Options()
897
898
# Headless mode
899
options.add_argument("--headless")
900
options.add_argument("--window-size=1920,1080")
901
902
# Stealth mode to avoid detection
903
options.add_argument("--disable-blink-features=AutomationControlled")
904
options.add_experimental_option("excludeSwitches", ["enable-automation"])
905
options.add_experimental_option("useAutomationExtension", False)
906
907
# Custom user agent
908
user_agent = (
909
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
910
"AppleWebKit/537.36 (KHTML, like Gecko) "
911
"Chrome/91.0.4472.124 Safari/537.36"
912
)
913
options.add_argument(f"--user-agent={user_agent}")
914
915
# Additional stealth options
916
prefs = {
917
"profile.default_content_setting_values.notifications": 2,
918
"profile.default_content_settings.popups": 0,
919
"profile.managed_default_content_settings.images": 2
920
}
921
options.add_experimental_option("prefs", prefs)
922
923
driver = webdriver.Chrome(options=options)
924
925
# Execute script to remove webdriver property
926
driver.execute_script(
927
"Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
928
)
929
930
return driver
931
```
932
933
This comprehensive guide covers all aspects of browser configuration in Selenium WebDriver, enabling you to customize browser behavior, manage driver processes, and configure network settings for your specific testing needs.