or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

action-chains.mdbrowser-configuration.mdelement-interaction.mdindex.mdwaits-conditions.mdwebdriver-classes.md

browser-configuration.mddocs/

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.